WebApiのエラーメッセージをどうカスタマイズです?

本来是发布在客户的Wiki上,所以就用日语写。

------------------------------------------------------------------------

Web Pageの場合、Web.configで

<customErrors mode="On" defaultRedirect="~/Error/HttpError">

    <error statusCode="404" redirect="~/Error/NotFound"/>

    <error statusCode="503" redirect="~/Error/Maintenance"/>

 </customErrors>

を配置すれば、404或いは503エラーの場合、カスタマイズのエラーページに遷移されます。

 

WebApiの場合はどうする?
特にWeb PageとWebApiのRouteが分かれている場合、Apiへのアクセスが間違っても、カスタマイズのエラーページに遷移しません。
技術不足で、Web.configでどう配置すれば分からないですが、ControllerとActionのほうだけで工夫して仕方がないです。

MVCでは、APIをサクセスする時、まずControllerを探してから、Actionを探します。ControllerとActionが合っていると、Actionに入って、該当するロジックを実行します。
こっちの考えでは、APIをサクセスする時、該当するController或いはActionを検出されない場合、カスタマイズのエラーを返します。

まず「HttpControllerSelector」というControllerを検出するものを実装する。

public class MyHttpControllerSelector : DefaultHttpControllerSelector

    {

        public MyHttpControllerSelector(HttpConfiguration configuration)

            : base(configuration)

        {

        }



        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)

        {

            HttpControllerDescriptor descriptor = null;

            try

            {

                descriptor = base.SelectController(request);

            }

            catch(Exception e)

            {

                APIResult<string> apiResult = new APIResult<string>()

                {

                    StatusCode = StatusCode.UnexpectedError

                };

                var response = new HttpResponseMessage(HttpStatusCode.OK)

                {

                    Content = new ObjectContent<APIResult<string>>(apiResult, new JsonMediaTypeFormatter())

                };



                Trace.WriteLine(e.Message);

        

        // Controllerが検出されない場合、直接カスタマイズのResponseを返します。

                throw new HttpResponseException(response);



            }

            return descriptor;



        }

    }

以上のやつを実装終われば、「Global.asax.cs」にレジストなくてはなりません。

protected void Application_Start()

{

   GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new MyHttpControllerSelector(GlobalConfiguration.Configuration));

}

次はActionの検知処理です。

public class BaseApiController : ApiController

    {

        public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, System.Threading.CancellationToken cancellationToken)

        {

            Task<HttpResponseMessage> result;

            try

            {

                result = base.ExecuteAsync(controllerContext, cancellationToken);

            }

            catch(Exception e)

            {

                APIResult<string> apiResult = new APIResult<string>() 

                {

                    StatusCode = StatusCode.UnexpectedError

                };

                var response = new HttpResponseMessage(HttpStatusCode.OK)

                {

                    Content = new ObjectContent<APIResult<string>>(apiResult, new JsonMediaTypeFormatter())

                };

                var tsc = new TaskCompletionSource<HttpResponseMessage>();

                tsc.SetResult(response);



                Trace.WriteLine(e.Message);



                return tsc.Task;

            }



            return result;

        }

    }

  

 

你可能感兴趣的:(Web)