10

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

我目前面临的挑战是根据我的状态码返回不同的返回类型(实体主体)。

例如,对于资源 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 联合,它代表这种类型或那种类型,并让它作为正常返回过程的一部分进行序列化(并且只需覆盖状态代码和所需的任何响应标头)。即使我仔细考虑了如何做到这一点,我感觉它最终仍然会变得非常hacky。

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

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

...但现在我需要弄清楚如何挂钩自动魔术序列化并将其设置response.ContentAccept标头协商表示。

4

1 回答 1

16

我从另一个问题上收到的答案中得出了这个问题的明确答案。

如果我返回 value HttpResponseMessage,我可以通过返回 a 来返回我需要的任何状态或内容new HttpResponseMessage()

编辑2012 年 5 月 10 日:感谢@DarrelMiller 的输入,删除已弃用HttpResponseMessage<T>并替换为调用HttpRequestMessage.CreateResponse<T>()扩展方法。注意:此扩展方法在 MVC4/WebAPI beta 中不可用。您需要从源代码构建或获取每晚构建

过于简单的例子:

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);
    }
}
于 2012-04-28T04:24:24.127 回答