我正在使用ASP.NET WebAPI,一切都适用于accept:application / json标头,但是当使用accept:application / xml标头时,XMLFormatter似乎无法序列化只获取属性。
这是我正在尝试序列化的基类
public class RequestResponse
{
public string Status
{
get
{
if (Success)
return "SUCCESS";
else
{
return "FAIL";
}
}
}
public IList<RequestError> Errors { get; set; }
protected bool Success { get; set; }
}
这是XML响应
<RequestResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Backend.Models">
<Errors i:nil="true" />
</RequestResponse>
这是JSON响应
{
"Status": "FAIL",
"Errors": null
}
XML版本缺少get only属性Status。我尝试添加XmlElement(“Status”)甚至XmlElement(IsNullable = true)只是为了看看它是否会提出来,但它似乎没有改变任何东西。只有这样我才能使它工作是通过在我的属性中添加set方法,但我真的不想这样做。
这是WebAPI v2中的错误,还是有一些方法可以序列化只获取属性。
这是我的控制器方法。
[HttpGet]
public RequestResponse Test()
{
RequestResponse response = new RequestResponse();
return response;
}
答案 0 :(得分:1)
我认为你不能序列化只获得道具。 首先对字符串进行反序列化时,必须使用默认构造函数构造新实例,然后使用set props写入值,这样就不会有setter,也没有序列化。
此外,json序列化程序将序列化只读的prop,但它无法将其反序列化回对象。
如果你真的需要这个工作,你可以在你的对象上实现ISerializable并手动控制整个流程,但它非常重要 https://msdn.microsoft.com/en-us/library/ty01x675(v=vs.110).aspx
&#34;嗯,不幸的是,您的长篇文章的简短回答是XML序列化不支持非公共或只读属性。话虽如此,没有什么能说你的二传手必须做任何事情;它必须存在。你可以采取被动 - 攻击性路线,只需要一个空的setter,然后在你的文档中做一个模糊的评论,关于这些属性本质上是只读的事实(并且当然归咎于整个事情)。或者,您可以在您的setter中抛出异常,这将为开发人员提供更好的调试信息。&#34;
答案 1 :(得分:1)
如果您不介意执行自己的数据序列化,请构建HttpResponseMessage
并相应填写。
[HttpGet]
public HttpResponseMessage Test()
{
HttpResponseMessage TestResponse = new HttpResponseMessage();
RequestResponse response = new RequestResponse();
string JsonData = JsonConvert.SerializeObject(response);
if (Request.Headers.Accept.Contains(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml")))
{
XmlDocument doc = JsonConvert.DeserializeXmlNode(JsonData, "RequestResponse");
TestResponse.Content = new StringContent(doc.InnerXml, System.Text.Encoding.UTF8, "application/xml");
}
else
{
TestResponse.Content = new StringContent(JsonData, System.Text.Encoding.UTF8, "application/json");
}
return TestResponse;
}
这将完全绕过系统格式化程序。