ASP.NET Core return JSON with status code
ASP.NET Core return JSON with status code
我正在寻找在我的 .NET Core Web API 控制器中使用 HTTP 状态代码 return JSON 的正确方法。我以前是这样使用它的:
public IHttpActionResult GetResourceData()
{
return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}
这是在 4.6 MVC 应用程序中,但现在使用 .NET Core 我似乎没有这个 IHttpActionResult
我有 ActionResult
并且像这样使用:
public ActionResult IsAuthenticated()
{
return Ok(Json("123"));
}
但是服务器的响应很奇怪,如下图:
我只希望 Web API 控制器像我在 Web API 中那样使用 HTTP 状态代码 return JSON 2.
响应 JsonResult
的最基本版本是:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
但是,这对您的问题没有帮助,因为您无法明确处理自己的响应代码。
The way to get control over the status results, is you need to return a ActionResult
which is where you can then take advantage of the StatusCodeResult
type.
例如:
// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
var result = _authorRepository.GetByNameSubstring(namelike);
if (!result.Any())
{
return NotFound(namelike);
}
return Ok(result);
}
请注意,以上两个示例均来自 Microsoft 文档中的精彩指南:Formatting Response Data
额外内容
我经常遇到的问题是我希望对我的 WebAPI 进行更精细的控制,而不是仅仅使用 VS 中 "New Project" 模板的默认配置。
让我们确保您掌握了一些基础知识...
第 1 步:配置您的服务
为了让您的 ASP.NET 核心 WebAPI 以 JSON 序列化 Object 响应并完全控制状态代码,您应该首先确保您拥有在通常在 Startup.cs
.
中找到的 ConfigureServices
方法中包含 AddMvc()
服务
It's important to note thatAddMvc()
will automatically include the Input/Output Formatter for JSON along with responding to other request types.
如果您的项目需要完全控制并且您想严格定义您的服务,例如您的 WebAPI 将如何处理各种请求类型,包括 application/json
和不响应对于其他请求类型(例如标准浏览器请求),您可以使用以下代码手动定义它:
public void ConfigureServices(IServiceCollection services)
{
// Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
// https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs
services
.AddMvcCore(options =>
{
options.RequireHttpsPermanent = true; // does not affect api requests
options.RespectBrowserAcceptHeader = true; // false by default
//options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
//remove these two below, but added so you know where to place them...
options.OutputFormatters.Add(new YourCustomOutputFormatter());
options.InputFormatters.Add(new YourCustomInputFormatter());
})
//.AddApiExplorer()
//.AddAuthorization()
.AddFormatterMappings()
//.AddCacheTagHelper()
//.AddDataAnnotations()
//.AddCors()
.AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}
您会注意到我还提供了一种方法供您添加自己的自定义 Input/Output 格式化程序,以防您可能想要响应另一种序列化格式(protobuf、thrift 等)。
上面的代码块大部分是 AddMvc()
方法的副本。但是,我们通过定义每个服务而不是使用带有模板的 pre-shipped 服务来实现我们自己的每个 "default" 服务。我已经在代码块中添加了存储库 link,或者您可以查看 AddMvc()
from the GitHub repository..
请注意,有些指南会尝试通过 "undoing" 默认值来解决此问题,而不是一开始就不实施它...如果您考虑到这一点,我们我现在正在使用开源软件,这是多余的工作,糟糕的代码,坦率地说,这是一个很快就会消失的旧习惯。
第 2 步:创建控制器
我将向您展示一个真正的 straight-forward 来解决您的问题。
public class FooController
{
[HttpPost]
public async Task<IActionResult> Create([FromBody] Object item)
{
if (item == null) return BadRequest();
var newItem = new Object(); // create the object to return
if (newItem != null) return Ok(newItem);
else return NotFound();
}
}
第 3 步:检查您的 Content-Type
和 Accept
您需要确保 请求 中的 Content-Type
和 Accept
header 设置正确。对于您的情况 (JSON),您需要将其设置为 application/json
.
如果您希望您的 WebAPI 默认响应 JSON,无论请求 header 指定什么,您都可以通过 几种方式.
方式一
如我之前推荐的文章 (Formatting Response Data) 中所示,您可以在 Controller/Action 级别强制使用特定格式。我个人不喜欢这种方法......但这里是为了完整性:
Forcing a Particular Format If you would like to restrict the response formats for a specific action you can, you can apply the
[Produces] filter. The [Produces] filter specifies the response
formats for a specific action (or controller). Like most Filters, this
can be applied at the action, controller, or global scope.
[Produces("application/json")]
public class AuthorsController
The [Produces]
filter will force all actions within the
AuthorsController
to return JSON-formatted responses, even if other
formatters were configured for the application and the client provided
an Accept
header requesting a different, available format.
方式二
我的首选方法是让 WebAPI 以请求的格式响应所有请求。但是,如果它不接受请求的格式,则 fall-back 为默认值(即 JSON)
首先,您需要在您的选项中注册(我们需要修改默认行为,如前所述)
options.RespectBrowserAcceptHeader = true; // false by default
最后,只需 re-ordering 服务构建器中定义的格式化程序列表,虚拟主机将默认为您位于列表顶部(即位置 0)的格式化程序。
可以在此找到更多信息 .NET Web Development and Tools Blog entry
您已经为最常见的状态代码预定义了方法。
Ok(result)
returns 200
响应
CreatedAtRoute
returns 201
+ 新资源 URL
NotFound
returns 404
BadRequest
returns400
等等
有关所有方法的列表,请参阅 BaseController.cs
and Controller.cs
。
但是如果你真的坚持可以使用 StatusCode
来设置自定义代码,但你真的不应该这样做,因为它会降低代码的可读性,你将不得不重复代码来设置 headers(例如 CreatedAtRoute
)。
public ActionResult IsAuthenticated()
{
return StatusCode(200, "123");
}
请参考下面的代码,您可以管理多个不同类型的状态码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.");
}
}
我想到的最简单的方法是:
var result = new Item { Id = 123, Name = "Hero" };
return new JsonResult(result)
{
StatusCode = StatusCodes.Status201Created // Status code here
};
使用 ASP.NET Core 2.0,从 Web API
到 return object 的理想方式(与 MVC 统一并使用相同的基础 class Controller
) is
public IActionResult Get()
{
return new OkObjectResult(new Item { Id = 123, Name = "Hero" });
}
注意
- 它 return 具有
200 OK
状态代码(它是 ObjectResult
的 Ok
类型)
- 它进行内容协商,即它会 return 基于请求中的
Accept
header。如果在请求中发送 Accept: application/xml
,它将 return 作为 XML
。如果什么都不发送,默认为 JSON
。
如果需要发送带有特定状态码的,请改用ObjectResult
或StatusCode
。两者做同样的事情,并支持内容协商。
return new ObjectResult(new Item { Id = 123, Name = "Hero" }) { StatusCode = 200 };
return StatusCode( 200, new Item { Id = 123, Name = "Hero" });
或更细粒度的 ObjectResult:
Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection myContentTypes = new Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection { System.Net.Mime.MediaTypeNames.Application.Json };
String hardCodedJson = "{\"Id\":\"123\",\"DateOfRegistration\":\"2012-10-21T00:00:00+05:30\",\"Status\":0}";
return new ObjectResult(hardCodedJson) { StatusCode = 200, ContentTypes = myContentTypes };
如果您特别想 return 为 JSON,有几种方法
//GET http://example.com/api/test/asjson
[HttpGet("AsJson")]
public JsonResult GetAsJson()
{
return Json(new Item { Id = 123, Name = "Hero" });
}
//GET http://example.com/api/test/withproduces
[HttpGet("WithProduces")]
[Produces("application/json")]
public Item GetWithProduces()
{
return new Item { Id = 123, Name = "Hero" };
}
注意
- 两者都以两种不同的方式执行
JSON
。
- 两者都忽略内容协商。
- 第一种方法使用特定序列化器
Json(object)
. 强制执行 JSON
- 第二种方法通过使用
Produces()
属性(这是一个 ResultFilter
)和 contentType = application/json
来实现同样的效果
在 the official docs. Learn about filters here 中阅读更多关于它们的信息。
样本中使用的简单模型class
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
这是我最简单的解决方案:
public IActionResult InfoTag()
{
return Ok(new {name = "Fabio", age = 42, gender = "M"});
}
或
public IActionResult InfoTag()
{
return Json(new {name = "Fabio", age = 42, gender = "M"});
}
使用枚举代替 404/201 状态码
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 !!!"));
}
我在 Asp Net Core Api 应用程序中所做的是创建一个 class 从 ObjectResult 扩展并提供许多构造函数来自定义内容和状态代码。
然后,我所有的 Controller 操作都适当地使用其中一个构造函数。
您可以在以下位置查看我的实现:
https://github.com/melardev/AspNetCoreApiPaginatedCrud
和
https://github.com/melardev/ApiAspCoreEcommerce
这里是 class 的样子(去我的仓库获取完整代码):
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 的 base(dto),你应该可以开始了。
我在这里找到了很棒的答案,我也试过这个 return 语句见 StatusCode(whatever code you wish)
并且它有效!!!
return Ok(new {
Token = new JwtSecurityTokenHandler().WriteToken(token),
Expiration = token.ValidTo,
username = user.FullName,
StatusCode = StatusCode(200)
});
我成功了。我的大问题是我的 json 是一个字符串(在我的数据库中...而不是 specific/known 类型)。
好的,我终于让它工作了。
////[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.1.0\ref\netcoreapp3.1\Microsoft.AspNetCore.Mvc.Core.dll
我从这里得到提示:: https://www.jianshu.com/p/7b3e92c42b61
控制器操作 return 键入 ASP.NET 核心网络 API
2020 年 2 月 3 日
6 分钟阅读时间
+2
作者:斯科特·艾迪 Link
[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);
}
我找到的最干净的解决方案是在 Startup.cs 中的 ConfigureServices 方法中设置以下内容(在我的例子中,我希望删除 TZ 信息。我总是希望看到用户看到的日期时间).
services.AddControllers()
.AddNewtonsoftJson(o =>
{
o.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Unspecified;
});
DateTimeZoneHandling 选项是 Utc、Unspecified、Local 或 RoundtripKind
我仍然想找到一种方法能够在每次调用的基础上请求这个。
类似
static readonly JsonMediaTypeFormatter _jsonFormatter = new JsonMediaTypeFormatter();
_jsonFormatter.SerializerSettings = new JsonSerializerSettings()
{DateTimeZoneHandling = DateTimeZoneHandling.Unspecified};
return Ok("Hello World", _jsonFormatter );
我正在从 ASP.NET 进行转换,并且我使用了以下辅助方法
public static ActionResult<T> Ok<T>(T result, HttpContext context)
{
var responseMessage = context.GetHttpRequestMessage().CreateResponse(HttpStatusCode.OK, result, _jsonFormatter);
return new ResponseMessageResult(responseMessage);
}
我正在寻找在我的 .NET Core Web API 控制器中使用 HTTP 状态代码 return JSON 的正确方法。我以前是这样使用它的:
public IHttpActionResult GetResourceData()
{
return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}
这是在 4.6 MVC 应用程序中,但现在使用 .NET Core 我似乎没有这个 IHttpActionResult
我有 ActionResult
并且像这样使用:
public ActionResult IsAuthenticated()
{
return Ok(Json("123"));
}
但是服务器的响应很奇怪,如下图:
我只希望 Web API 控制器像我在 Web API 中那样使用 HTTP 状态代码 return JSON 2.
响应 JsonResult
的最基本版本是:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
但是,这对您的问题没有帮助,因为您无法明确处理自己的响应代码。
The way to get control over the status results, is you need to return a
ActionResult
which is where you can then take advantage of theStatusCodeResult
type.
例如:
// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
var result = _authorRepository.GetByNameSubstring(namelike);
if (!result.Any())
{
return NotFound(namelike);
}
return Ok(result);
}
请注意,以上两个示例均来自 Microsoft 文档中的精彩指南:Formatting Response Data
额外内容
我经常遇到的问题是我希望对我的 WebAPI 进行更精细的控制,而不是仅仅使用 VS 中 "New Project" 模板的默认配置。
让我们确保您掌握了一些基础知识...
第 1 步:配置您的服务
为了让您的 ASP.NET 核心 WebAPI 以 JSON 序列化 Object 响应并完全控制状态代码,您应该首先确保您拥有在通常在 Startup.cs
.
ConfigureServices
方法中包含 AddMvc()
服务
It's important to note that
AddMvc()
will automatically include the Input/Output Formatter for JSON along with responding to other request types.
如果您的项目需要完全控制并且您想严格定义您的服务,例如您的 WebAPI 将如何处理各种请求类型,包括 application/json
和不响应对于其他请求类型(例如标准浏览器请求),您可以使用以下代码手动定义它:
public void ConfigureServices(IServiceCollection services)
{
// Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
// https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs
services
.AddMvcCore(options =>
{
options.RequireHttpsPermanent = true; // does not affect api requests
options.RespectBrowserAcceptHeader = true; // false by default
//options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
//remove these two below, but added so you know where to place them...
options.OutputFormatters.Add(new YourCustomOutputFormatter());
options.InputFormatters.Add(new YourCustomInputFormatter());
})
//.AddApiExplorer()
//.AddAuthorization()
.AddFormatterMappings()
//.AddCacheTagHelper()
//.AddDataAnnotations()
//.AddCors()
.AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}
您会注意到我还提供了一种方法供您添加自己的自定义 Input/Output 格式化程序,以防您可能想要响应另一种序列化格式(protobuf、thrift 等)。
上面的代码块大部分是 AddMvc()
方法的副本。但是,我们通过定义每个服务而不是使用带有模板的 pre-shipped 服务来实现我们自己的每个 "default" 服务。我已经在代码块中添加了存储库 link,或者您可以查看 AddMvc()
from the GitHub repository..
请注意,有些指南会尝试通过 "undoing" 默认值来解决此问题,而不是一开始就不实施它...如果您考虑到这一点,我们我现在正在使用开源软件,这是多余的工作,糟糕的代码,坦率地说,这是一个很快就会消失的旧习惯。
第 2 步:创建控制器
我将向您展示一个真正的 straight-forward 来解决您的问题。
public class FooController
{
[HttpPost]
public async Task<IActionResult> Create([FromBody] Object item)
{
if (item == null) return BadRequest();
var newItem = new Object(); // create the object to return
if (newItem != null) return Ok(newItem);
else return NotFound();
}
}
第 3 步:检查您的 Content-Type
和 Accept
您需要确保 请求 中的 Content-Type
和 Accept
header 设置正确。对于您的情况 (JSON),您需要将其设置为 application/json
.
如果您希望您的 WebAPI 默认响应 JSON,无论请求 header 指定什么,您都可以通过 几种方式.
方式一 如我之前推荐的文章 (Formatting Response Data) 中所示,您可以在 Controller/Action 级别强制使用特定格式。我个人不喜欢这种方法......但这里是为了完整性:
Forcing a Particular Format If you would like to restrict the response formats for a specific action you can, you can apply the [Produces] filter. The [Produces] filter specifies the response formats for a specific action (or controller). Like most Filters, this can be applied at the action, controller, or global scope.
[Produces("application/json")] public class AuthorsController
The
[Produces]
filter will force all actions within theAuthorsController
to return JSON-formatted responses, even if other formatters were configured for the application and the client provided anAccept
header requesting a different, available format.
方式二 我的首选方法是让 WebAPI 以请求的格式响应所有请求。但是,如果它不接受请求的格式,则 fall-back 为默认值(即 JSON)
首先,您需要在您的选项中注册(我们需要修改默认行为,如前所述)
options.RespectBrowserAcceptHeader = true; // false by default
最后,只需 re-ordering 服务构建器中定义的格式化程序列表,虚拟主机将默认为您位于列表顶部(即位置 0)的格式化程序。
可以在此找到更多信息 .NET Web Development and Tools Blog entry
您已经为最常见的状态代码预定义了方法。
Ok(result)
returns200
响应CreatedAtRoute
returns201
+ 新资源 URLNotFound
returns404
BadRequest
returns400
等等
有关所有方法的列表,请参阅 BaseController.cs
and Controller.cs
。
但是如果你真的坚持可以使用 StatusCode
来设置自定义代码,但你真的不应该这样做,因为它会降低代码的可读性,你将不得不重复代码来设置 headers(例如 CreatedAtRoute
)。
public ActionResult IsAuthenticated()
{
return StatusCode(200, "123");
}
请参考下面的代码,您可以管理多个不同类型的状态码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.");
}
}
我想到的最简单的方法是:
var result = new Item { Id = 123, Name = "Hero" };
return new JsonResult(result)
{
StatusCode = StatusCodes.Status201Created // Status code here
};
使用 ASP.NET Core 2.0,从 Web API
到 return object 的理想方式(与 MVC 统一并使用相同的基础 class Controller
) is
public IActionResult Get()
{
return new OkObjectResult(new Item { Id = 123, Name = "Hero" });
}
注意
- 它 return 具有
200 OK
状态代码(它是ObjectResult
的Ok
类型) - 它进行内容协商,即它会 return 基于请求中的
Accept
header。如果在请求中发送Accept: application/xml
,它将 return 作为XML
。如果什么都不发送,默认为JSON
。
如果需要发送带有特定状态码的,请改用ObjectResult
或StatusCode
。两者做同样的事情,并支持内容协商。
return new ObjectResult(new Item { Id = 123, Name = "Hero" }) { StatusCode = 200 };
return StatusCode( 200, new Item { Id = 123, Name = "Hero" });
或更细粒度的 ObjectResult:
Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection myContentTypes = new Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection { System.Net.Mime.MediaTypeNames.Application.Json };
String hardCodedJson = "{\"Id\":\"123\",\"DateOfRegistration\":\"2012-10-21T00:00:00+05:30\",\"Status\":0}";
return new ObjectResult(hardCodedJson) { StatusCode = 200, ContentTypes = myContentTypes };
如果您特别想 return 为 JSON,有几种方法
//GET http://example.com/api/test/asjson
[HttpGet("AsJson")]
public JsonResult GetAsJson()
{
return Json(new Item { Id = 123, Name = "Hero" });
}
//GET http://example.com/api/test/withproduces
[HttpGet("WithProduces")]
[Produces("application/json")]
public Item GetWithProduces()
{
return new Item { Id = 123, Name = "Hero" };
}
注意
- 两者都以两种不同的方式执行
JSON
。 - 两者都忽略内容协商。
- 第一种方法使用特定序列化器
Json(object)
. 强制执行 JSON
- 第二种方法通过使用
Produces()
属性(这是一个ResultFilter
)和contentType = application/json
来实现同样的效果
在 the official docs. Learn about filters here 中阅读更多关于它们的信息。
样本中使用的简单模型class
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
这是我最简单的解决方案:
public IActionResult InfoTag()
{
return Ok(new {name = "Fabio", age = 42, gender = "M"});
}
或
public IActionResult InfoTag()
{
return Json(new {name = "Fabio", age = 42, gender = "M"});
}
使用枚举代替 404/201 状态码
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 !!!"));
}
我在 Asp Net Core Api 应用程序中所做的是创建一个 class 从 ObjectResult 扩展并提供许多构造函数来自定义内容和状态代码。 然后,我所有的 Controller 操作都适当地使用其中一个构造函数。 您可以在以下位置查看我的实现: https://github.com/melardev/AspNetCoreApiPaginatedCrud
和
https://github.com/melardev/ApiAspCoreEcommerce
这里是 class 的样子(去我的仓库获取完整代码):
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 的 base(dto),你应该可以开始了。
我在这里找到了很棒的答案,我也试过这个 return 语句见 StatusCode(whatever code you wish)
并且它有效!!!
return Ok(new {
Token = new JwtSecurityTokenHandler().WriteToken(token),
Expiration = token.ValidTo,
username = user.FullName,
StatusCode = StatusCode(200)
});
我成功了。我的大问题是我的 json 是一个字符串(在我的数据库中...而不是 specific/known 类型)。
好的,我终于让它工作了。
////[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.1.0\ref\netcoreapp3.1\Microsoft.AspNetCore.Mvc.Core.dll
我从这里得到提示:: https://www.jianshu.com/p/7b3e92c42b61
控制器操作 return 键入 ASP.NET 核心网络 API 2020 年 2 月 3 日
6 分钟阅读时间 +2
作者:斯科特·艾迪 Link
[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);
}
我找到的最干净的解决方案是在 Startup.cs 中的 ConfigureServices 方法中设置以下内容(在我的例子中,我希望删除 TZ 信息。我总是希望看到用户看到的日期时间).
services.AddControllers()
.AddNewtonsoftJson(o =>
{
o.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Unspecified;
});
DateTimeZoneHandling 选项是 Utc、Unspecified、Local 或 RoundtripKind
我仍然想找到一种方法能够在每次调用的基础上请求这个。
类似
static readonly JsonMediaTypeFormatter _jsonFormatter = new JsonMediaTypeFormatter();
_jsonFormatter.SerializerSettings = new JsonSerializerSettings()
{DateTimeZoneHandling = DateTimeZoneHandling.Unspecified};
return Ok("Hello World", _jsonFormatter );
我正在从 ASP.NET 进行转换,并且我使用了以下辅助方法
public static ActionResult<T> Ok<T>(T result, HttpContext context)
{
var responseMessage = context.GetHttpRequestMessage().CreateResponse(HttpStatusCode.OK, result, _jsonFormatter);
return new ResponseMessageResult(responseMessage);
}