为什么我的IExceptionHandler实现没有返回错误响应?

时间:2016-04-18 14:46:32

标签: asp.net-web-api f# asp.net-web-api2

我正在使用ASP.NET和F#构建一个web api。我有一个IExceptionHandler的实现。

type DefaultExceptionHandler() =

let mapExceptionTypetoHttpStatusCode (ex:Exception) : HttpStatusCode =
    match ex with
    | :? ArgumentException -> HttpStatusCode.BadRequest
    | _ -> HttpStatusCode.InternalServerError

interface IExceptionHandler with
    member x.HandleAsync (context:ExceptionHandlerContext, cancellationToken:CancellationToken) =
        let request = context.Request
        let ex = context.Exception
        let httpStatusCode = mapExceptionTypetoHttpStatusCode ex

        context.Result <- { new IHttpActionResult with member x.ExecuteAsync(token:CancellationToken) = Task.FromResult(request.CreateErrorResponse(httpStatusCode, ex)) }
        Task.FromResult(0) :> Task

它在启动时注册。

type Global() =
inherit System.Web.HttpApplication() 

static member RegisterWebApi(config: HttpConfiguration) =
    // Configure routing
    config.MapHttpAttributeRoutes()
    config.Routes.MapHttpRoute(
        "DefaultApi", // Route name
        "api/{controller}/{id}", // URL with parameters
        { controller = "{controller}"; id = RouteParameter.Optional } // Parameter defaults
    ) |> ignore


    config.Services.Replace(typeof<IExceptionHandler>, new DefaultExceptionHandler())

member x.Application_Start() =
    GlobalConfiguration.Configure(Action<_> Global.RegisterWebApi)

我可以调试并查看代码是否已遍历,但返回的响应不是处理程序中设置的响应。我确信这是一个简单的东西,我忽略了,并没有触发编译器错误,但我到目前为止无法确定问题。我没有正确设置context.Result吗?

希望你们其中一位F#大师会立即看到我的错误。感谢您花时间阅读这篇文章。

1 个答案:

答案 0 :(得分:3)

好的,所以*问题*变得非常简单,我将在此发布,以防其他人在使用F#Web API模板作为学习机制时遇到类似问题。

它源于对模板的误解。由于它当前存在,模板使用位于项目根目录中的index.html文件按惯例传递响应。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Car List App</title>
    <link href="./Content/bootstrap.min.css" rel="stylesheet">
    <link href="./Content/Site.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <h2 class="sub-header">All Cars</h2>
    <table id="cars" class="table">
        <thead>
            <tr>
                <td>#</td>
                <td>Make</td>
                <td>Model</td>
            </tr>
        </thead>
        <tbody />
    </table>
</div>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
<script src="./Scripts/main.js"></script>

index.html内部调用的一些JavaScript实际上是对控制器执行的调用。

$(function () {
    var uri = 'api/cars';

    $.getJSON(uri)
        .done(function (data) {
            $.each(data, function (key, item) {
                $('<tr><td>' + (key + 1) + '</td><td>' + item.make + '</td><td>' + item.model + '</td></tr>')
                    .appendTo($('#cars tbody'));
            });
        });
});

由于JS期望具有上述属性的对象,因此当它收到错误响应时,它会忽略它并显示空的index.html页面。

新秀,错了。希望这可以节省一些人的生命。

相关问题