ASP.NET Core Mvc 중 공 반환 값 처리 방법 상세 설명

9568 단어 coremvc빈 반환 값
머리말
만약 당신 이 초보 자가 ASP.NET 이나 ASP.NET MVC 를 배우 기 시작 했다 면,당신 은 무엇이.net Framework 와.net ore 인지 모 를 것 입 니 다.걱정 마!공식 문 서 를 보 시 는 것 을 권장 합 니 다.https://docs.microsoft.com/zh-cn/aspnet/index 비교 와 차 이 를 쉽게 볼 수 있 습 니 다.
.NET Core MVC 는 조작 결 과 를 어떻게 되 돌려 주 는 지 매우 유연 하 다.
IAction Result 인 터 페 이 스 를 실현 하 는 대상 으로 돌아 갈 수 있 습 니 다.예 를 들 어 우리 가 잘 알 고 있 는 ViewResult,FileResult,ContentResult 등 입 니 다.

[HttpGet]
public IActionResult SayGood()
{
 return Content("Good!");
}
물론 당신 은 같은 종류의 인 스 턴 스 를 직접 되 돌려 줄 수 있 습 니 다.

[HttpGet]
public string HelloWorld()
{
 return "Hello World";
}
.NET Core 2.1 에 서 는 Action Result 의 일반적인 대상 으로 돌아 갈 수 있다.

[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
 return new string[] { "value1", "value2" };
}
오늘 블 로그 에 서 는.NET Core Mvc 가 빈 값 대상 으로 돌아 가 는 방법 과.NET Core Mvc 가 빈 값 대상 결과 에 대한 기본 행동 을 어떻게 바 꾸 는 지 살 펴 보 겠 습 니 다.
다음은 더 이상 할 말 이 없 으 니 상세 한 소 개 를 살 펴 봅 시다.
.NET Core Mvc 의 빈 값 대상 에 대한 기본 처리 행위
그렇다면 우리 가 Action 에서 null 로 돌 아 왔 을 때 결 과 는 어 땠 을 까?
다음은 ASP.NET Core WebApi 프로젝트 를 새로 만 들 고 BookController 를 추가 합 니 다.코드 는 다음 과 같 습 니 다.

[Route("api/[controller]")]
[ApiController]
public class BookController : ControllerBase
{
 private readonly List<Book> _books = new List<Book> {
  new Book(1, "CLR via C#"),
  new Book(2, ".NET Core Programming")
 };

 [HttpGet("{id}")]
 public IActionResult GetById(int id)
 {
  var item = _books.FirstOrDefault(p => p.BookId == id);
  return Ok(item);
 }

 //[HttpGet("{id}")]
 //public ActionResult<Book> GetById(int id)
 //{
 // var book = _books.FirstOrDefault(p => p.BookId == id);
 // return book;
 //}

 //[HttpGet("{id}")]
 //public Book GetById(int id)
 //{
 // var book = _books.FirstOrDefault(p => p.BookId == id);
 // return book;
 //}
}

public class Book
{
 public Book(int bookId, string bookName)
 {
  BookId = bookId;
  BookName = bookName;
 }

 public int BookId { get; set; }

 public string BookName { get; set; }
}
이 Controller 에서 우 리 는 도서 의 집합 을 정 의 했 고 도서 ID 에 따라 도 서 를 조회 하 는 세 가지 실현 방식 을 제공 했다.
그리고 프로젝트 를 시작 하고 Postman 을 사용 하 며/api/book/3 을 요청 합 니 다.결 과 는 다음 과 같 습 니 다.

우리 가 생각 했 던 200 OK 가 아 닌 204 NoContent 로 돌아 온 Status 를 발견 할 수 있 을 것 이다.이전 코드 의 설명 을 수정 할 수 있 습 니 다.다른 두 가지 방식 을 사용 하면 결과 도 마찬가지 입 니 다.
일반적인 ASP.NET Mvc 프로젝트 를 만 들 고 비슷 한 코드 를 추가 할 수 있 습 니 다.결 과 는 다음 과 같 습 니 다.

