REST服务返回自定义的HttpResponseMessage

WebApi框架中对资源的操作,都是通过其Controller提供的各种方法(GET,POST,PUT,DELET等)来实现,而这些方法的返回信息有以下几种形式:

方法返回类型 HttpResponseMessage
void StateCode:204(No Content)
HttpResponseMessage 直接返回HttpResponseMessage
IHttpActionResult 调用ExecuteAsync方法去创建一个HttpResponseMessage 对象,让后将这个对象转换成Http响应消息
其他类型(如int,string等) 将序列化的值写到响应消息的内容中,返回StateCode:200(OK)

1:返回void的情况不多做介绍,返回给浏览器的responseMessage如下:

HTTP/1.1 204 No Content
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 02:13:26 GMT

2:返回HttpResponseMessage

我们自定义的HttpResponseMessage主要可以通过这种返回类型来实现,例如,自定义response的Header:

public HttpResponseMessage Get()
    {
        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, "value");
        response.Content = new StringContent("hello", Encoding.Unicode);
        response.Headers.CacheControl = new CacheControlHeaderValue()
        {
            MaxAge = TimeSpan.FromMinutes(20)
        };
        return response;
    } 

又例如,对方法的不同执行结果返回不同的HttpResponseMessage:

[HttpGet]
        public HttpResponseMessage GetTopic(int id)
        {
            TopicModel topic;
            using (var connection = new OracleConnection(Setting.ConnectionStr))
            {
                var sql = string.Format("select * from {0} where topicid=:TopicId", Setting.TopicModelTable);
                var condition = new
                {
                    TopicId = id
                };
                connection.Open();
                topic = connection.QueryList<TopicModel>(sql,condition, null,null).FirstOrDefault();
                connection.Close();
            }
            HttpResponseMessage resp;
            if (topic == null)
            {
                resp = new HttpResponseMessage(HttpStatusCode.NoContent)
                {
                    ReasonPhrase = "no resource found"
                };
            }
            else
            {
                resp = Request.CreateResponse(HttpStatusCode.OK, topic);
            }
            return resp;
        }

在上例中,自定义HttpResponseMessage有两种方法,一种是通过构造函数,new HttpResponseMessage,同时用JSON序列化后的实体对象创建HttpResponseMessage中的Content(通过new StringContent):

new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent(JsonConvert.SerializeObject(topic))
                };

另外一种是直接通过实体,自己JSON序列化后形成HttpResponseMessage:

Request.CreateResponse(HttpStatusCode.OK, topic);  //topic为实体对象

这两种创建响应信息的方式,返回给浏览器的响应略有不同,前者返回给浏览器Header如下:

HTTP/1.1 200 OK
Content-Length: 122
Content-Type: text/plain; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 14 Jul 2015 12:59:42 GMT

后者返回给浏览器Header如下:

HTTP/1.1 200 OK
Content-Length: 122
Content-Type: text/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 14 Jul 2015 12:56:36 GMT

区别就在于Content-Type,因此,在某些对Content-Type有特殊要求的场合需要区分。

3:没怎么用过,对HttpResponseMessage提供一定的封装。

4:直接返回自定义对象,则默认序列化为JSON对象,加上StateCode:200(OK),形成新的HttpResponseMessage返回给浏览器:

HTTP/1.1 200 OK
Content-Length: 320
Content-Type: text/xml; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 14 Jul 2015 13:12:41 GMT

其实HttpResponseMessage对象中的Header中的Content-Type是可以通过设置HttpRequestMessage的Header中的Accept来指定的,即内容协商机制,如下的HttpRequestMessage:

GET http://192.168.22.6:7777/api/topic/3 HTTP/1.1
User-Agent: Fiddler
Accept: text/xml
Content-Type: text/json
Host: 192.168.22.6:7777
Content-Length: 118

即协商指定接收Content-Type为text/xml,以下是服务返回的HttpResponseMessage的Header:

HTTP/1.1 200 OK
Content-Length: 320
Content-Type: text/xml; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 14 Jul 2015 13:12:41 GMT

由此可见,虽然服务返回的Content-Type是JSON,但最终返回给浏览器的Content-Type被协商为了XML格式。



原文地址:https://www.cnblogs.com/you-you-111/p/4646625.html