在自定義授權 MVC4 Web Api 中訪問 post 或 get 參數
是否可以通過 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();