돌아 온 결 과 는 200 OK,내용 은 null 입 니 다.
왜 결과 가 나 오지?
선배 들(ASP.NET Mvc,ASP.NET WebApi)과 달리 ASP.NET Core Mvc 는 null 값 을 교묘 하 게 처 리 했 습 니 다.위의 예 에서 ASP.NET Core Mvc 는 응답 내용 을 출력 하기 위해 적합 한 출력 포맷 기(output formatter)를 선택 합 니 다.보통 이 출력 포맷 기 는 JSON 포맷 기 나 XML 포맷 기 입 니 다.
그러나 null 값 에 대해 ASP.NET Core Mvc 는 특수 한 포맷 기 HttpNoContentOutput Formatter 를 사용 하여 null 값 을 204 상태 코드 로 변환 합 니 다.이것 은 null 값 이 JSON 이나 XML 로 정렬 되 지 않 는 다 는 것 을 의미 합 니 다.이것 은 우리 가 기대 하 는 결과 가 아 닐 수도 있 습 니 다.가끔 우 리 는 200 OK 로 돌아 가 고 싶 습 니 다.응답 내용 은 null 입 니 다.
Tips:Action 반환 값 이 void 나 Task 일 때 ASP.NET Core Mvc 는 기본적으로 HttpNoContentOutput Formatter 를 사용 합 니 다.
설정 수정 을 통 해 기본 null 값 포맷 기 를 제거 합 니 다.
HttpNoContentOutputFormatter 대상 의 TreatNullValueAsNoContent 속성 을 false 로 설정 하여 기본 HttpNoContentOutputFormatter 가 null 값 에 대한 포맷 을 제거 할 수 있 습 니 다.
Startup.cs 파일 의 Configure Service 방법 에서 저 희 는 Mvc 서 비 스 를 추가 하 는 곳 에서 기본 출력 포맷 기 를 수정 합 니 다.코드 는 다음 과 같 습 니 다.

public void ConfigureServices(IServiceCollection services)
{
 services.AddMvc(o =>
 {
  o.OutputFormatters.RemoveType(typeof(HttpNoContentOutputFormatter));
  o.OutputFormatters.Insert(0, new HttpNoContentOutputFormatter 
  { 
   TreatNullValueAsNoContent = false;
  });
 });
}
수정 후 프로그램 을 다시 실행 하고 Postman 을 사용 하여/api/book/3 에 접근 합 니 다.
결 과 는 다음 과 같 습 니 다.반환 값 200 OK,내용 은 null 입 니 다.이것 은 우리 의 수정 이 성공 했다 는 것 을 설명 합 니 다.

404 Not Found 페이지 를 찾 을 수 없습니다.
위의 예 에서 저 희 는 204 No Content 행 위 를 사용 하지 않 았 고 응답 결 과 는 200 OK 로 바 뀌 었 으 며 내용 은 null 입 니 다.그러나 때때로 우 리 는 어떤 결과 도 찾 지 못 할 때 404 Not Found 로 돌아 가 기 를 기대 합 니 다.그러면 이 럴 때 코드 를 수정 하고 확장 해 야 합 니까?
.NET Core Mvc 에 서 는 사용자 정의 필터(Custom Filter)를 사용 하여 이 행동 을 바 꿀 수 있 습 니 다.
여기 서 우 리 는 2 개의 특성 류 NotFoundAction FilterAttribute 와 NotFoundResultFilterAttribute 를 만 듭 니 다.코드 는 다음 과 같 습 니 다.

public class NotFoundActionFilterAttribute : ActionFilterAttribute
{
 public override void OnActionExecuted(ActionExecutedContext context)
 {
  if (context.Result is ObjectResult objectResult && objectResult.Value == null)
  {
   context.Result = new NotFoundResult();
  }
 }
}

