共计 3230 个字符,预计需要花费 9 分钟才能阅读完成。
译文链接:https://www.infoworld.com/art…
传统的 asp.net mvc 对应着 .netcore 中的 asp.net core mvc,能够利用 asp.net core mvc 去构建跨平台,可扩大,高性能的 web 利用和 api 接口。
程序员都有一些洁癖,很多时候咱们都想很完满的包装一些错误信息,如一些返回空 response 的 request 申请,或者一些 action 中返回 null value 的状况,通常这些状况下,asp.net core mvc 都会返回 http status 204(No Content),在本篇中,我筹备批改一下这种从 action 返回 null value 的默认行为。
要想运行本篇的例子,你须要装置一下 Visual Studio 2019,如果没有装置,能够到官网装置一下:https://visualstudio.microsof…
在 Asp.NET Core 中新建 Controller
在解决方案窗口中的 Controller 文件夹上右键并抉择 Add -> Controller
去新建 Controller,指定这个 Controller 的名字为 DemoController,接下来用上面的代码替换 DemoController。
[Route("api/[controller]")]
[ApiController]
public class DemoController : ControllerBase
{readonly Repository repository = new Repository();
[HttpGet]
public ActionResult Get()
{string item = repository.GetMessage();
return Ok(item);
}
[HttpGet("{id}", Name = "Get")]
public IActionResult Get(int id)
{string item = repository.GetMessage();
return Ok(item);
}
}
创立一个 Repository
上面是一个 Repository 类,外面蕴含了一个返回 null 的 GetMessage 办法,当然这仅仅是为了演示目标。
public class Repository
{public string GetMessage()
{return null;}
}
在 asp.net core mvc 中如何解决 null 值
当用 httpGet 的形式去申请 DemoController 的 GetMessage 办法,mvc 会返回 Http Status 204 (No Content),如下图所示:
为什么会这样呢?当 response 筹备返回时,asp.net core mvc 会从以后可用的 格式化器 列表中抉择一个适合的去解决以后的 response 对象,比如说:这个格式化器能够是 Json formatter,又能够是 Xml formatter,或者任何适合于该资源的 formatter。
对了,当遇到 null 值时,asp.net core mvc 框架会应用一个叫做 HttpNoContentOutputFormatter
,它的职责就是将 null 转换成 Http Status 204(No Content
),上面展现了源码实现:
public class HttpNoContentOutputFormatter : IOutputFormatter
{public Task WriteAsync(OutputFormatterWriteContext context)
{
HttpResponse response = context.HttpContext.Response;
response.ContentLength = 0L;
if (response.StatusCode == 200)
{response.StatusCode = 204;}
return Task.CompletedTask;
}
}
禁用 HttpNoContentOutputFormatter
如果你好奇的话,能够把 HttpNoContentOutputFormatter 禁用掉,这样就切断了 asp.net mvc core 解决 null 值的默认行为,如果要这么做的话,在 Startup 类的 ConfigureServices 办法做如下配置。
services.AddMvc(f =>
{
f.OutputFormatters.RemoveType
(typeof(HttpNoContentOutputFormatter));
f.OutputFormatters.Insert(0, new
HttpNoContentOutputFormatter
{TreatNullValueAsNoContent = false});
});
下面的代码禁用了 http status 204
的行为,取而代之的就是返回 http status 200(OK),而后 null 值会被塞到 response body 中。
在 Asp.Net Core 中返回 http status 404
为了可能达到 404 的成果,我来更新一下 action 的名字,上面就是 DemoController 更新后的代码片段:
[Route("api/[controller]")]
[ApiController]
public class DemoController : ControllerBase
{readonly Repository repository = new Repository();
[HttpGet]
public ActionResult Get()
{string item = repository.GetMessage();
if (item == null)
return NotFound();
return Ok(item);
}
}
当你再次申请 DemoController 时,框架会返回 http status 404(Not Found),如上面图片所示:
一个更欠缺的的返回 http 404 的形式
一个更好的返回 http status 404 的形式是应用 action filter 或者 result filter,如下代码:
public class NotFoundActionFilterAttribute : ActionFilterAttribute
{public override void OnActionExecuted(ActionExecutedContext context)
{if (context.Result is ObjectResult)
{
ObjectResult objectResult = context.Result
as ObjectResult;
if (objectResult.Value == null)
context.Result = new NotFoundResult();}
}
}
你能够将这个 filter 搁置在 action 级别,controller 级别 或者 全局级别,如果你要放到全局级别,能够在 Startup 的 ConfigureServices 办法中新增如下代码:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(f =>
{f.Filters.Add(new NotFoundResultFilterAttribute());
});
}
当在应用 asp.net core mvc 时,你能够在 action 返回值处应用 IActionResult
或 ActionResult<T>
或其余任何对象,在 Action 返回数据后,框架底层会对你的返回后果做必要的 序列化操作。
然而,当 action 返回 null 值时,asp.net core mvc 并不会尝试用任何可用的序列化器去解决这个 null 值,换句话说,框架会返回 Http status 204,示意申请胜利但无内容,侥幸的是,你能够按需扭转这个默认的行为。
更多高质量干货:参见我的 GitHub: dotnetfly