.NET Core Web API 컨트롤러에서 HTTP 상태 코드로 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 2에서했던 것처럼 HTTP 상태 코드로 JSON을 반환하기를 원합니다.
답변
a JsonResult
로 응답하는 가장 기본적인 버전 은 다음 과 같습니다.
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
그러나 자신의 응답 코드를 명시 적으로 처리 할 수 없기 때문에 문제를 해결하는 데 도움이되지 않습니다.
상태 결과를 제어하는 방법
ActionResult
은StatusCodeResult
유형 을 활용할 수있는 곳 을 반환해야한다는 것입니다 .
예를 들면 다음과 같습니다.
// 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 설명서에서 제공하는 훌륭한 가이드에서 제공 한 것입니다. 응답 데이터 형식화
추가 물건
내가 자주 접하는 문제는 VS의 “New Project”템플릿에서 기본 구성을 사용하기보다는 WebAPI를보다 세밀하게 제어하기를 원한다는 것입니다.
몇 가지 기본 사항이 있는지 확인하십시오 …
1 단계 : 서비스 구성
ASP.NET Core WebAPI가 상태 코드를 완전히 제어하면서 JSON Serialized Object로 응답하도록하려면 먼저에서 찾은 메소드에 AddMvc()
서비스를 포함시켜야합니다 .ConfigureServices
Startup.cs
AddMvc()
다른 요청 유형에 대한 응답과 함께 JSON 용 입력 / 출력 포맷터가 자동으로 포함 된다는 점에 유의해야 합니다.
프로젝트에 모든 권한이 필요 application/json
하고 다른 요청 유형 (예 : 표준 브라우저 요청)을 포함하여 응답하지 않는 다양한 요청 유형에 대한 WebAPI의 동작과 같은 서비스를 엄격하게 정의하려는 경우 다음 코드 :
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)
}
다른 직렬화 형식 (protobuf, thrift 등)에 응답하려는 경우 사용자 정의 입력 / 출력 포맷터를 추가 할 수있는 방법도 포함되어 있습니다.
위의 코드 덩어리는 대부분 AddMvc()
메서드 의 복제본입니다 . 그러나 템플릿이 포함 된 사전 배송 된 서비스를 사용하는 대신 각각의 모든 서비스를 정의하여 각 “기본”서비스를 자체적으로 구현하고 있습니다. 코드 블록에 리포지토리 링크를 추가했거나 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();
}
}
3 단계 : 확인 당신 Content-Type
과Accept
요청의 헤더 Content-Type
와 Accept
헤더가 올바르게 설정 되어 있는지 확인해야합니다 . 귀하의 경우 (JSON), 당신은 그것을 설정하고 싶을 것입니다application/json
.
요청 헤더의 지정에 관계없이 WebAPI가 기본값으로 JSON으로 응답하도록하려면 몇 가지 방법으로 수행 할 수 있습니다 .
방법 1
이전에 권장 한 기사 ( 응답 데이터 형식화 )에 표시된 것처럼 컨트롤러 / 액션 수준에서 특정 형식을 강제 할 수 있습니다. 나는 개인적 으로이 접근법을 좋아하지 않지만 … 완전성을위한 것입니다.
특정 형식 강제 적용 가능한 특정 작업에 대한 응답 형식을 제한하려면 [제작] 필터를 적용 할 수 있습니다. [Produces] 필터는 특정 작업 (또는 컨트롤러)에 대한 응답 형식을 지정합니다. 대부분의 필터와 마찬가지로이 값은 작업, 컨트롤러 또는 전역 범위에서 적용 할 수 있습니다.
[Produces("application/json")] public class AuthorsController
[Produces]
필터는 내의 모든 작업을 강제로
AuthorsController
다른 포매터가 응용 프로그램에 대한 구성 및 클라이언트가 제공 한 경우에도, JSON 형식의 응답을 반환하는Accept
다른 가능한 형식을 요청 헤더를.
방법 2
선호하는 방법은 WebAPI가 요청 된 형식으로 모든 요청에 응답하는 것입니다. 그러나,이 요구 된 형식을 허용하지 않는 경우에, 다음 가을 – 다시 초기 상태로 (즉. JSON)
먼저 옵션에 등록해야합니다 (앞서 언급 한대로 기본 동작을 다시 작업해야 함).
options.RespectBrowserAcceptHeader = true; // false by default
마지막으로, 서비스 빌더에 정의 된 포맷터 목록의 순서를 다시 정렬하면 웹 호스트는 목록의 맨 위에 위치하는 포맷터 (예 : 위치 0)로 기본 설정됩니다.
자세한 내용은이 .NET 웹 개발 및 도구 블로그 항목을 참조하십시오.
답변
가장 일반적인 상태 코드에 대해 미리 정의 된 방법이 있습니다.
Ok(result)
200
응답과 함께 반환CreatedAtRoute
201
+ 새로운 리소스 URL을 반환NotFound
보고404
BadRequest
400
등을 반환
참조 BaseController.cs
및 Controller.cs
모든 메소드의 목록.
그러나 정말로 주장한다면 StatusCode
사용자 정의 코드를 설정하는 데 사용할 수는 있지만 코드를 읽을 수 없게 만들고 헤더를 설정하기 위해 코드를 반복해야합니다 (와 같은 CreatedAtRoute
).
public ActionResult IsAuthenticated()
{
return StatusCode(200, "123");
}
답변
ASP.NET Core 2.0을 사용하면 객체를 반환하는 이상적인 방법 Web API
은 MVC와 통합되고 동일한 기본 클래스를 사용하는 것 Controller
입니다.
public IActionResult Get()
{
return new OkObjectResult(new Item { Id = 123, Name = "Hero" });
}
그것을주의해라
200 OK
상태 코드 와 함께 반환됩니다 (의Ok
유형 임ObjectResult
)- 콘텐츠 협상을 수행합니다. 즉,
Accept
요청 헤더에 따라 반환 됩니다.Accept: application/xml
요청이 전송 되면 로 반환됩니다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 };
특별히 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
서로 다른 두 가지 방식으로 시행 됩니다. - 둘 다 콘텐츠 협상을 무시합니다.
- 첫 번째 방법은 특정 serializer로 JSON을 적용
Json(object)
합니다. - 두 번째 방법은
Produces()
속성 (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
};
답변
이것이 가장 쉬운 해결책입니다.
public IActionResult InfoTag()
{
return Ok(new {name = "Fabio", age = 42, gender = "M"});
}
또는
public IActionResult InfoTag()
{
return Json(new {name = "Fabio", age = 42, gender = "M"});
}
답변
enum을 사용하여 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 !!!"));
}
답변
내가 여기서 찾은 멋진 대답과 나는이 반환 진술을 보았고 StatusCode(whatever code you wish)
효과가있었습니다 !!!
return Ok(new {
Token = new JwtSecurityTokenHandler().WriteToken(token),
Expiration = token.ValidTo,
username = user.FullName,
StatusCode = StatusCode(200)
});