【发布时间】:2015-05-07 08:51:19
【问题描述】:
我有一个正在转换为使用 OData v4 的 Web API 2.2 控制器。在 ApiController 我能够做到这一点:
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, MyObject);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
return ResponseMessage(response);
它发回 201 的 Http 状态代码 - 已创建,主体中序列化为 JSON 的对象(Web API 2.2 的默认格式化程序),以及 text/html 的内容类型。
这个工作的原因是 Request.CreateResponse() 将格式化程序设置为 JSON,尽管我之后直接更改了内容类型,但它仍然存在。所以对象被序列化为 JSON,并且返回的响应内容类型为 text/html。
我需要这个的原因是,现有的前端利用 iframe 执行上传,然后从 iframe 正文中提取响应以将任何信息传递给用户。如果内容类型是 application/json,浏览器会尝试将其保存为文件。但是作为 text/html,它很容易被注入到 iframe 中。我们可以将其提取出来并反序列化为一个 javascript 对象。
如果使用 ODataController,现在尝试执行相同的中断,但出现以下错误:
{
"error":{
"code":"","message":"An error has occurred.","innererror":{
"message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'text/html'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{
"message":"A supported MIME type could not be found that matches the content type of the response. None of the supported type(s) 'application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false, application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=true, application/json;odata.metadata=minimal;odata.streaming=true, application/json;odata.metadata=minimal;odata.streaming=false;IEEE754Compatible=false, application/json;odata.metadata=minimal;odata.streaming=false;IEEE754Compatible=true, application/json;odata.metadata=minimal;odata.streaming=false, application/json;odata.metadata=minimal;IEEE754Compatible=false, application/json;odata.metadata=minimal;IEEE754Compatible=true, application/json;odata.metadata=minimal, application/json;odata.metadata=full;odata.streaming=true;IEEE754Compatible=false, application/json;odata.metadata=full;odata.streaming=true;IEEE754Compatible=true, application/json;odata.metadata=full;odata.streaming=true, application/json;odata.metadata=full;odata.streaming=false;IEEE754Compatible=false, application/json;odata.metadata=full;odata.streaming=false;IEEE754Compatib...' matches the content type 'text/html'.","type":"Microsoft.OData.Core.ODataContentTypeException","stacktrace":" at Microsoft.OData.Core.MediaTypeUtils.GetFormatFromContentType(String contentTypeName, ODataPayloadKind[] supportedPayloadKinds, ODataMediaTypeResolver mediaTypeResolver, ODataMediaType& mediaType, Encoding& encoding, ODataPayloadKind& selectedPayloadKind)\r\n at Microsoft.OData.Core.MediaTypeUtils.GetFormatFromContentType(String contentTypeHeader, ODataPayloadKind[] supportedPayloadKinds, ODataMediaTypeResolver mediaTypeResolver, ODataMediaType& mediaType, Encoding& encoding, ODataPayloadKind& selectedPayloadKind, String& batchBoundary)\r\n at Microsoft.OData.Core.ODataMessageWriter.EnsureODataFormatAndContentType()\r\n at Microsoft.OData.Core.ODataMessageWriter.SetHeaders(ODataPayloadKind payloadKind)\r\n at Microsoft.OData.Core.ODataMessageWriter.SetOrVerifyHeaders(ODataPayloadKind payloadKind)\r\n at Microsoft.OData.Core.ODataMessageWriter.WriteToOutput[TResult](ODataPayloadKind payloadKind, Action verifyHeaders, Func`2 writeFunc)\r\n at Microsoft.OData.Core.ODataMessageWriter.CreateODataEntryWriter(IEdmNavigationSource navigationSource, IEdmEntityType entityType)\r\n at System.Web.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()"
}
}
}
}
OData 格式化程序的工作方式似乎有点不同。并且在删除我的内容类型分配行的同时,将正确序列化的 OData 发送回,它使用 application/json 的内容类型执行此操作,然后浏览器尝试将其保存到文件中...
关于如何让 ODataController 像 ApiController 一样工作的任何想法?我是否必须创建自己的格式化程序才能做到这一点?考虑到我唯一要更改的是返回的内容类型,这似乎有点傻。
【问题讨论】:
标签: iframe odata asp.net-web-api content-type