C# WebAPI v2 XMLFormatter未序列化仅获取属性

C# WebAPI v2 XMLFormatter未序列化仅获取属性,c#,asp.net,xml,serialization,asp.net-web-api2,C#,Asp.net,Xml,Serialization,Asp.net Web Api2,我使用的是ASP.NET WebAPI,一切都与accept:application/json头配合得很好,但是当使用accept:application/xml头时,XMLFormatter似乎无法序列化get-only属性 这是我试图序列化的基类 public class RequestResponse { public string Status { get { if (Success)

我使用的是ASP.NET WebAPI,一切都与accept:application/json头配合得很好,但是当使用accept:application/xml头时,XMLFormatter似乎无法序列化get-only属性

这是我试图序列化的基类

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版本缺少仅获取属性状态。我尝试添加xmlement(“Status”)甚至xmlement(IsNullable=true),只是想看看它是否会出现这种情况,但它似乎没有改变任何东西。我似乎能让它工作的唯一方法是将set方法添加到我的属性中,但我真的不想这样做

这是WebAPI v2中的一个bug,还是有某种方法可以序列化get-only属性

这是我的控制器方法

[HttpGet]
public RequestResponse Test()
{
    RequestResponse response = new RequestResponse();
    return response;
}

我不认为你可以连载得到唯一的道具。 当字符串首先被反序列化时,它必须使用默认构造函数构造新实例,然后使用set props写入值,这样就没有setter,也没有序列化

json序列化程序还将序列化只读属性,但无法将其反序列化回对象

如果您确实需要这样做,您可以在对象上实现ISerializable并手动控制整个流,但这并不简单

从msdn上取下


“嗯,不幸的是,对于您的长篇文章,简短的回答是XML序列化不支持非公共或只读属性。也就是说,没有任何东西说你的二传手必须实际做任何事情;它必须存在。您可以采取被动攻击的方式,只使用一个空的setter,然后在文档中对属性实际上是只读的这一事实做出模糊的评论(当然,这一切都要归咎于Microsoft)。或者,您可以在setter中抛出一个异常,这将为使用您的类的开发人员提供更好的调试信息。”

我认为您不能序列化get only props。 当字符串首先被反序列化时,它必须使用默认构造函数构造新实例,然后使用set props写入值,这样就没有setter,也没有序列化

json序列化程序还将序列化只读属性,但无法将其反序列化回对象

如果您确实需要这样做,您可以在对象上实现ISerializable并手动控制整个流,但这并不简单

从msdn上取下


“嗯,不幸的是,对于您的长篇文章,简短的回答是XML序列化不支持非公共或只读属性。也就是说,没有任何东西说你的二传手必须实际做任何事情;它必须存在。您可以采取被动攻击的方式,只使用一个空的setter,然后在文档中对属性实际上是只读的这一事实做出模糊的评论(当然,这一切都要归咎于Microsoft)。或者,您可以在setter中抛出一个异常,这将为使用您的类的开发人员提供更好的调试信息。”

如果您不介意执行自己的数据序列化,请构建一个
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;
}

这将完全绕过系统格式化程序。

如果您不介意执行自己的数据序列化,请构建一个
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;
}
这将完全绕过系统格式化程序

[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;
}