0

有谁知道为什么在 ASP.NET WebAPI 的控制器中的 PUT 操作方法中引发异常的行为会与任何其他操作和动词类型不同?

基本上我有下面的代码(我通常有一个全局注册的异常过滤器,但我已经禁用它以确保它不是原因)。

public class JourneysController : ApiController
{
    private IJourneyRepository repository = null;

    public JourneysController(IJourneyRepository repository)
    {
        this.repository = repository;
    }

    public async Task<Journey> GetById(string id)
    {
        throw new BusinessException("test1");

        var item = await repository.Get(id);
        if (item == null) throw new HttpResponseException(HttpStatusCode.NotFound);
        return item;
    }

    public async Task<HttpResponseMessage> Post(HttpRequestMessage request, [FromBody]Journey value)
    {
        throw new BusinessException("test2");

        value = await repository.Add(value);

        var response = request.CreateResponse<Journey>(HttpStatusCode.Created, value);

        string uri = Url.Link("DefaultApi", new { id = value.Id });
        response.Headers.Location = new Uri(uri);
        return response;
    }

    public async void Put(string id, [FromBody]Journey value)
    {
        throw new BusinessException("test3");

        value.Id = id;
        if (!await repository.Update(value)) throw new HttpResponseException(HttpStatusCode.NotFound);
    }

    public HttpResponseMessage Delete(string id)
    {
        throw new BusinessException("test4");

        repository.Remove(id);
        return new HttpResponseMessage(HttpStatusCode.NoContent);
    }
}

当我执行(使用 Chrome 高级 REST 客户端)GET、POST 和 DELETE 动词时,我会得到如下所示的有效负载(无法从客户端复制/粘贴):

500 Internal Server Error 

Date: Tue, 25 Sep 2012 15:37:56 GMT 
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 813 
Pragma: no-cache 

{
    "Message": "An error has occurred.",
    "ExceptionMessage": "test4",
    "ExceptionType": "KieranBenton.LeaveNow.Services.Model.BusinessException",
    "StackTrace": " <snip>"
}

但是,PUT 操作返回给我一个黄色的死亡有效负载屏幕,例如:

<span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>

        <h2> <i>test3</i> </h2></span>

        <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

        <b> Description: </b>An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

        <b> Exception Details:    </b>KieranBenton.LeaveNow.Services.Model.BusinessException: test3

有没有人知道为什么会发生这种情况,或者我是否真的偶然发现了一个错误?

谢谢。

4

2 回答 2

3

一个指导方针async避免async void

async同步方法返回的等价物voidasync方法返回Taskasync void仅存在以便事件处理程序可能是async.

正如您所注意到的,异常处理是不同的。从 an 引发的任何异常async void都直接发送到SynchronizationContext方法启动时的当前。这对于事件处理程序来说是很自然的,但在其他情况下会令人困惑。

ASP.NET建立一个SynchronizationContext表示当前 HTTP 请求的,因此方法中的任何异常async void都不会传递给运行控制器的 WebAPI 代码;它们通过 WebAPI 框架直接传递到 ASP.NET 请求上下文。

于 2012-09-26T13:32:22.157 回答
1

我找到了答案:)

这是因为我的 PUT 方法是唯一一个标记为 async void 的方法 - 如果我将其更改为 async Task 那么它工作正常(毫无疑问,因为管道的其余部分可以检测到抛出的异常被包装在 Task 中)。

越来越多的 async void 似乎是一个非常糟糕的主意!

于 2012-09-25T15:55:00.437 回答