Web APIのメソッドを呼び出すときに発生する例外の詳細を返す方法を探しています。
実稼働環境のデフォルトでは、エラー500「内部サーバーエラー」がAPIによって返される唯一の情報です。
これはインターネット経由で公開されないプライベートAPIであり、呼び出し元アプリケーションは例外の場合にすべての詳細を取得して保存する必要があります。
例外の詳細は[〜#〜] json [〜#〜]HttpResponseコンテンツでフォーマットされ、呼び出し元がMessage属性、およびStackTraceString属性例外(UseDeveloperExceptionPage構成のようなHTTPページなし)。
現在、デフォルトのStartup Configureメソッドは次のとおりです。
public class Startup
{
[...]
public void Configure(IApplicationBuilder app, IHostingEnvironment env, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory)
{
loggerFactory.AddNLog();
env.ConfigureNLog(Path.Combine(AppContext.BaseDirectory, "nlog.config"));
if ( env.IsDevelopment() )
app.UseDeveloperExceptionPage();
else
app.UseStatusCodePages();
app.UseMvc();
}
}
すべての例外をインターセプトして呼び出し元に返すカスタムミドルウェアを作成できます。
public class ExceptionHandler
{
private readonly RequestDelegate _next;
public ExceptionHandler(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next.Invoke(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var response = context.Response;
response.ContentType = "application/json";
response.StatusCode = (int)HttpStatusCode.InternalServerError;
await response.WriteAsync(JsonConvert.SerializeObject(new
{
// customize as you need
error = new
{
message = exception.Message,
exception = exception.GetType().Name
}
}));
}
}
それをStartup Configureメソッドに登録します:
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseMiddleware<ExceptionHandler>();
ミドルウェアの代わりに、ActionFilterAttributeを作成してIActionResultを変更できます
すべての未処理の例外について、Exceptionメソッドで400 Bad requestを返す属性の簡単な例を次に示します。
public class MyUnhandledExceptionFilter : ActionFilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext context)
{
context.Result = new BadRequestObjectResult(context.Exception.Message);
}
}
次に、スタートアップのConfigureServicesメソッドに次のように登録します
services.AddMvc(options =>
{
options.Filters.Add(typeof(MyUnhandledExceptionFilter));
})
これはMVCに到達した例外のみをキャッチします。ほとんどの場合、これは必要なものです