我正在寻找在我的. 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中所做的那样。
我在我的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)应该没问题了。
而不是使用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是一个字符串(在我的数据库…而不是特定的/已知的类型)。
好吧,我终于把它弄好了。
////[Route("api/[controller]")]
////[ApiController]
////public class MyController: Microsoft.AspNetCore.Mvc.ControllerBase
////{
//// public IActionResult MyMethod(string myParam) {
string hardCodedJson = "{}";
int hardCodedStatusCode = 200;
Newtonsoft.Json.Linq.JObject job = Newtonsoft.Json.Linq.JObject.Parse(hardCodedJson);
/* "this" comes from your class being a subclass of Microsoft.AspNetCore.Mvc.ControllerBase */
Microsoft.AspNetCore.Mvc.ContentResult contRes = this.Content(job.ToString());
contRes.StatusCode = hardCodedStatusCode;
return contRes;
//// } ////end MyMethod
//// } ////end class
我恰巧用的是asp.net core 3.1
#region Assembly Microsoft.AspNetCore.Mvc.Core, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
//C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\3.1.0\ref\netcoreapp3.1\Microsoft.AspNetCore.Mvc.Core.dll
我从这里得到了提示::https://www.jianshu.com/p/7b3e92c42b61
控制器动作返回类型在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);
}