Dot-Net

在自定義授權 MVC4 Web Api 中訪問 post 或 get 參數

  • October 10, 2012

是否可以通過 HttpActionContext 對象訪問文章或獲取參數?

我有一組感測器將數據記錄到提供 REST api 的 Web 伺服器。我想通過讓感測器在數據中包含它們的硬體 id 來引入某種身份驗證/授權,然後在數據庫中查找該 id 是否存在。由於 API 提供了許多 Web api 操作方法,因此我最好使用自定義授權屬性

public class ApiAuthorizationFilter : AuthorizeAttribute
{
   protected override bool IsAuthorized(HttpActionContext actionContext)
   {
       return false;
   }
}

如何從 actionContext 訪問發布/獲取數據?

編輯:POST 範例

POST /Api/api/ActionMethod/ HTTP/1.1\r\n
Content-Type: application/json\r\n
Host: localhost\r\n
Accept: */*\r\n
Content-Length:52\r\n
\r\n
{"Id": '121a222bc', "Time": '2012-02-02 12:00:00'}\r\n

祝你今天過得愉快!

由於其性質,AuthoriseAttribute 看起來像是在模型綁定器和參數綁定執行之前在管道中呼叫它。當您訪問 Request.Content 並從中讀取時,您也會遇到問題…這只能完成一次,如果您要在 auth 屬性中嘗試它,您可能會破壞 mediaTypeFormater…

在 WebAPI 中,請求主體(一個 HttpContent)可能是一個只讀的、無限的、非緩衝的、不可回退的流。

更新 有不同的方法來指定執行上下文… <http://msdn.microsoft.com/en-us/library/system.web.http.filters.filterscope(v=vs.108).aspx>。AuthoriseAttribute 是“全域”的,因此訪問操作資訊的時間過早。

鑑於您想要訪問模型和參數,您可以稍微改變您的方法並使用 OnActionExecuting 過濾器(“Action”過濾器範圍),並根據您的驗證拋出 401 或 403。

此過濾器稍後在執行過程中呼叫,因此您可以完全訪問綁定的數據。

下面非常簡單的例子:

public class ApiAuthorizationFilter : ActionFilterAttribute
{
   public override void OnActionExecuting(HttpActionContext actionContext)
   {
       Foo model = (Foo)actionContext.ActionArguments["model"];
       string param1 = (string)actionContext.ActionArguments["param1"];
       int param2 = (int)actionContext.ActionArguments["param2"];

       if (model.Id != "1")
           throw new HttpResponseException(System.Net.HttpStatusCode.Forbidden);

       base.OnActionExecuting(actionContext);
   }
}

範例控制器:

public class Foo
{
   public string Id { get; set; }
   public DateTime Time { get; set; }
}

public class FoosController : ApiController
{
   // PUT api/foos/5
   [ApiAuthorizationFilter]
   public Foo Put(int id, Foo model, [FromUri]string param1 = null, int? param2 = null)
   {
       return model;
   }
}

其他答案在說什麼……他們是對的,如果您可以訪問 URL 上所需的所有內容,則可以通過請求獲取內容;但是,我認為模型和請求內容應該單獨保留:

var queryStringCollection = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query);

   //example for param1
   string param1 = queryStringCollection["param1"];
   //example for param2
   int param2 = int.Parse(queryStringCollection["param2"]);
   //Example of getting the ID from the URL
   var id = actionContext.Request.RequestUri.Segments.LastOrDefault();

引用自:https://stackoverflow.com/questions/12817202