3

ASP.NET Web Api 2 프레임 워크를 사용하고 아래의 기본 경로 제약 조건을 사용하고 있습니다.ASP.NET 웹 Api 경로 제한 HTTP 상태 반환 코드를 설정하는 방법

[Route("Number/{id:int:min(2):max(10)}")] 
    public HttpResponseMessage GetNumber([FromUri] int id) 
    { 
     return (id > 0) 
      ? Request.CreateResponse(HttpStatusCode.OK, id) 
      : Request.CreateResponse(HttpStatusCode.PreconditionFailed); 
    } 

id가 위의 제약 조건 인 .e.g와 충돌 할 때를 알고 싶습니다. 1 또는 11, 404의 기본 HTTP 상태 리턴 코드를 어떻게 무시할 수 있습니까?

대단히 감사합니다.

답변

7

당신은 분을 확인하는 사용자 정의 경로 제약 조건을 만들 수 있습니다, 당신처럼 최대 값은 소원하고, 또한 당신이 HttpStatusCode 경우에는 제약 조건이 제대로 이행되지 지정할 수 있습니다.

 var constraintResolver = new DefaultInlineConstraintResolver(); 
     constraintResolver.ConstraintMap.Add("rangeWithStatus", typeof(RangeWithStatusRouteConstraint)); 
     config.MapHttpAttributeRoutes(constraintResolver); 

그리고 당신의 경로가 지금과 같이 할 수 있습니다 :이 경우 Conflict

public class MyController : ApiController 
{ 
    [Route("Number/{id:int:rangeWithStatus(2, 10, PreconditionFailed)}")] 
    public HttpResponseMessage GetNumber([FromUri] int id) 
    { 
     return Request.CreateResponse(HttpStatusCode.OK, id); 
    } 
} 

이의 캐릭터 라인 표현입니다

public class RangeWithStatusRouteConstraint : IHttpRouteConstraint 
{ 
    private readonly int _from; 
    private readonly int _to; 
    private readonly HttpStatusCode _statusCode; 

    public RangeWithStatusRouteConstraint(int from, int to, string statusCode) 
    { 
     _from = from; 
     _to = to; 
     if (!Enum.TryParse(statusCode, true, out _statusCode)) 
     { 
      _statusCode = HttpStatusCode.NotFound; 
     } 
    } 

    public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, 
     HttpRouteDirection routeDirection) 
    { 
     object value; 
     if (values.TryGetValue(parameterName, out value) && value != null) 
     { 
      var stringValue = value as string; 
      var intValue = 0; 

      if (stringValue != null && int.TryParse(stringValue, out intValue)) 
      { 
       if (intValue >= _from && intValue <= _to) 
       { 
        return true; 
       } 

       //only throw if we had the expected type of value 
       //but it fell out of range 
       throw new HttpResponseException(_statusCode); 
      } 
     } 

     return false; 
    } 
} 

이제 특성 매핑에 등록해야 HttpStatusCode.Conflict 열거 형은 나중에 제약 조건의 열거 형 값으로 변환됩니다.

이러한 설정을 사용하면 값이 [2, 10] 범위를 벗어나면 웹 API 인프라가 기본값 404 대신 409 상태 코드로 응답합니다.

1

올바른 해결 방법은 컨트롤러 내부의 제약 조건을 확인하는 것입니다 (@aanund 제안). 그러나 Route 제약 조건을 유지하고 코드에서 조건문을 사용하지 않으려면 같은 경로를 사용하지만 제약 조건이없는 다른 액션 컨트롤러를 만들 수 있습니다. 제약 조건이 확인되지 않으면 새 작업 컨트롤러가 호출됩니다.

[Route("Number/{id:int:min(2):max(10)}")] 
public HttpResponseMessage GetNumber([FromUri] int id) 
{ 
    Request.CreateResponse(HttpStatusCode.OK, id) 
} 

[Route("Number/{id}")] 
public HttpResponseMessage GetNumber2([FromUri] int id) 
{ 
    Request.CreateResponse(HttpStatusCode.PreconditionFailed); 
} 
5

경로의 제약 조건을 제거하고 메서드 내부에서 유효성 검사를 수행합니다.

제약 조건은 경로를 전혀 사용해야 하는지를 결정하는 데 사용되지만 입력 값이 일부 매개 변수를 벗어나는 경우 상태 코드를 변경하려고합니다.

[Route("Number/{id})] // No constraints 
public HttpResponseMessage GetNumber([FromUri] int id) 
{ 
    return (id > 1 && id < 11) // here you validate id range 
     ? Request.CreateResponse(HttpStatusCode.OK, id) 
     : Request.CreateResponse(HttpStatusCode.PreconditionFailed); 
}