简体   繁体   English

Web API 2返回文本/简单响应

[英]Web API 2 returning text/plain responses

Really struggling with something I hope people here can help with. 真的很挣钱,我希望这里的人可以提供帮助。 I'm writing a RESTful API in Web API 2. Whenever I send a request to this service, the response is consistently being sent with a Content-Type of text/plain . 我正在Web API 2中编写RESTful API。每当我向此服务发送请求时,响应始终与Content-Type of text/plain Obviously this is no good, my response needs to be Content-Type of application/json . 显然这不好,我的回复需要是Content-Type of application/json I've tried a few suggestions that I found from Google but I don't think I'm understanding the whole picture. 我已经尝试了一些我从谷歌发现的建议,但我认为我并不了解整体情况。

Is there something special I need to do in order to have my web service respond with application/json content? 为了让我的Web服务响应application/json内容,我需要做些什么特别的事情吗? Note that I want this to work globally across the whole app, so I'm not after a way to modify a given response and set its content type - I want this to be a default behaviour for the whole web service: If a request contains an Accept header for application/json I want my web service to return that Content-Type instead of text/plain . 请注意,我希望这在整个应用程序中全局工作,所以我不是在修改给定的响应并设置其内容类型 - 我希望这是整个Web服务的默认行为:如果请求包含application/jsonAccept标头我希望我的Web服务返回Content-Type而不是text/plain

Edit to clarify: 编辑澄清:

My response contains an object called "responseData" that should be serialized into JSON and included in the body. 我的响应包含一个名为“responseData”的对象,该对象应序列化为JSON并包含在正文中。 I'm currently putting together my response like this: 我目前正在将这样的回答放在一起:

HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, responseData);
return response;

responseData is a POCO. responseData是一个POCO。 This get's correctly serialized as JSON and returned in the response - the only missing part is the Content-Type which is incorrectly set to "text/plain". 这个get被正确地序列化为JSON并在响应中返回 - 唯一缺少的部分是Content-Type,它被错误地设置为“text / plain”。 I could manually change this on every single response I compose, but I'm wanting to configure this on a global level. 我可以在我编写的每个响应上手动更改它,但我想在全局级别配置它。

OK, assuming that your responseData is a string, the Content-type header will be text/plain when you create the HttpResponseMessage . 好的,假设您的responseData是一个字符串,在创建HttpResponseMessage时, Content-type标头将是text/plain Doesn't matter what the contents of the string are, since no attempt is made to determine this. 无论字符串的内容是什么,因为没有尝试确定这一点。

The solution is to create the appropriate Content object for your message, initialized with the media type you're returning: 解决方案是为您的消息创建适当的Content对象,使用您要返回的媒体类型进行初始化:

HttpResponseMessage response = new HttpResponseMessage()
    {
        Content = new StringContent(
                responseData,
                Encoding.UTF8,
                "application/json"
            )
    };

There are other methods that amount to returning a particular object type and letting the API libraries serialize to JSON or XML for you as required. 还有其他方法相当于返回特定的对象类型,并允许API库根据需要为您序列化为JSON或XML。 I prefer to let the framework do the work for me where possible, but this is how you'd achieve it with a string you've created yourself. 我更愿意让框架尽可能地为我工作,但这就是你用你自己创建的字符串来实现它的方法。


For a strict JSON-only result, remove the XML formatter from the WebAPI configuration and return your POCO. 对于严格的仅JSON结果,从WebAPI配置中删除XML格式化程序并返回您的POCO。

In App_Start\\WebApiConfig.cs , add the following to the WebApiConfig.Register method: App_Start\\WebApiConfig.cs ,将以下内容添加到WebApiConfig.Register方法:

config.Formatters.Remove(config.Formatters.XmlFormatter);

And for your API: 对于您的API:

public class MyObject
{
    public bool result;
    public string reason;
}

public class TestController : ApiController
{
    public MyObject GetData()
    {
        MyObject result = new MyObject { result = "true", reason = "Testing POCO return" };
        return result;
    }
}

I ran this up and requested /api/Test from Chrome, which doesn't even mention application/json in the Accept header. 我运行了这个并从Chrome请求/api/Test ,它甚至没有在Accept标头中提到application/json Here are the response headers up until it hits Content-Type : 以下是响应标题,直到它命中Content-Type

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8

And the body: 和身体:

{"result":true,"reason":"Testing POCO return"}

Since I disabled XML it defaulted to JSON. 由于我禁用了XML,因此默认为JSON。

Add the following to Global.asax file. 将以下内容添加到Global.asax文件中。

protected void Application_Start()
{

JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
serializerSettings.Converters.Add(new IsoDateTimeConverter());
var jsonFormatter = new JsonNetFormatter(serializerSettings);
jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
GlobalConfiguration.Configuration.Formatters.Insert(0, jsonFormatter);

}

Another possible source of the issue described is that there may be an authorization redirect in play as was the case for us when one of the engineers thought to re-use user authentication for an api. 所描述的问题的另一个可能的来源是可能存在授权重定向,就像我们当其中一个工程师想要为api重用用户认证一样。

This means incoming requests were being redirected to a login page which was the text/html response that couldn't be parsed by ReadAsync<> . 这意味着传入的请求被重定向到登录页面,该页面是ReadAsync<>无法解析的text/html响应。 A silly mistake to be sure, but not an easy one to spot. 这是一个愚蠢的错误,但不容易发现。

The solution in that case was to remove the user authentication and implement HMAC based authentication for the api. 在这种情况下的解决方案是删除用户身份验证并为api实现基于HMAC的身份验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM