MVC Api Action & System.Web.Http.AuthorizeAttribute - How to get post parameters?

情到浓时终转凉″ 提交于 2019-12-05 09:13:19

The AuthorizeAttribute should have an AuthorizationContext parameter rather than a HttpActionContext one, from that you should be able to access the RouteData e.g.

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

Update

Noticed you are using ApiController and as such using Http.AuthorizeAttribute (explains why you don't have an AuthorizationContext). In that case, you can get the RouteData via the action context e.g.

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

I have also encountered this problem.

To work around it I wrote the following method which I call from within the OnAuthorization method:

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

This code makes the following assumptions:

  • The key you are extracting matches an argument name on the action method.

  • The parameter type you are obtaining will have a converter valid for the type.

  • You are not using any custom binding or formatting on the parameter.

In the scenario that I am using the code I am only expecting simple types such as Guid, Boolean, String etc and could be customised as per your requirements.

The extension method GetQueryNameValuePairs is part of the System.Net.Http.HttpRequestMessageExtensions class and will read querystring / form data.

Example use:

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

If the request's contenttype is application/json;charset=utf-8

The API action can retrieve the Post Data as follow:

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);

You can give this extension method a try: (this is an excerpt of working code)

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];
}

I agree with James' answer, you have to access the request context via the actionContext in this scenario.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!