2016-04-18 15 views
3

私はASP.NETとF#を使用してWeb APIを構築しています。私はIExceptionHandlerの実装を持っています。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#gurusがすぐに自分のエラーを表示します。これまでに読んでいただきありがとうございます。

+0

'Task.FromResult(0)'式が疑わしいと思われます。メソッドボディ全体をタスク内で実行しようとするか、より多くのF#nessに対して、 'async'ワークフローで実装し、それを戻り式として' Task'に変換してください。 –

+0

同様の例として、これは役立つかもしれません:http://blog.ploeh.dk/2014/06/12/web-api-raygun-error-handler –

+0

@MarkSeemann応答いただきありがとうございます。私は、私の問題を引き起こしていたものの詳細を以下に掲載しました。私は別の[質問](http://stackoverflow.com/questions/36699555/what-is-the-correct-way-to-return-an-empty-task-when-implementing-message-hand)を投稿しました。 'Task.FromResult(0)'の使用に関して発生した懸念に対処してください。このリンクをお寄せいただき、ありがとうございました.F#を使用した「Functional Architecture with F#」コースを発見しました。これは現在、私の待ち行列の最上部にあります。 – pluralMonad

答えて

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

それはそれを無視し、空index.htmlページに表示されるエラー応答を受信したときJSは、上記特性を有するオブジェクトを期待しているからです。

ルーキー、間違い。うまくいけば、これは誰かの人生を数分節約します。

関連する問題