code

ASP.NET Core가 상태 코드와 함께 JSON을 반환합니다.

starcafe 2023. 3. 29. 21:40
반응형

ASP.NET Core가 상태 코드와 함께 JSON을 반환합니다.

에서 HTTP 상태 코드를 사용하여 JSON을 반환하는 올바른 방법을 찾고 있습니다.NET Core Web API 컨트롤러.나는 이것을 이렇게 사용하곤 했다.

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을 반환해 주었으면 합니다.

" "로 인 버전JsonResult 말합니다

// GET: api/authors
[HttpGet]
public JsonResult Get()
{
    return Json(_authorRepository.List());
}

단, 고객 자신의 응답 코드를 명시적으로 처리할 수 없기 때문에 이 방법은 고객님의 문제에 도움이 되지 않습니다.

하려면 , .ActionResult '먹다', '먹다', '먹다'를 할 수 .StatusCodeResultdiscloss.discloss.

예를 들어 다음과 같습니다.

// 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 Documentation에서 입수할 수 있는 훌륭한 가이드에 기재되어 있습니다.응답 데이터 형식 지정


추가 정보

자주 발생하는 문제는 VS의 "New Project" 템플릿에서 기본 구성을 사용하는 것이 아니라 WebAPI를 보다 세밀하게 제어해야 한다는 것입니다.

기본적인 사항들을 확실히 파악해두죠.

순서 1: 서비스 설정

ASP の asp asp 。코드의 JSON Serialized Object가 되어 있는지 .AddMvc()를 하다ConfigureServices 에서 볼 수 있는 Startup.cs.

할 점은AddMvc()에는 다른 요구 유형에 대한 응답과 함께 JSON용 입력/출력 포메터가 자동으로 포함됩니다.

프로젝트에 완전한 제어가 필요하고 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)
}

다른 시리얼라이제이션 포맷(protobuf, slift 등)에 응답하고 싶은 경우에 대비하여 커스텀 입력/출력 포맷을 추가하는 방법도 포함되어 있습니다.

복제 입니다.AddMvc() however. 템플릿과 ' 하고 있습니다.단, 템플릿과 함께 출하된 서비스가 아니라 모든 서비스를 정의함으로써 각각의 "기본" 서비스를 자체적으로 구현하고 있습니다.블록에 , 「 」를 체크 할 수 있습니다.AddMvc() GitHub 저장소에서 가져옵니다.

이 문제를 해결하기 위해 처음부터 구현하지 않는 것이 아니라 기본 설정을 "해제"하여 해결하는 가이드도 있습니다.오픈 소스로 작업하고 있는 것을 고려하면, 이것은 장황한 작업이며, 코드도 나쁘고, 솔직히 말하면 오래된 습관도 곧 없어질 것입니다.


순서 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 앞서 권장한 기사(응답 데이터 포맷)에서 보듯이 컨트롤러/액션 수준에서 특정 형식을 강제 적용할 수 있습니다.난 개인적으로 이런 방식이 마음에 안 들어...여기에서는 완전성을 추구합니다.

특정 형식 강제 적용 가능한 특정 작업에 대한 응답 형식을 제한하려면 [Products] 필터를 적용할 수 있습니다.[Products] 필터는 특정 액션(또는 컨트롤러)에 대한 응답 형식을 지정합니다.대부분의 필터와 마찬가지로 액션, 컨트롤러 또는 글로벌 범위에서 적용할 수 있습니다.

[Produces("application/json")]
public class AuthorsController

[Produces]는, 「필터」합니다.AuthorsControllerJSON 응답을 되어 있고 가 Accept사용 가능한 다른 형식을 요구하는 헤더입니다.

방법 2 WebAPI가 모든 요청에 대해 요청된 형식으로 응답하는 것이 좋습니다.단, 요청된 형식을 받아들이지 않을 경우 기본값으로 폴백합니다(즉,JSON)

먼저 옵션을 등록해야 합니다(앞에서 설명한 바와 같이 기본 동작을 변경해야 합니다).

options.RespectBrowserAcceptHeader = true; // false by default

마지막으로 서비스 빌더에 정의되어 있는 포메터의 목록을 정렬하는 것만으로 웹 호스트는 기본적으로 목록의 맨 위에 배치한 포메터(위치 0)로 바뀝니다.

상세한 것에 대하여는, 을 참조해 주세요.NET Web Development and Tools 블로그 엔트리

대부분의 일반적인 상태 코드에 대해 미리 정의된 방법이 있습니다.

  • Ok(result)200
  • CreatedAtRoute201 URL + 로 + url URL
  • NotFound404
  • BadRequest400★★★★★★★★★★★★★★★.

모든 메서드의 리스트에 대해서는및 을 참조해 주십시오.

.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" });
}

주의해 주세요

  1. 와 함께 반환됩니다.200 OK코드(「」입니다OkObjectResult)
  2. . 즉,을 합니다.Accept헤더가 요구되고 있습니다. ifAccept: 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" };
}

주의해 주세요

  1. 다 " " "를 적용합니다.JSON두 가지 방법으로요.
  2. 둘 다 콘텐츠네고시에이션을 무시합니다.
  3. 번째 은 특정 에 JSON을 합니다.Json(object).
  4. 번째 은 똑같이 요.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"});
}

멋진 , 이요.여기서 찾은 답변과 이 반환문도 시도해 보았습니다.StatusCode(whatever code you wish)★★★★★★★!!!

return Ok(new {
                    Token = new JwtSecurityTokenHandler().WriteToken(token),
                    Expiration = token.ValidTo,
                    username = user.FullName,
                    StatusCode = StatusCode(200)
                });

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 !!!"));
    }

ASP의 컨트롤러 작업 반환 유형입니다.NET Core Web API 02/03/2020

+2까지 6분 소요

Scott Addie 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);
}

아래 코드를 참조하십시오. 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 에서 보실 수 있습니다.

그리고.

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를 오브젝트로 대체하면 바로 사용할 수 있습니다.

내가 할 일이 있어.내 큰 문제는 내 아들이 문자열이라는 거야 (데이터베이스에서...)특정/알려진 타입이 아닙니다).

좋아, 드디어 작동하게 됐어

////[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

지금까지 발견된 솔루션 중 가장 깨끗한 것은 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);
    }

언급URL : https://stackoverflow.com/questions/42360139/asp-net-core-return-json-with-status-code

반응형