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
.
我有空的 .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
.