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格式。