[C#/XML/ASP.net MVC] 控制字元導致輸出XML失敗「 '.', hexadecimal value 0x , is an invalid character」解法
前言
最近開發的介接API程式,發生XML輸出失敗
中文錯誤訊息↓ '.' (十六進位值 0x ) 是無效的字元。
查了文字檔Log,神奇的是,用Notepad++可以看到奇怪符號,用一般記事本就算另存UTF8編碼格式卻沒看到奇怪符號↓
為了追查倒底怎麼回事,我寫了一支Console程式去把原本ANSI編碼的文字檔讀取出來
以上字串其實是從DB撈出來的,也不知道當初使用者是怎麼輸入進去這些奇怪符號= =”
強者我同事(同時也是我的業主,他寫C語言),依照以下線索
1.使用者在操作畫面看不到奇怪符號
2.用Notepad++卻可以看到奇怪符號
3.程式錯誤畫面,清楚寫著有無效字元
4.包含奇怪符號的字串絕對無法轉XML
判斷應該是控制字元造成的影響
於是在業主的淫威下,要我過濾掉這些符號
我回:那還不簡單,加個try catch,遇到這種字串,就輸出空資料的XML就好了XD…………………(這解法當然被打槍,因為介接對象需要的是原本完整的字串)
說明
該如何知道有哪些奇怪符號會導致XML輸出失敗呢?
還好業主給我一個線索:控制字元
讓人聯想到學生時代寫C語言作業,曾寫過如何判斷英文大小寫的簡單程式,有寫過經驗的人,一定知道此解法跟ASCII字碼有關= = +
後來在Google大神下,還真的讓我找到控制字元的ASCII碼表
後來自己寫了一支測試用的ASP.net MVC驗證看看,究竟是不是控制字元在搞鬼
執行結果,正常↓
換輸出控制字元看看…
執行結果,異常↓
經由上面ASP.net MVC的驗證,已經瞭解控制字元會造成轉XML失敗的事實
加上ASCII字碼表也可知道控制字元的ASCII碼範圍是從哪裡到哪裡
這樣解決辦法就有頭緒
實作
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
//輸出英文字母 A 和 倒三角形
public ActionResult Index()
{
XDocument xdoc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("recordset",//加上此↓函數
new XElement("測試字串", ConvertControlCharToEmpty("大寫的A=" + Convert.ToChar(65) + ",倒三角形:" + Convert.ToChar(31)) )
));
string xml = xdoc.ToString();//轉成xml字串
return Content(xml, "text/xml", Encoding.UTF8);
}
/// <summary>
/// 把原本字串過濾掉控制字元
/// </summary>
/// <returns></returns>
private string ConvertControlCharToEmpty(string input)
{
string output = "";
foreach (char c in input)//走訪字串的每個字元
{
int asciiInt = Convert.ToInt32(c);
if ((asciiInt >= 0 && asciiInt <= 31) == false)
{//非控制字元
output += c;//就把合法的字元累加到output字串
}
}//end foreach
return output;
}
}
}
執行結果,很完美= =+
結語
幸好經過學生時代寫C語言曾接觸ASCII字碼的經驗加上強者同事的判斷,XML文件轉字串報錯問題才順利解決\(^O^)/