2013-07-24 2 views
1

ASP.NET 웹 API 컨트롤러에서 상당히 긴 Get() 메서드가 있습니다. 이런 식으로 뭔가가 :ASP.NET 웹 API에서 인식 할 수없는 쿼리 매개 변수 찾기

public PaginatedResult Get(int perPage = 10, int pageNum = 0, string param1 = null, [...] string param20 = null) 

내가 원하는 것은 요청이 메소드 서명의 일부가 아니다 쿼리 PARAM을 포함 상황을 처리 할 수있을 것입니다. 누군가가이 요청하는 경우 즉, :

/?perPage=10&paran19=foo&param21=bar 

... 나는, 안녕 ','paran19 '이나'param21 '이도를 말할 수 있어야합니다, 그래서 그들은이 결과에 영향을 미치지 않습니다 질문!"

내가 처리 할 수있는 유일한 방법은 요청에서 GetQueryNameValuePairs()를 호출 한 다음 리플렉션을 사용하여 해당 목록을 내 Get() 메서드에서 허용하는 매개 변수와 비교하는 것입니다. 그래도이 문제는 과도한 것처럼 보입니다. 더 좋은 방법이 있습니까? 여러 가지 방법에 쉽게 적용 할 수있을 정도로 유연한 것이 이상적입니다.

+1

궁극적으로 다른 곳에서 '일치'하지 않은 인수 (GetQueryNameValuePairs)를 찾아야한다고 생각합니다. 이를 수행하기 위해 사용자 정의 ModelBinder를 작성하여 컨트롤러에 복잡성을 추가하지 않도록 할 수 있습니다. –

답변

0

잘하면이 자체 응답은 가난한 형태가 아니지만 Cj S.의 답변에서 약간 깬다면 Web API 메시지 수명주기에 대해 더 자세히 살펴본 결과 Action Filter를 만들었습니다.

public class QueryParamMatchingActionFilter : ActionFilterAttribute 
{ 

    public override void OnActionExecuting(HttpActionContext filterContext) 
    { 
     List<string> queryParamNames = filterContext.Request.GetQueryNameValuePairs().Select(q => (string)q.Key.ToLowerInvariant()).ToList(); 

     List<string> methodParams = filterContext.ActionArguments.Select(q => (string)q.Key.ToLowerInvariant()).ToList(); 

     List<string> unrecognized = queryParamNames.Where(qp => !methodParams.Any(mp => mp == qp)).ToList(); 

     if (unrecognized.Count > 0) 
     { 
      List<string> errors; 
      if (filterContext.Request.Properties.ContainsKey("MY_ERRORS")) 
       errors = (List<string>)filterContext.Request.Properties["MY_ERRORS"]; 
      else 
       errors = new List<string>(); 

      foreach (string badParam in unrecognized) 
      { 
       errors.Add(String.Format("UNRECOGNIZED PARAMETER IGNORED: {0}", badParam)); 
      } 

      filterContext.Request.Properties["MY_ERRORS"] = errors; 
     } 
    } 

} 

그래서 지금은 그냥 "[QueryParamMatchingActionFilter]"내 컨트롤러를 장식하실 수 있습니다. MY_ERRORS의 내용은 DelegatingHandler에 의해 응답됩니다. 이미 유용한 메타 데이터로 응답을 래핑하는 설정이 있습니다. 그러나이 코드는 외래 매개 변수를 사용하여 다른 작업을 수행하는 용도로 쉽게 사용할 수 있어야합니다. filterContext의 ActionArguments 속성을 사용할 수 있다는 것은 리플렉션을 사용하여 건너 뛸 수 있음을 의미하지만, 다른 누군가가이 작업을보다 효율적으로 수행 할 수 있다는 것을 알고 있다면 놀라지 않을 것입니다.