asp.net web api - MVC 6 WebAPI returning html error page instead of json version of exception object -
i calling api endpoint in mvc 6 webapi:
post http://localhost:57287/mytestapi/testentity/ http/1.1 accept: application/json x-apikey: 00000000-0000-0000-0000-000000000000 content-type: application/json; charset=utf-8 host: localhost:57287 content-length: 1837 expect: 100-continue connection: keep-alive in body have json serialized test entity.
i have bug in entity controller code , api returning 500 response 'server error' know bug fix it, issue need api returning html instead of json serialized exception object - json expect: it's old webapi return. have ported coded old test project know works.
so why mvc 6 webapi returning html rather json? there configuration need do?
edit: added accept: application/json headers suggested @danludwig, did not resolve issue, still got html error page back.
i looked @ startup.cs , found:
if (env.isdevelopment()) { //app.usebrowserlink(); app.usedeveloperexceptionpage(); } else { app.useexceptionhandler("/home/error"); } in configureapp method. tested app.usedeveloperexceptionpage(); commented out. prevented return of html error page in api response body, still not getting json serialised exception object.
the exceptionhandlermiddleware configured when using useexceptionhandler("home/error") not include support json. return error html page. same can said when using usedeveloperexceptionpage.
as far know need add piece of code handle errors , return json.
one option use exception filter , add either globally or on selected controllers, although approach cover exceptions coming controller action methods. example following filter return json object when request accept application/json (otherwise let exception pass through example handled global error page):
public class customjsonexceptionfilter : exceptionfilterattribute { public override void onexception(exceptioncontext context) { if (context.httpcontext.request.gettypedheaders().accept.any(header => header.mediatype == "application/json")) { var jsonresult = new jsonresult(new { error = context.exception.message }); jsonresult.statuscode = (int)system.net.httpstatuscode.internalservererror; context.result = jsonresult; } } } services.addmvc(opts => { //here being added globally. //could used attribute on selected controllers instead opts.filters.add(new customjsonexceptionfilter()); });another option add own exception handler middleware using
app.useexceptionhandleroverload lets specify behavior of alternative pipeline process exception. have wrote similar example using inline middleware, return json object when request accept application/json:if (env.isdevelopment()) { app.usedeveloperexceptionpage(); } else { app.useexceptionhandler("/home/error"); } app.useexceptionhandler(appbuilder => { appbuilder.use(async (context, next) => { var exchandler = context.features.get<iexceptionhandlerfeature>(); if (context.request.gettypedheaders().accept.any(header => header.mediatype == "application/json")) { var jsonstring = string.format("{{\"error\":\"{0}\"}}", exchandler.error.message); context.response.contenttype = new mediatypeheadervalue("application/json").tostring(); await context.response.writeasync(jsonstring, encoding.utf8); } else { //i haven't figured out better way of signally exceptionhandlermiddleware can't handle exception //but trick of letting other error handlers intervene //as exceptionhandlermiddleware class swallow exception , rethrow original 1 throw exchandler.error; } }); });
both approaches let have other error handlers maybe provide html pages non json requests (another idea either return json or html page custom error handler).
ps. if using second approach, want put logic own middleware class , use different approach generate json response. in case take @ jsonresultexecutor does
Comments
Post a Comment