我正在寻找在我的. net核心Web API控制器中返回带有HTTP状态代码的JSON的正确方法。我以前是这样用的:
public IHttpActionResult GetResourceData()
{
return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}
这是在一个4.6 MVC应用程序,但现在与。net核心,我似乎没有这个IHttpActionResult,我有ActionResult和使用像这样:
public ActionResult IsAuthenticated()
{
return Ok(Json("123"));
}
但是服务器的反应很奇怪,如下图所示:
我只是想让Web API控制器返回带有HTTP状态码的JSON,就像我在Web API 2中所做的那样。
请参考以下代码,您可以管理多个状态代码与不同类型的JSON
public async Task<HttpResponseMessage> GetAsync()
{
try
{
using (var entities = new DbEntities())
{
var resourceModelList = entities.Resources.Select(r=> new ResourceModel{Build Your Resource Model}).ToList();
if (resourceModelList.Count == 0)
{
return this.Request.CreateResponse<string>(HttpStatusCode.NotFound, "No resources found.");
}
return this.Request.CreateResponse<List<ResourceModel>>(HttpStatusCode.OK, resourceModelList, "application/json");
}
}
catch (Exception ex)
{
return this.Request.CreateResponse<string>(HttpStatusCode.InternalServerError, "Something went wrong.");
}
}
控制器动作返回类型在ASP。NET核心web API
02/03/2020
6分钟阅读
+ 2
作者:斯科特·艾迪·林克
同步动作
[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<Product> GetById(int id)
{
if (!_repository.TryGetProduct(id, out var product))
{
return NotFound();
}
return product;
}
异步操作
[HttpPost]
[Consumes(MediaTypeNames.Application.Json)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<Product>> CreateAsync(Product product)
{
if (product.Description.Contains("XYZ Widget"))
{
return BadRequest();
}
await _repository.AddProductAsync(product);
return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}
您已经为大多数常见的状态代码预定义了方法。
result返回200
CreatedAtRoute返回201 +新的资源URL
NotFound返回404
BadRequest返回400等等。
所有方法的列表请参见baseconcontroller .cs和Controller.cs。
但如果你真的坚持你可以使用StatusCode来设置一个自定义代码,但你真的不应该这样做,因为它使代码可读性较差,你将不得不重复代码来设置头部(如CreatedAtRoute)。
public ActionResult IsAuthenticated()
{
return StatusCode(200, "123");
}
而不是使用404/201状态代码使用enum
public async Task<IActionResult> Login(string email, string password)
{
if (string.IsNullOrWhiteSpace(email) || string.IsNullOrWhiteSpace(password))
{
return StatusCode((int)HttpStatusCode.BadRequest, Json("email or password is null"));
}
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
return StatusCode((int)HttpStatusCode.BadRequest, Json("Invalid Login and/or password"));
}
var passwordSignInResult = await _signInManager.PasswordSignInAsync(user, password, isPersistent: true, lockoutOnFailure: false);
if (!passwordSignInResult.Succeeded)
{
return StatusCode((int)HttpStatusCode.BadRequest, Json("Invalid Login and/or password"));
}
return StatusCode((int)HttpStatusCode.OK, Json("Sucess !!!"));
}
请参考以下代码,您可以管理多个状态代码与不同类型的JSON
public async Task<HttpResponseMessage> GetAsync()
{
try
{
using (var entities = new DbEntities())
{
var resourceModelList = entities.Resources.Select(r=> new ResourceModel{Build Your Resource Model}).ToList();
if (resourceModelList.Count == 0)
{
return this.Request.CreateResponse<string>(HttpStatusCode.NotFound, "No resources found.");
}
return this.Request.CreateResponse<List<ResourceModel>>(HttpStatusCode.OK, resourceModelList, "application/json");
}
}
catch (Exception ex)
{
return this.Request.CreateResponse<string>(HttpStatusCode.InternalServerError, "Something went wrong.");
}
}
我在我的Asp Net Core Api应用程序中所做的是创建一个从ObjectResult扩展的类,并提供许多构造函数来定制内容和状态代码。
然后我所有的控制器动作都使用适当的构造函数之一。
你可以看看我的实现:
https://github.com/melardev/AspNetCoreApiPaginatedCrud
and
https://github.com/melardev/ApiAspCoreEcommerce
下面是类的样子(去我的回购完整代码):
public class StatusCodeAndDtoWrapper : ObjectResult
{
public StatusCodeAndDtoWrapper(AppResponse dto, int statusCode = 200) : base(dto)
{
StatusCode = statusCode;
}
private StatusCodeAndDtoWrapper(AppResponse dto, int statusCode, string message) : base(dto)
{
StatusCode = statusCode;
if (dto.FullMessages == null)
dto.FullMessages = new List<string>(1);
dto.FullMessages.Add(message);
}
private StatusCodeAndDtoWrapper(AppResponse dto, int statusCode, ICollection<string> messages) : base(dto)
{
StatusCode = statusCode;
dto.FullMessages = messages;
}
}
注意用对象替换dto的基数(dto)应该没问题了。