2012-08-31 1 views
5

나는 다음과 같은 API 컨트롤러가 있습니다MVC API 작업 및 System.Web.Http.AuthorizeAttribute - 게시 매개 변수를 가져 오는 방법?

public class TestController : ApiController 
{ 
    [HttpPost] 
    [APIAuthorizeAttribute] 
    public IQueryable<Computers> ListOfComputersInFolder(Guid folderId) 
    { 
     return GetListOfComputersForFolder(folderId); 
    } // End of ListOfComputersInFolder 
} // End of TestController 

을 그리고 다음 내 기본 APIAuthorizeAttribute입니다. 나는 데

public class APIAuthorizeAttribute : System.Web.Http.AuthorizeAttribute 
{ 
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     var Request = System.Web.HttpContext.Current.Request; 
     var folderId = Request.RequestContext.RouteData.Values["folderId"] ?? Request.Params["folderId] as string; 
     if(null == folderId) 
     { 
      folderId = actionContext.ControllerContext.RouteData.Values["folderId"]; 
     } 

     base.OnAuthorization(actionContext); 
    } 
} 

문제는 folderId가 onAuthorize 방법에 널 (null)을오고 있다는 점이다. (나는 this 코드에 fetcher 기반으로했다.)

나는 이것이 작동해야한다고 생각하지만, 나는 그것을 얻을 수없는 것 같습니다. 내가 뭘 잘못하고 어떻게 게시 된 매개 변수를 가져 가야하는지에 대한 아이디어가 있습니까?

편집 :

내게 다음 구문 분석 할 수 JSON 형식으로 포스트 데이터를 가져
using (StreamReader inputStream = new StreamReader(request.InputStream)) 
{ 
    output = inputStream.ReadToEnd(); 
} 
request.InputStream.Position = 0; 

하지만 그때 내 전화는 비록하게 결코 : 나는 다음과 직접 포스트 데이터를 읽는 시도했다.

<h2>500 - Internal server error.</h2> 
    <h3>There is a problem with the resource you are looking for, and it cannot be displayed. 

at System.Json.JXmlToJsonValueConverter.JXMLToJsonValue(Stream jsonStream, Byte[] jsonBytes)\u000d\u000a at System.Net.Http.Formatting.JsonMediaTypeFormatter.<>c__DisplayClass7.<OnReadFromStreamAsync>b__6()\u000d\u000a at System.Net.Http.Internal.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)"} 

편집 : 나는 응답에 다음과 같은 예외를 얻을이 가능 ApiController, System.Web.Http.AuthorizeAttributeHttpPost의 조합 버그가 있었던 것처럼 를 결국, (HttpGet를 사용하는 경우이 작업을 수행) 보인다. 버그 보고서가 제출되었습니다.

답변

7

AuthorizeAttributeHttpActionContext이 아니고 AuthorizationContext 매개 변수 여야합니다. 그 중 RouteData에 액세스 할 수 있어야합니다.

public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    var folderId = filterContext.RouteData.Values["folderId"]; 
    ... 
} 

업데이트

당신이 ApiController을 사용하고 같은 Http.AuthorizeAttribute를 사용 드러내 (당신이 AuthorizationContext이없는 이유를 설명). 이 경우 액션 컨텍스트를 통해 RouteData을 가져올 수 있습니다.

var folderId = actionContext.Request.GetRouteData().Values["folderId"]; 
+3

