ASP.NET Web API的不同返回类型

我正在尝试使用ASP.NET MVC 4 Web API在HTTP上编写真正的RESTful Web服务。

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

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

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

如果ID不存在(404)或需要不同的授权(401),我可以轻松地快速返回并手动设置状态代码和任何其他内容,这很酷。 但是,在许多非2xx状态中,我想返回一个与Hammer资源表示不同的实体。 我可以轻松地手动执行此操作,但我希望根据请求标头利用ASP.NET MVC 4 Web API自动序列化和反序列化到XML或JSON。

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

我想到的一些潜在方法是:

  1. 让控制器方法返回主资源类型,但用HttpContext.Current.Response短路返回并以某种方式挂钩到自动序列化(首选)。

  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.Content设置为Accept头协商表示。

我从另一个问题的答案中得出了这个问题的清晰答案。

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

编辑5/10/2012 :感谢来自@DarrelMiller的输入,删除了已弃用的HttpResponseMessage并替换为对HttpRequestMessage.CreateResponse()扩展方法的调用。 注意:此扩展方法在MVC4 / WebAPI测试版中不可用。 你需要从源代码构建或获得每晚构建 。

过度简化的例子:

 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); } }