我的控制器中有7个动作。我已经对其进行了重构,从而能够隔离公共部分。
public IActionResult Get()
{
var response = CommonCode();
}
public IActionResult Get(guid id)
{
var response = CommonCode();
}
public IActionResult Post(ViewModel vm)
{
var response = CommonCode();
}
这是我重构通用代码的地方。
provate IActionResult CommonCode()
{
if(userHasNoPermission())
return Forbid();
if(IdProvidedDoesntExist())
return BadRequest();
//...
}
当我查看response
时,只能看到一种方法:ExecuteResultAsync()
。
有没有办法检索我在helper方法中发送的HTTP代码?
例如,我想停止处理500
,如果它是ModelState*
,则检索要添加到400
的消息,但是如果它是OK
,则继续处理
答案 0 :(得分:2)
您可以从private方法返回状态代码本身。 例如
private IActionResult CommonCode() {
if(userHasNoPermission())
return StatusCode(401);
if(IdProvidedDoesntExist())
return StatusCode(400);
//... }
然后在您的方法中进行检查
public IActionResult Post(ViewModel vm)
{
var response = CommonCode();
if (this.HttpContext.Response.StatusCode = 418)
Console.WriteLine("I'm a teapot")
else {
return response;
}
}
答案 1 :(得分:1)
CommonCode
的返回只是IActionResult
的某种类型。 “结果”实际上不是“响应”。稍后,当操作完全返回到请求管道中时(当您直接在代码中调用该方法时尚未发生)。结果,诸如HTTP状态代码之类的概念甚至都不相关。如果返回类似StatusCodeResult
的内容,则从技术上讲,这只是一个建议状态代码。如果稍后请求管道中出现异常,或者某些中间件由于某种原因显式更改了状态代码,则情况将有所不同。
总之,您正在尝试将两个无关的内容合并在一起。我认为您只是想知道CommonCode
中发生了什么,并认为HTTP状态是确定此情况的最佳方法。实际上,最好返回一个元组或执行类似于模式匹配的操作:
使用元组,基本上可以从CommonCode
方法返回一件事。例如,您可以执行以下操作:
private (int, IActionResult) CommonCode()
{
if(userHasNoPermission())
return (403, Forbid());
if(IdProvidedDoesntExist())
return (400, BadRequest());
//...
}
然后:
public IActionResult Get()
{
(var status, var response) = CommonCode();
// branch on `status`
}
或者,通过模式匹配:
public IActionResult Get()
{
var response = CommonCode();
switch (response)
{
case ForbidResult forbid:
// do something for forbidden
break;
case BadRequestResult badRequest:
// do something for bad request
break;
}
}
答案 2 :(得分:0)
有几种“肮脏”的方法可以在没有案例说明的情况下进行操作。状态代码实际上位于结果中,但是IActionResult和ActionResult讨厌被强制转换为通用类型。
此示例从任何常见结果中获取IActionResult,并使用反射将状态代码剔除。如果您不介意这样做,则可以省去case语句进行模式匹配的麻烦。内容也可以这样做。
public static HttpStatusCode GetHttpStatusCode(IActionResult functionResult)
{
try
{
return (HttpStatusCode)functionResult
.GetType()
.GetProperty("StatusCode")
.GetValue(functionResult, null);
}
catch
{
return HttpStatusCode.InternalServerError;
}
}