참고이가 [APIController]이기 때문에 그 (http://msdn.microsoft.com/en-us/library/system.web.http.apicontroller(v=vs.108).aspx) 및 [컨트롤러] (http://msdn.microsoft.com /en-us/library/system.web.mvc.controller(v=vs.108)) .aspx), 나는 System.Web.Mvc.AuthorizeAttribute가 아닌'System.Web.Http.AuthorizeAttribute'를 사용합니다. 나는 그것의'ControllerContext.RouteData.Values ​​[ "folderId"]에 접근하려고 시도했지만 여전히 null을 리턴했다. – Kyle

+0

@Zenox 내 업데이트 된 답변을 참조하십시오. – James

+0

덕분에 나는 이것도 보았지만 아직도 운이 없다. 'actionContext.Request' 클래스는 [HttpRequestMessage] (http://msdn.microsoft.com/en-us/library/system.net.http.httprequestmessage_methods)이며'GetRouteData' 메소드를 포함하지 않습니다. 또한 보면 : actionContext.ControllerContext.RouteData.Values에는 컨트롤러와 액션이라는 두 개의 키만 포함되어 있습니다. 최선의 선택은 inputStream에서 포스트 데이터를 읽는 것이라고 생각합니다. 나는 이것을 시도해 보았고 나의 게시물 데이터를 볼 수 있다는 것을 확인했지만 조금 해킹 된 것처럼 보였으므로 지금 당분간 찾고있다. – Kyle

0

당신은이 확장 방법에게 시험을 제공 할 수 있습니다 : 나는 제임스의 대답에 동의

public static string GetParameter(this RequestContext requestContext, string key) 
{ 
    if (key == null) throw new ArgumentNullException("key"); 

    var lowKey = key.ToLower(); 

    return requestContext.RouteData.Values.ContainsKey(lowKey) && 
      requestContext.RouteData.Values[lowKey] != null 
       ? requestContext.RouteData.Values[lowKey].ToString() 
       : requestContext.HttpContext.Request.Params[lowKey]; 
} 

(이것이 작동 코드의 발췌 한 것입니다), 당신은에 ActionContext에를 통해 요청 컨텍스트에 액세스 할 수 있습니다 이 시나리오.

1

이 문제가 발생했습니다. 당신이 일치하는 압축을 해제 할

  • 키 :

    private static object GetValueFromActionContext(HttpActionContext actionContext, string key) 
    { 
        var queryNameValuePairs = actionContext.Request.GetQueryNameValuePairs(); 
    
        var value = queryNameValuePairs 
         .Where(pair => pair.Key.Equals(key, StringComparison.OrdinalIgnoreCase)) 
         .Select(pair => pair.Value) 
         .FirstOrDefault(); 
    
        var methodInfo = ((ReflectedHttpActionDescriptor) (actionContext.ActionDescriptor)).MethodInfo; 
        var parameters = methodInfo.GetParameters(); 
        var parameterType = 
         parameters.Single(p => p.Name.Equals(key, StringComparison.OrdinalIgnoreCase)).ParameterType; 
    
        var converter = TypeDescriptor.GetConverter(parameterType); 
    
        return converter.ConvertFromString(value); 
    } 
    

    이 코드는 다음과 같은 가정을한다 :

    는 해결하려면 본인은 OnAuthorization 메소드 내에서 호출 다음과 같은 방법을 썼다 조치 메소드의 인수 이름.

  • 얻는 매개 변수 유형에는 해당 유형에 유효한 변환기가 있습니다.

  • 매개 변수에 사용자 지정 바인딩이나 서식을 사용하고 있지 않습니다.

나는 코드를 사용하고 있는데 Guid, Boolean, String 등의 간단한 유형 만 기대하며 요구 사항에 따라 사용자 정의 할 수 있습니다.

확장 메서드 GetQueryNameValuePairs는 System.Net.Http.HttpRequestMessageExtensions 클래스의 일부이며 쿼리 문자열/양식 데이터를 읽습니다.

사용 예 :

object folderId = GetValueFromActionContext(actionContext, "folderId"); 
0

요청의 컨텐트 유형은 application/json;charset=utf-8

경우 다음과 같이 포스트 데이터를 검색 할 수있는 API 동작 :

Stream stream = actionContext.Request.Content.ReadAsStreamAsync().Result; 
Encoding encoding = Encoding.UTF8; 
stream.Position = 0; 
string responseData = ""; 

using (StreamReader reader = new StreamReader(stream, encoding)) 
{ 
    responseData = reader.ReadToEnd().ToString(); 
} 

var dic = JsonConvert.DeserializeObject<IDictionary<string, string>>(responseData); 
관련 문제