在MVC 5中,您可以使用HTTP代码抛出HttpException,这将设置响应,如下所示:
throw new HttpException((int)HttpStatusCode.BadRequest, "Bad Request.");
Run Code Online (Sandbox Code Playgroud)
ASP.NET 5/MVC 6中不存在HttpException.等效代码是什么?
我有一个ASP.NET Core 1.0 Web API应用程序,并尝试弄清楚如果我的控制器调用的函数错误输出异常消息到客户端.
我尝试了很多东西,但没有实现IActionResult.
我不明白为什么这不是人们需要的常见事情.如果真的没有解决方案可以有人告诉我为什么?
我确实看到了一些使用的文档HttpResponseException(HttpResponseMessage),但为了使用它,我必须安装compat shim.在Core 1.0中有没有新的方法来做这些事情?
这是我一直在尝试使用垫片,但它不起作用:
// GET: api/customers/{id}
[HttpGet("{id}", Name = "GetCustomer")]
public IActionResult GetById(int id)
{
Customer c = _customersService.GetCustomerById(id);
if (c == null)
{
var response = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent("Customer doesn't exist", System.Text.Encoding.UTF8, "text/plain"),
StatusCode = HttpStatusCode.NotFound
};
throw new HttpResponseException(response);
//return NotFound();
}
return new ObjectResult(c);
}
Run Code Online (Sandbox Code Playgroud)
当HttpResponseException抛出时,我查看客户端,无法找到我在内容中发送任何内容的消息.
我想从Web API(Asp.net Core 2.1)中仅返回标准化的错误响应,但我似乎无法弄清楚如何处理模型绑定错误.
该项目只是从"ASP.NET Core Web Application">"API"模板创建的.我有一个简单的动作定义为:
[Route("[controller]")]
[ApiController]
public class MyTestController : ControllerBase
{
[HttpGet("{id}")]
public ActionResult<TestModel> Get(Guid id)
{
return new TestModel() { Greeting = "Hello World!" };
}
}
public class TestModel
{
public string Greeting { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如果我使用无效的Guid(例如https://localhost:44303/MyTest/asdf)向此操作发出请求,我会收到以下响应:
{
"id": [
"The value 'asdf' is not valid."
]
}
Run Code Online (Sandbox Code Playgroud)
我有以下代码Startup.Configure:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
JsonErrorMiddleware.CreateSingleton(env);
if (!env.IsDevelopment())
{
app.UseHsts();
}
app
.UseHttpsRedirection()
.UseStatusCodePages(async ctx => …Run Code Online (Sandbox Code Playgroud) 我在启动时有
(更新:解决方案是将 UseRouting 移到 /api/error 路由下)
app.UseRouting();
if (env.IsDevelopment()) {
app.UseExceptionHandler("/api/error/error-local-development");
SwaggerConfig.Configure(app);
}
else {
app.UseExceptionHandler("/api/error/error");
}
app.UseCors();
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseSpaStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.UseRequestLocalization(options);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<ResultHub>("/hubs/resultHub");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "wwwroot";
});
Run Code Online (Sandbox Code Playgroud)
但是,throw new Exception()在控制器操作中时,永远不会调用错误控制器方法。
[Route("api/error")]
[ApiController]
[ApiExplorerSettings(IgnoreApi = true)]
public class ErrorController : OwnBaseController
{
public ErrorController(IApplicationUserService applicationUserService, ILogger<ErrorController> logger, IDiagnosticContext diagnosticContext) : base(applicationUserService, logger, diagnosticContext)
{
}
[Route("error")]
public IActionResult Error()
{
return Problem();
}
[Route("error-local-development")]
public IActionResult ErrorLocalDevelopment([FromServices] IWebHostEnvironment webHostEnvironment) …Run Code Online (Sandbox Code Playgroud) 在Framework WebAPI 2中,我有一个如下所示的控制器:
[Route("create-license/{licenseKey}")]
public async Task<LicenseDetails> CreateLicenseAsync(string licenseKey, CreateLicenseRequest license)
{
try
{
// ... controller-y stuff
return await _service.DoSomethingAsync(license).ConfigureAwait(false);
}
catch (Exception e)
{
_logger.Error(e);
const string msg = "Unable to PUT license creation request";
throw new HttpResponseException(HttpStatusCode.InternalServerError, msg);
}
}
Run Code Online (Sandbox Code Playgroud)
果然,我收到消息的500错误.
如何在ASP.NET Core Web API中执行类似的操作?
HttpRequestException似乎不存在.我宁愿继续返回对象而不是HttpRequestMessage.
我正在尝试使用该DefaultHttpContext对象来单元测试我的异常处理中间件.
我的测试方法如下所示:
[Fact]
public async Task Invoke_ProductionNonSuredException_ReturnsProductionRequestError()
{
var logger = new Mock<ILogger<ExceptionHandlerMiddleware>>();
var middleWare = new ExceptionHandlerMiddleware(next: async (innerHttpContext) =>
{
await Task.Run(() =>
{
throw new Exception();
});
}, logger: logger.Object);
var mockEnv = new Mock<IHostingEnvironment>();
mockEnv.Setup(u => u.EnvironmentName).Returns("Production");
var context = new DefaultHttpContext();
await middleWare.Invoke(context, mockEnv.Object);
var reader = new StreamReader(context.Response.Body);
var streamText = reader.ReadToEnd();
//TODO: write assert that checks streamtext is the expected production return type and not the verbose development environment version.
} …Run Code Online (Sandbox Code Playgroud) 在尝试找到对所有未捕获的异常实施全面捕获的最佳方法时,我发现了这一点。
但是,在实现它的过程中,我想起了我读过的内容:
警告不要
Response在调用next()... 后修改对象,因为响应可能已经开始发送,并且可能导致发送无效数据。pg。580
当中间件在MVC中间件之前充当全局异常处理程序时,如果调用异常中间件似乎没有任何响应可以启动,这是否合理,这是一个问题吗?
Invoke 在中间件上:
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
// A catch-all for uncaught exceptions...
catch (Exception exception)
{
var response = context.Response;
response.ContentType = "application/json";
response.StatusCode = (int)HttpStatusCode.InternalServerError;
await response.WriteAsync(...);
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个简单的 Web API Core v3.1,我试图在其中全局处理异常。遵循此答案/sf/answers/3861648311/后,这是我执行此操作的代码。
app.UseExceptionHandler(appBuilder => appBuilder.Run(async context =>
{
var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
var exception = exceptionHandlerPathFeature.Error;
var result = JsonConvert.SerializeObject(new { error = exception.Message });
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(result);
}));
Run Code Online (Sandbox Code Playgroud)
我得到的错误是context.Response.WriteAsync(result);:
System.ObjectDisposeException:无法访问关闭的流。
我很确定我错过了一些基本的东西,但无法弄清楚这一点。
每当发生异常时,我基本上需要将响应包装到一个对象中。
我正在玩一点 ASP.NET Core。我正在创建一个基本的 webapi。我想在出现问题时显示 JSON 错误。
打印屏幕在屏幕上显示我想要的内容。唯一的问题是发送时状态码为 200。
catch (NullReferenceException e)
{
return Json(NotFound(e.Message));
}
Run Code Online (Sandbox Code Playgroud)
我可以通过这样做来解决它:
return NotFound(new JsonResult(e.Message) {StatusCode = 404);
Run Code Online (Sandbox Code Playgroud)
但我不喜欢这样,因为现在您可以使用 NotFound 指定状态代码 500。
有人可以把我引向正确的方向吗?
此致,布莱希特
c# ×9
asp.net-core ×7
asp.net ×2
.net ×1
.net-core ×1
asp.net5 ×1
json ×1
moq ×1
unit-testing ×1