HTTP 상태 코드가 있는 JSON을 반환하는 올바른 방법을 찾고 있습니다.NET Core 웹 API 컨트롤러입니다. 나는 이것을 이렇게 사용하곤 한다.
public IHttpActionResult GetResourceData()
{
return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}
이것은 4.6 MVC 응용 프로그램에 있었지만 지금은 에 있다.NET Core I don'NET Core I don't have this.IHttp ActionResult'가 있으며 다음과 같이 사용합니다.
public ActionResult IsAuthenticated()
{
return Ok(Json("123"));
}
그러나 아래 이미지와 같이 서버의 응답이 이상합니다.
[1
나는 단지 웹 API 컨트롤러가 웹 API 2에서 했던 것처럼 HTTP 상태 코드로 JSON을 반환하기를 원한다.
JsonResult로 응답하는 가장 기본적인 버전은 다음과 같다.
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
그러나 이는 자신의 응답 코드를 명시적으로 처리할 수 없기 때문에 문제 해결에 도움이 되지 않습니다.
상태 결과를 제어하려면 상태 코드 결과 유형을 사용할 수 있는 ActionResult를 반환해야 합니다.
예:
// 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 설명서에서 제공하는 훌륭한 안내서 응답 데이터 형식 지정에서 가져온 것입니다.
제가 자주 접하는 문제는 "의 기본 구성만 하는 것이 아니라 웹 API를 보다 세밀하게 제어하고 싶다는 것입니다.VS의 새 프로젝트" 템플릿
몇 가지 기본 사항을 숙지하고 있는지 확인해보십시오.
ASP를 받기 위해서.상태 코드를 완전히 제어하여 JSON 직렬화 개체로 응답하려면 NET Core WebAPI에서 일반적으로 "Startup.cs"에 있는 "Configure Services" 메서드에 "AddMvc()" 서비스를 포함했는지 확인해야 합니다.
'AddMvc()'는 다른 요청 유형에 대한 응답과 함께 JSON용 입력/출력 포맷터를 자동으로 포함한다는 점에 유의해야 합니다.
프로젝트에 전체 제어가 필요하고 웹 API가 '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)
}
다른 직렬화 형식(프로토버프, 절약 등)에 응답하려는 경우 사용자 지정 입력/출력 포맷을 추가할 수 있는 방법도 함께 포함되어 있습니다.
위의 코드 청크는 대부분 AddMvc() 메서드의 복제입니다. 그러나 템플릿과 함께 사전 배송된 서비스를 그대로 사용하는 대신 모든 서비스를 정의하여 각 "default" 서비스를 자체적으로 구현하고 있습니다. 코드 블록에 리포지토리 링크를 추가했거나, [GitHub 리포지토리에서 AddMvc()][2]를 확인할 수 있습니다.
일부 가이드는 이 문제를 처음부터 구현하지 않고 기본값으로 해결하려고 합니다. 만약 우리가 지금 오픈 소스와 함께 일하고 있다는 점을 고려한다면, 이것은 중복된 작업이고, 잘못된 코드이며, 솔직히 말해서 곧 사라질 오래된 습관이다.
질문을 정리하기 위해 아주 간단한 것을 보여드리겠습니다.
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();
}
}
요청에서 'Content-Type' 및 'Accept' 헤더가 올바르게 설정되어 있는지 확인해야 합니다. 사용자의 경우(JSON)에는 'application/json'으로 설정합니다.
요청 헤더에 지정된 내용에 관계없이 웹 API가 기본적으로 JSON으로 응답하도록 하려면 **몇 가지 방법으로 응답할 수 있습니다.
Way 1 앞에서 권장한 문서(Formatting Response Data)에서와 같이 컨트롤러/작업 수준에서 특정 형식을 강제 적용할 수 있습니다. 저는 개인적으로 이런 방식을 좋아하지 않습니다. 하지만 이건 완전성을 위한 거야
특정 형식 강제 적용 가능한 특정 작업에 대한 응답 형식을 제한하려면 [생산] 필터입니다. [Products] 필터는 응답을 지정합니다. 특정 작업(또는 컨트롤러)의 형식을 지정합니다. 대부분의 필터와 마찬가지로 이 필터는 는 작업, 컨트롤러 또는 전역 범위에서 적용할 수 있습니다.
[생산("애플리케이션/json")] 공용 클래스 작성자 제어기
'[Products]' 필터는 다음 시간 내에 모든 작업을 강제로 수행합니다. "AuthorsController"는 다른 응답을 반환하는 경우에도 JSON 형식 응답 포맷터가 애플리케이션 및 제공된 클라이언트에 대해 구성되었습니다. 사용 가능한 다른 형식을 요청하는 'Accept' 헤더입니다.
**Way 2* 내가 선호하는 방법은 웹 API가 요청한 형식으로 모든 요청에 응답하는 것이다. 그러나 요청된 형식을 수락하지 않는 경우 폴백**이 기본값으로 설정됩니다. JSON)
먼저 옵션에서 해당 항목을 등록해야 합니다(앞에서 설명한 대로 기본 동작을 다시 만들어야 합니다).
options.RespectBrowserAcceptHeader = true; // false by default
마지막으로, 단순히 서비스 작성기에 정의된 포맷터 목록을 다시 정렬하면 웹 호스트는 기본적으로 목록 맨 위에 있는 포맷터(즉, 위치 0)로 설정됩니다.
자세한 내용은 이 []에서 확인할 수 있습니다.NET 웹 개발 및 도구 블로그 항목]3
[2]: https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/Mvc 서비스 컬렉션Extensions.cs
대부분의 일반 상태 코드에 대해 미리 정의된 메서드가 있습니다.
모든 방법 목록은 'BaseController.cs' 및 'Controller.cs'를 참조하십시오.
그러나 만약 당신이 정말로 '상태 코드'를 사용하여 사용자 지정 코드를 설정할 수 있다고 주장한다면, 당신은 그것이 코드를 덜 읽을 수 있게 하고 헤더를 설정하기 위해 코드를 반복해야 하기 때문에('CreatedAtRoute'의 경우처럼) 정말로 그렇게 해야 한다.
public ActionResult IsAuthenticated()
{
return StatusCode(200, "123");
}
진ASP.NET 핵심 2.0,이상적인 방법을 개체 반환에서웹 API
(는 통합과 MVC 고 사용하여 동일한 기본 클래스컨트롤러
)은
public IActionResult Get()
{
return new OkObjectResult(new Item { Id = 123, Name = "Hero" });
}
알
200OK
상태 코드(그것이's anOk
형식의ObjectResult
)가 보낸 요청에서,it'll
로 돌아온 XML. 는 경우에도 전송,
JSON`은 기본입니다.그것은 필요가있는 경우에 보낼로 특정 상태호,사용 ObjectResult
또는`상태코드합니다. 모두 같은 일을 지원하고,콘텐츠 협상.
return new ObjectResult(new Item { Id = 123, Name = "Hero" }) { StatusCode = 200 };
return StatusCode( 200, new Item { Id = 123, Name = "Hero" });
는 경우에 당신을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)
.생산()
특성(는ResultFilter
)가contentType=application/json
자세히보기에 그들에 대해공식 문서. 에 대해 배우필터를 여기.
간단한 모델 클래스에 사용되는 샘플
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
가장 쉬운 방법이 나온다:
var result = new Item { Id = 123, Name = "Hero" };
return new JsonResult(result)
{
StatusCode = StatusCodes.Status201Created // Status code here
};
를 사용하는 대신 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 핵심 Api 응용 프로그램을 확장하는 클래스를 만들에서 ObjectResult 제공하는 많은 생성자를 사용자 정의 컨텐츠와 상태 코드입니다. 그런 내 모든 컨트롤러의 동작 중 하나를 사용 costructors 으로 적합하다. 당신이 볼 수 있는 내 구현: https://github.com/melardev/AspNetCoreApiPaginatedCrud
고
https://github.com/melardev/ApiAspCoreEcommerce
는 방법은 다음과 같습니다:등처럼 보인(내 repo 대체 코드):
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 으로 귀하의 개체고 있어야 합 갈 수 있습니다.
아래 코드를 참조하십시오. 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.");
}
}