Joh*_*ohn 7 asp.net-web-api asp.net-core-mvc
我在MVC 6 WebAPI中调用api端点:
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
Run Code Online (Sandbox Code Playgroud)
在身体我有json序列化测试实体.
我的实体控制器代码中有一个错误,api返回500响应'服务器错误'我知道错误是什么将修复它,但我需要一些帮助的问题是API返回HTML而不是json序列化异常对象 - Json是我所期望的:它是旧webapi将返回的内容.我已经从我知道可行的旧测试项目中移植了编码.
那么为什么MVC 6 WebAPI返回html而不是json?我需要做一些配置吗?
编辑:我添加了Accept:application/json到@danludwig建议的标题,但是这没有解决问题,我仍然有一个html错误页面.
我查看了我的StartUp.cs并发现:
if (env.IsDevelopment())
{
//app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
Run Code Online (Sandbox Code Playgroud)
在ConfigureApp方法中.我用app.UseDeveloperExceptionPage()进行了测试; 评论说.这阻止了在api响应体中返回html错误页面,但是我仍然没有得到json序列化的异常对象.
使用时ExceptionHandlerMiddleware配置UseExceptionHandler("Home/Error")不包括对JSON的任何支持.它只会返回错误的html页面.使用时也可以这样说UseDeveloperExceptionPage.
据我所知,你需要添加一些代码来处理错误并返回一个json.
一种选择是使用异常过滤器并将其全局或在选定的控制器上添加,尽管此方法仅涵盖来自控制器操作方法的异常.例如,以下过滤器仅在请求接受为application/json时返回json对象(否则它将允许异常通过,例如可以由全局错误页面处理):
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 it is being added globally.
//Could be used as attribute on selected controllers instead
opts.Filters.Add(new CustomJSONExceptionFilter());
});
Run Code Online (Sandbox Code Playgroud)另一个选择是使用app.UseExceptionHandler重载添加您自己的异常处理程序中间件,该重载允许您指定将处理异常的备用管道的行为.我已经使用内联中间件快速编写了一个类似的例子,只有当请求接受是application/json时才会返回一个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 a better way of signally ExceptionHandlerMiddleware that we can't handle the exception
//But this will do the trick of letting the other error handlers to intervene
//as the ExceptionHandlerMiddleware class will swallow this exception and rethrow the original one
throw excHandler.Error;
}
});
});
Run Code Online (Sandbox Code Playgroud)这两种方法都会让你有其他的错误处理程序,可能为非json请求提供html页面(另一个想法是从你的自定义错误处理程序返回一个json页面或一个html页面).
PS.如果使用第二种方法,您很可能希望将该逻辑放入其自己的中间件类中,并使用不同的方法来生成json响应.在这种情况下,看看有什么 JsonResultExecutor呢
| 归档时间: |
|
| 查看次数: |
4988 次 |
| 最近记录: |