HttpResponseMessage 无法序列化内容

HttpResponseMessage can't serialize content

我有空的 .net rest api,它只接受 XML。 如果controller方法return是class我想直接序列化,是没有问题的。但是我想使用响应包装器,以便所有控制器方法 return HttpResponseMessage.

所以这有效: FooController.cs:

public FooResponse PostFoo(FooRequest foo)
{
  var fooVal = fooBll.GetFoo();
  return new FooResponse { Foo = fooVal;};
}

但这不是: FooController.cs:

public HttpResponseMessage PostFoo(FooRequest foo)
{
  var fooVal = fooBll.GetFoo();
  HttpResponseMesage response;
  response = fooBll.GetSuccessResponse(Url, new FooResponse {Foo = foovVal;});
  return response ;
}

ResponseBLL.cs:

public HttpResponseMessage GetSuccessResponse(UrlHelper Url, object obj)
{
    this.requestMsg = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage;
    this.responseMsg = this.requestMsg.CreateResponse(HttpStatusCode.OK, obj);
    this.responseMsg.Headers.Location = HttpContext.Current.Request.Url;
    return this.responseMsg;
}

FooBLL继承了ResponseBLL,所以我可以调用fooBll.GetSuccessResponse.

在WebApiConfig.cs我有:

config.Formatters.XmlFormatter.UseXmlSerializer = true;
config.Formatters.Remove(config.Formatters.JsonFormatter);

我得到的错误是

The type FooResponse was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

现在我知道这个问题已经有很多问题了,相信我,我已经解决了所有问题但没有成功。我已经尝试了我能想到的所有可能组合的 [DataContract], [DataMember], [Serializable][XmlInclude] 属性。 [XmlInclude(typeof(FooResponse))] 在 FooBLL 上 class,[XmlInclude(typeof(FooBLL))] 在 ResponseBLL 上等等。

希望你能帮助我。

HttpRequestMessageExtensions.CreateResponse<T>() 是一种通用方法。 T Value 参数必须正确输入而不是声明为 object,例如:

public HttpResponseMessage GetSuccessResponse<T>(UrlHelper Url, T obj)
{
    this.requestMsg = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage;
    this.responseMsg = this.requestMsg.CreateResponse(HttpStatusCode.OK, obj);
    this.responseMsg.Headers.Location = HttpContext.Current.Request.Url;
    return this.responseMsg;
}

此解决方案有效,因为 XmlMediaTypeFormatter 使用 typeof(T) 而不是 value.GetType() 构造其 XmlSerializer。来自 source code:

    protected internal virtual object GetSerializer(Type type, object value, HttpContent content)
    {
        return GetSerializerForType(type);
    }

我们可以看到只有 type(作为 ObjectContent<T>typeof(T) 传递给 WriteToStreamAsync())用于序列化器构造。 object value 不是。微软本可以选择使用 value.GetType(),但没有。然后序列化程序抛出异常,因为进来的根对象的实际类型(typeof(Foo) 在这种情况下)与用于构造序列化程序的类型(typeof(object))或已知类型之一不同object.