C# 更改 ASP.NET Web API 媒体类型格式化程序上的响应标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14202445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change Response Headers on Media Type Formatter for ASP.NET Web API
提问by Allison A
I have created an ASP.NET web API controller that is returning a strongly typed object on an action, as follows:
我创建了一个 ASP.NET Web API 控制器,它在操作上返回一个强类型对象,如下所示:
// GET api/iosdevices/5
public iOSDevice Get(string id) {
return new iOSDevice();
}
I have created a BufferedMediaTypeFormatter to handle the type iOSDevice:
我创建了一个 BufferedMediaTypeFormatter 来处理类型 iOSDevice:
public class iOSDeviceXmlFormatter : BufferedMediaTypeFormatter
{
public iOSDeviceXmlFormatter() {
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content) {
content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
iOSDevice device = (iOSDevice)value;
using (XmlWriter writer = XmlWriter.Create(writeStream)) {
writer.WriteStartElement("iOSDevice");
if (device.identifierForVendor != Guid.Empty) {
writer.WriteElementString("identifierForVendor", device.identifierForVendor.ToString());
writer.WriteElementString("userInterfaceIdiom", device.userInterfaceIdiom);
writer.WriteElementString("systemName", device.systemName);
writer.WriteElementString("systemVersion", device.systemVersion);
writer.WriteElementString("model", device.model);
}
writer.WriteEndElement();
}
writeStream.Close();
}
}
My problem is when I catch type "text/html" (e.g. someone attempts to access the API from his or her web browser), the response type is "text/html" instead of "application/xml". I want to override the response type so that the user gets a response that is "application/xml" instead of "text/html".
我的问题是当我捕获类型“text/html”(例如有人试图从他或她的 Web 浏览器访问 API)时,响应类型是“text/html”而不是“application/xml”。我想覆盖响应类型,以便用户获得“application/xml”而不是“text/html”的响应。
I cannot in the ApiController type get access to the "Response" property that is on regular MVC controllers and I am at a loss. How do I override the response type for this action that is being handled by a media type formatter?
我无法在 ApiController 类型中访问常规 MVC 控制器上的“响应”属性,我不知所措。如何覆盖由媒体类型格式化程序处理的此操作的响应类型?
EDIT: HELPFUL NOTE
编辑:有用的注释
I was trying this previously:
我以前试过这个:
var response = Request.CreateResponse<iOSDevice>(HttpStatusCode.Accepted, device);
response.Headers.Remove("Content-Type");
response.Headers.Add("Content-Type", "application/xml; charset=utf-8");
return response;
And it claimed I was "misusing" the headers.
它声称我“滥用”了标题。
But when I used Filip's example below of setting Content directly, it worked!
但是当我使用下面直接设置内容的 Filip 示例时,它起作用了!
var response = Request.CreateResponse();
response.Content = new ObjectContent<iOSDevice>(device, new iOSDeviceXmlFormatter());
return response;
采纳答案by Filip W
When you write to stream in the formatter, headers have been already sent.
当您在格式化程序中写入流时,已发送标头。
You can do this:
你可以这样做:
public HttpResponseMessage Get(string id) {
{
var value = new iOSDevice();
var response = Request.CreateResponse();
response.Content = new ObjectContent(typeof(iOSDevice), value, new iOSDeviceXmlFormatter());
//set headers on the "response"
return response;
}
or you can do this (add this method to your formatter):
或者你可以这样做(将此方法添加到格式化程序中):
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, string mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/xml");
}
Here is an example on how I used the SetDefaultContentHeaders
with a custom formatter:
http://www.strathweb.com/2012/09/generate-kindle-mobi-ebooks-with-your-asp-net-web-api/
这是我如何使用SetDefaultContentHeaders
自定义格式化程序的示例:http:
//www.strathweb.com/2012/09/generate-kindle-mobi-ebooks-with-your-asp-net-web-api/
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
if (CanWriteType(type) && mediaType.MediaType == supportedMediaType)
{
headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
headers.ContentDisposition.FileName = "ebook.mobi";
}
else
{
base.SetDefaultContentHeaders(type, headers, mediaType);
}
}