[C#/XML/ASP.net MVC] 控制字元導致輸出XML失敗「 '.', hexadecimal value 0x , is an invalid character」解法

[C#/XML/ASP.net MVC] 控制字元導致輸出XML失敗「 '.', hexadecimal value 0x , is an invalid character」解法

前言

最近開發的介接API程式,發生XML輸出失敗

image

中文錯誤訊息↓ '.' (十六進位值 0x ) 是無效的字元。

image

查了文字檔Log,神奇的是,用Notepad++可以看到奇怪符號,用一般記事本就算另存UTF8編碼格式卻沒看到奇怪符號↓

image

為了追查倒底怎麼回事,我寫了一支Console程式去把原本ANSI編碼的文字檔讀取出來

image

以上字串其實是從DB撈出來的,也不知道當初使用者是怎麼輸入進去這些奇怪符號= =”

強者我同事(同時也是我的業主,他寫C語言),依照以下線索

1.使用者在操作畫面看不到奇怪符號

2.用Notepad++卻可以看到奇怪符號

3.程式錯誤畫面,清楚寫著有無效字元

4.包含奇怪符號的字串絕對無法轉XML

判斷應該是控制字元造成的影響

 

於是在業主的淫威下,要我過濾掉這些符號

我回:那還不簡單,加個try catch,遇到這種字串,就輸出空資料的XML就好了XD…………………(這解法當然被打槍,因為介接對象需要的是原本完整的字串)

 

說明

該如何知道有哪些奇怪符號會導致XML輸出失敗呢?

還好業主給我一個線索:控制字元

讓人聯想到學生時代寫C語言作業,曾寫過如何判斷英文大小寫的簡單程式,有寫過經驗的人,一定知道此解法跟ASCII字碼有關= = +

後來在Google大神下,還真的讓我找到控制字元的ASCII碼表

image

後來自己寫了一支測試用的ASP.net MVC驗證看看,究竟是不是控制字元在搞鬼

image

執行結果,正常↓

image

換輸出控制字元看看…

image

執行結果,異常↓

image

經由上面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;
				 
        }

    }
}

執行結果,很完美= =+

image

結語

幸好經過學生時代寫C語言曾接觸ASCII字碼的經驗加上強者同事的判斷,XML文件轉字串報錯問題才順利解決\(^O^)/

參考文章

如何使用C#進行ASCII碼與字元的轉換

ASCII 字元表