asp.net webapi 序列化为xml 时实体属性增加防止特殊字符

     有时webapi在序列化xml时,可能需要给某些带有html或特殊字符(如 < > & /)的字段加上<![CDATA[]]> 已防止影响xml正常数据,如果使用.aspx视图那可直接在前台绑定字段时直接加入<![CDATA[]]>,webapi只有后台代码,那只能在后台做了,如下。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Net;
  5 using System.Net.Http;
  6 using System.Net.Http.Formatting;
  7 using System.Threading.Tasks;
  8 using System.Web.Http;
  9 using System.Xml;
 10 using System.Xml.Serialization;
 11 
 12 namespace MvcApplication1.Controllers
 13 {
 14     public class TestController : ApiController
 15     {
 16         [HttpGet]
 17         [HttpPost]
 18         public HttpResponseMessage HouseTest(string city)
 19         {
 20             //手动构造数据,这里应该是调用构造数据。
 21             var info = new GetHouseCountInfo()
 22             {
 23                 CityName = "北京",
 24                 CountInfo = new List<CountInfo>()
 25                 {
 26                     new CountInfo()
 27                     {
 28                         Data = "2016-08-30",
 29                         HouseDetail = "描述信息1111等。。。"
 30                     },
 31                     new CountInfo()
 32                     {
 33                         Data = "2016-08-30",
 34                         HouseDetail = "描述信息2222等。。。"
 35                     },
 36                     new CountInfo()
 37                     {
 38                         Data = "2016-08-30",
 39                         HouseDetail = "描述信息333等。。。"
 40                     }
 41                 }
 42             };
 43             //序列化实体与赋值
 44             var model = new HouseCountRoot {GetHouseInfo = new GetHouseCountInfo()};
 45             model.GetHouseInfo.CountInfo = info.CountInfo;
 46             model.Result = "";
 47             model.Message = "";
 48             model.GetHouseInfo.CityName = info.CityName;
 49 
 50             return new HttpResponseMessage()
 51             {
 52                 Content =
 53                     new ObjectContent<HouseCountRoot>(model, new CustomNamespaceXmlFormatter() {UseXmlSerializer = true},
 54                         new System.Net.Http.Headers.MediaTypeHeaderValue("application/xml") {CharSet = "utf-8"}),
 55                 StatusCode = HttpStatusCode.OK
 56             };
 57         }
 58     }
 59 
 60     [XmlRoot("houses")]
 61     public class HouseCountRoot
 62     {
 63         [XmlElement("result")]
 64         public string Result { get; set; }
 65 
 66         [XmlElement("message")]
 67         public string Message { get; set; }
 68 
 69         [XmlElement("housecount")]
 70         public GetHouseCountInfo GetHouseInfo { get; set; }
 71     }
 72 
 73     public class GetHouseCountInfo
 74     {
 75         /// <summary>
 76         /// 城市名称
 77         /// </summary>
 78         [XmlElement("cityname")]
 79         public string CityName { get; set; }
 80 
 81         /// <summary>
 82         /// 房源数信息
 83         /// </summary>
 84         [XmlElement("countinfo")]
 85         public List<CountInfo> CountInfo { get; set; }
 86     }
 87 
 88     public class CountInfo
 89     {
 90         /// <summary>
 91         /// 日期
 92         /// </summary>
 93         [XmlElement("data")]
 94         public string Data { get; set; }
 95 
 96         /// <summary>
 97         ///<![CDATA[ ]]>数据字段
 98         /// </summary>
 99         [XmlIgnore] //方式1,这里属性设置忽略,把CDataContent设置为housedetail
100         public string HouseDetail { get; set; }
101 
102         [XmlElement("housedetail")]
103         public XmlNode[] CDataContent
104         {
105             get
106             {
107                 return new XmlNode[]
108                 {
109                     new XmlDocument().CreateCDataSection(HouseDetail)
110                 };
111             }
112             set
113             {
114                 HouseDetail =
115                     value[0].Value;
116             }
117         }
118 
119         //方式二,这里把CDataContent设置为housedetail
120         //[XmlElement("housedetail")]
121         //public XmlNode CDataContent
122         //{
123         //    get
124         //    {
125         //        // 这种方式这里代码比上面的要多运行一定次数。
126         //        XmlNode node = new XmlDocument().CreateNode(XmlNodeType.CDATA, "", "");
127         //        node.InnerText = HouseDetail;
128         //        return node;
129         //    }
130         //    set
131         //    {
132         //        HouseDetail
133         //            = value.Value;
134         //    } //省略则CDataContent不会被序列化
135         //}
136 
137         //以下属性省略。。。。
138     }
139 
140     /// <summary>
141     /// 去除xml命名空间的 序列化类
142     /// </summary>
143     public class CustomNamespaceXmlFormatter : XmlMediaTypeFormatter
144     {
145         public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content,
146             TransportContext transportContext)
147         {
148             var xns = new XmlSerializerNamespaces();
149             foreach (var attribute in type.GetCustomAttributes(true))
150             {
151                 var xmlRootAttribute = attribute as XmlRootAttribute;
152                 if (xmlRootAttribute != null)
153                 {
154                     xns.Add(string.Empty, xmlRootAttribute.Namespace);
155                 }
156             }
157 
158             if (xns.Count == 0)
159             {
160                 xns.Add(string.Empty, string.Empty);
161             }
162 
163             var task = Task.Factory.StartNew(() =>
164             {
165                 var serializer = new XmlSerializer(type);
166                 serializer.Serialize(writeStream, value, xns);
167             });
168 
169             return task;
170         }
171     }
172 }

结果如下。

 1 <?xml version="1.0"?>
 2 <houses>
 3   <result />
 4   <message />
 5   <housecount>
 6     <cityname>北京</cityname>
 7     <countinfo>
 8       <data>2016-08-30</data>
 9       <housedetail><![CDATA[描述信息1111等。。。]]></housedetail>
10     </countinfo>
11     <countinfo>
12       <data>2016-08-30</data>
13       <housedetail><![CDATA[描述信息2222等。。。]]></housedetail>
14     </countinfo>
15     <countinfo>
16       <data>2016-08-30</data>
17       <housedetail><![CDATA[描述信息333等。。。]]></housedetail>
18     </countinfo>
19   </housecount>
20 </houses>