2012-04-26 123 views
9

我正在尝试使用ASP.NET MVC 4 Web API通过HTTP编写真正的RESTful Web服务。ASP.NET Web API的不同返回类型

我现在面临的挑战是根据我的状态代码返回不同的返回类型(entity-body)。

例如,对于资源锤我有一个.NET模型类 “锤”,和一个HammerController:

namespace Awesomeness 
{ 
    public class HammerController : ApiController 
    { 
     public Hammer Get(int id) 
     { 
     } 
... 

如果ID不存在(404)或需要不同的授权(401),我可以轻松地快速返回并手动设置状态码和其他任何内容,这很酷。但是,在许多非2xx状态中,我想返回与Hammer资源表示不同的实体主体。我可以很容易地做到这一点,但我想利用ASP.NET MVC 4 Web API automagic序列化和反序列化XML/JSON取决于请求头。

所以我的核心问题是:我可以利用ASP.NET MVC 4 Web API的automagic序列化,同时返回不同的返回类型吗?

我已经考虑过一些潜在方法是:

  1. 具有控制器方法返回主资源的类型,但短路用HttpContext.Current.Response并以某种方式返回勾入AUTOMAGIC序列化(优选的)。

  2. 让我的Model类更像是一个C union,它表示这种类型或类型,并让它作为正常返回过程的一部分被序列化(并且只是覆盖状态码和任何需要的响应头)。即使我想通过如何做到这一点,我有一种感觉,它仍然会变得非常黑客。

编辑2012年4月27日:我可以抛出HttpResponseException这样的:

HttpResponseMessage response = new HttpResponseMessage(statusCode); 
if (!string.IsNullOrWhiteSpace(text)) 
{ 
    response.Content = new StringContent(text); 
} 
throw new HttpResponseException(response); 

...但现在我需要弄清楚如何挂钩到自动魔法序列化和设置response.ContentAccept标题协商表示。

回答

15

我从this other question收到的答案得出了这个问题的答案。

如果我将返回值HttpResponseMessage返回,我可以通过返回new HttpResponseMessage()返回所需的任何状态或内容。

EDIT 2012/5/10:由于从@DarrelMiller输入,除去弃用HttpResponseMessage<T>并与呼叫HttpRequestMessage.CreateResponse<T>()扩展方法代替。注意:此扩展方法在MVC4/WebAPI测试版中不可用。您需要build from source或获取nightly build

简化的示例:

public HttpResponseMessage Post(MyResource myResource) 
{ 
    ... 
    if (goodStuff) 
    { 
     return ControllerContext.Request.CreateResponse(HttpStatusCode.Created, myNewResource); 
    } 
    else if (badStuff) 
    { 
     return ControllerContext.Request.CreateResponse(HttpStatusCode.BadRequest, badRequest); 
    } 
    else 
    { 
     return new HttpResponseMessage(HttpStatusCode.InternalServerError); 
    } 
} 
+0

感谢您的EDIT。我整天看到HttpResponseMessage 与我安装的测试版一起工作... – Max 2012-05-12 18:30:03

+0

为什么不HttpResponseMessage具有过载,以“创建响应”? – 2015-05-28 01:38:33

+2

@Simon_Weaver - 我猜,因为你响应HttpRequestMessage创建HttpResponseMessage,所以它使用了关于如何使响应上下文的请求。 – MikeJansen 2015-05-28 16:47:00