エラー/例外よりも検証に問題があるようですので、両方について少しお話しします。
検証
コントローラーのアクションは、通常、検証がモデルで直接宣言されている入力モデルを取る必要があります。
public class Customer
{
[Require]
public string Name { get; set; }
}
次に、ActionFilter
検証メッセージをクライアントに自動的に送信する を使用できます。
public class ValidationActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var modelState = actionContext.ModelState;
if (!modelState.IsValid) {
actionContext.Response = actionContext.Request
.CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
}
}
}
詳細については、http://ben.onfabrik.com/posts/automatic-modelstate-validation-in-aspnet-mvcをご覧ください。
エラー処理
発生した例外を表すメッセージを (関連するステータス コードと共に) クライアントに返すことをお勧めします。
Request.CreateErrorResponse(HttpStatusCode, message)
メッセージを指定する場合は、すぐに使用する必要があります。ただし、これによりコードがRequest
オブジェクトに関連付けられるため、これを行う必要はありません。
私は通常、独自のタイプの「安全な」例外を作成し、クライアントが他のすべての例外を処理して一般的な 500 エラーでラップする方法を知っていると期待しています。
アクション フィルターを使用して例外を処理すると、次のようになります。
public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var exception = context.Exception as ApiException;
if (exception != null) {
context.Response = context.Request.CreateErrorResponse(exception.StatusCode, exception.Message);
}
}
}
その後、グローバルに登録できます。
GlobalConfiguration.Configuration.Filters.Add(new ApiExceptionFilterAttribute());
これは私のカスタム例外タイプです。
using System;
using System.Net;
namespace WebApi
{
public class ApiException : Exception
{
private readonly HttpStatusCode statusCode;
public ApiException (HttpStatusCode statusCode, string message, Exception ex)
: base(message, ex)
{
this.statusCode = statusCode;
}
public ApiException (HttpStatusCode statusCode, string message)
: base(message)
{
this.statusCode = statusCode;
}
public ApiException (HttpStatusCode statusCode)
{
this.statusCode = statusCode;
}
public HttpStatusCode StatusCode
{
get { return this.statusCode; }
}
}
}
私の API がスローできる例外の例。
public class NotAuthenticatedException : ApiException
{
public NotAuthenticatedException()
: base(HttpStatusCode.Forbidden)
{
}
}