public class NotFoundResultFilterAttribute : ResultFilterAttribute
{
 public override void OnResultExecuting(ResultExecutingContext context)
 {
  if (context.Result is ObjectResult objectResult && objectResult.Value == null)
  {
   context.Result = new NotFoundResult();
  }
 }
}
코드 해석
  • 여기 서 Action FilterAttribute 와 ResultFilterAttribute 를 사 용 했 습 니 다.Action FilterAttribute 의 OnAction Executed 방법 은 action 이 실 행 된 후에 실 행 됩 니 다.ResultFilterAttribute 의 OnResultExecuting 은 action 이 결 과 를 되 돌려 주기 전에 실 행 됩 니 다.
  • 이 두 가지 방법 은 모두 action 의 반환 결 과 를 바 꾸 는 것 입 니 다.결 과 를 되 돌려 주 는 값 이 null 이면 NotFoundResult
  • 로 바 꿉 니 다.
    추가 완료 후,당신 은 종 류 를 선택 하여 그들 을 추가 할 수 있 습 니 다.
    컨트롤 러 헤드
    
    [Route("api/[controller]")]
    [ApiController]
    [NotFoundResultFilter]
    public class BookController : ControllerBase
    {
     ...
    }
    액 션 헤드
    
    [HttpGet("{id}")]
    [NotFoundResultFilter]
    public IActionResult GetById(int id)
    {
     var item = _books.FirstOrDefault(p => p.BookId == id);
     return Ok(item);
    }
    Mvc 서 비 스 를 추가 할 때 도 설정 할 수 있 습 니 다.
    
    public void ConfigureServices(IServiceCollection services)
    {
     services.AddMvc(o =>
     {
      o.Filters.Add(new NotFoundResultFilterAttribute());
     });
    }
    다시 실행 할 항목 을 선택 한 후,효 과 는 설정 수정 을 통 해 기본 null 값 포맷 기 를 제거 하 는 것 과 같 습 니 다.
    IAlwaysRunResultFilter
    이상 의 몇 가지 해결 방안 은 완벽 해 보이 지만 실제로는 약간의 흠 이 있다.ASP.NET Core Mvc 에서 필터 의 단락 메커니즘(즉,모든 필터 에서 Result 에 대한 할당 은 프로그램 이 파이프 에 남 은 필 터 를 건 너 뛰 게 할 수 있 습 니 다)으로 인해 현재 일부 제3자 구성 요 소 를 사용 한 후 제3자 구성 요소 가 파이프 에 자신의 단락 여과 기 를 삽입 하여 코드 가 실 효 될 수 있 습 니 다.
    ASP.NET Core Mvc 필터
    다음은 다음 단락 필 터 를 추가 합 니 다.
    
    public class ShortCircuitingFilterAttribute : ActionFilterAttribute
    {
     public override void OnActionExecuting(ActionExecutingContext context)
     {
      context.Result = new ObjectResult(null);
     }
    }
    그리고 BookController 의 GetById 방법 을 수정 합 니 다.
    
    [HttpGet("{id}")]
    [ShortCircuitingFilter]
    [NotFoundActionFilter]
    public IActionResult GetById(int id)
    {
     var item = _books.FirstOrDefault(p => p.BookId == id);
     return Ok(item);
    }
    프로그램 을 다시 실행 한 후,Postman 을 사용 하여/api/book/3 에 접근 하고,프로그램 은 204 Not Content 를 되 돌려 줍 니 다.이것 은 우리 의 코드 가 효력 을 잃 었 다 는 것 을 설명 합 니 다.
    이때 이 문 제 를 해결 하기 위해 서 는.NET Core 2.1 에 새로 도 입 된 인터페이스 IAlways RunResultFilter 를 사용 해 야 한다.IAlwaysRunResultFilter 인 터 페 이 스 를 실현 하 는 필 터 는 항상 실 행 됩 니 다.앞의 필터 가 단락 을 촉발 하 든 말 든.
    여기에 새 필 터 를 추가 합 니 다.NotFoundation AlwaysRunFilterAttribute.
    
    public class NotFoundAlwaysRunFilterAttribute : Attribute, IAlwaysRunResultFilter
    {
     public void OnResultExecuted(ResultExecutedContext context)
     {
     }
    
     public void OnResultExecuting(ResultExecutingContext context)
     {
      if (context.Result is ObjectResult objectResult && objectResult.Value == null)
      {
       context.Result = new NotFoundResult();
      }
     }
    }
    그리고 저 희 는 BookController 의 GetById 방법 을 계속 수정 하여 NotFoundAlwaysRunFilter 기능 을 추가 합 니 다.
    
    [HttpGet("{id}")]
    [ShortCircuitingFilter]
    [NotFoundActionFilter]
    [NotFoundAlwaysRunFilter]
    public IActionResult GetById(int id)
    {
     var item = _books.FirstOrDefault(p => p.BookId == id);
     return Ok(item);
    }
    프로그램 을 다시 실행 한 후,Postman 을 사용 하여/api/book/3 에 접근 하 였 으 며,프로그램 은 404 Not Found 를 성공 적 으로 되 돌려 주 었 습 니 다.이것 은 우리 의 코드 가 또 효력 이 발생 했 음 을 설명 합 니 다.
    이 원본 코드:https://github.com/lamondlu/NullAction ( 로 컬 다운로드
    원본 주소:https://www.strathweb.com/2018/10/convert-null-valued-results-to-404-in-asp-net-core-mvc/
    작성 자:Filip W.
    Lamond Lu
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기