2014-02-20 3 views
1

Я хотел бы переопределить контроллер API, чтобы проверить определенные значения в заголовке на всех вызовах HttpGet и HttpPost, поскольку они сделаны без включения кода для проверки в каждом звонке. В настоящее время мой метод выглядит следующим образом:Как переопределить HttpGet/HttpPost в Asp.net MVC 5 ApiController

public class MyApiController : ApiController 
{ 
    [HttpGet] 
    public HttpResponseMessage GetAccountById() 
    { 
     var accountId = (Request.Headers.Where(t => t.Key == "accountid").Count() == 0) ? null : Request.Headers.GetValues("accountid").First(); 
     var apiKey = (Request.Headers.Where(t => t.Key == "apikey").Count() == 0) ? null : Request.Headers.GetValues("apikey").First(); 

     if (String.IsNullOrEmpty(accountId)) { 
       return Request.CreateResponse(HttpStatusCode.Forbidden, "Please provide an Account Id."); 
     } 

     if (String.IsNullOrEmpty(apiKey)) { 
       return Request.CreateResponse(HttpStatusCode.Forbidden, "Please provide an Account Api Key."); 
     } 

     // Get Account 
     // return Account; 
    } 
} 

Как я могу сделать этот чек apikey/ACCOUNTID в каждом вызове без необходимости писать чек в каждый вызов?

РЕШЕНИЕ: Переопределение делегированияГандлер отлично работает.

ApiSecurityHandler.cs

public class ApiSecurityHandler : DelegatingHandler 
{ 
    public ApiSecurityHandler(HttpConfiguration httpConfiguration) 
    { 
     InnerHandler = new HttpControllerDispatcher(httpConfiguration); 
    } 

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     var accountId = (request.Headers.Where(t => t.Key == "accountid").Count() == 0) ? null : request.Headers.GetValues("accountid").First(); 
     var apiKey = (request.Headers.Where(t => t.Key == "apikey").Count() == 0) ? null : request.Headers.GetValues("apikey").First(); 

     if (String.IsNullOrEmpty(accountId)) { 
      var response = new HttpResponseMessage(HttpStatusCode.Forbidden); 
      response.Content = new StringContent("Please provide an Account Id."); 

      var tsc = new TaskCompletionSource<HttpResponseMessage>(); 
      tsc.SetResult(response); 
      return tsc.Task; 
     } 

     if (String.IsNullOrEmpty(apiKey)) { 
      var response = new HttpResponseMessage(HttpStatusCode.Forbidden); 
      response.Content = new StringContent("Please provide an Account Api Key."); 

      var tsc = new TaskCompletionSource<HttpResponseMessage>(); 
      tsc.SetResult(response); 
      return tsc.Task; 
     } 

     // Authorize the Account Id and Api Key here 
     using (var accountManager = new AccountManager()) { 
      if (!accountManager.AuthorizeAccountApiKey(accountId, apiKey)) { 
       var response = new HttpResponseMessage(HttpStatusCode.Forbidden); 
       response.Content = new StringContent("Api authorization denied."); 

       var tsc = new TaskCompletionSource<HttpResponseMessage>(); 
       tsc.SetResult(response); 
       return tsc.Task; 
      } 
     } 

     return base.SendAsync(request, cancellationToken); 
    } 
} 

И в вашей конфигурации маршрутизации просто добавить этот параметр на карте маршрут:

handler: new ApiSecurityHandler(GlobalConfiguration.Configuration) 

ответ

1

Я бы рекомендовал использовать DelegatingHandler.

This example from msdn показано, как переопределить заголовок

Этот код должен работать, наслаждаться:

public class Myhandler: DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessagerequest, CancellationToken cancellationToken) 
    { 
     if(request.Headers.Contains("accountid") && request.Headers.Contains("apikey")) 
     { 

      string accountid = request.Headers.GetValues("accountid").FirstOrDefault(); 
      string apikey = request.Headers.GetValues("apikey").FirstOrDefault(); 

       //HERE you can get your account and do what you want 
     }else{ 
       return SendError("please provide account id and api key", HttpStatusCode.Forbidden); 
     } 

      return base.SendAsync(request, cancellationToken); 
    } 




    private Task<HttpResponseMessage> SendError(string error, HttpStatusCode code) 
    { 
     var response = new HttpResponseMessage(); 
     response.Content = new StringContent(error); 
     response.StatusCode = code; 

     return Task<HttpResponseMessage>.Factory.StartNew(() => response); 
    } 

} 

one more example of DelegatingHandler

More examples

0

То, что я сделал бы, вместо того, наиважнейшая ApiController есть, создать базовый класс, который наследует ApiController и выполняет вашу кодировку. Как это:

public class APIBaseController : ApiController 
{ 
    [HttpGet] 
    public void APIBaseController() { 
     //Request.Headers.Count() 
    } 

    [HttpPost] 
    public void APIBaseController() { 
     //Request.Headers.Count() 
    } 
} 

А потом это сделать:

public class MyApiController : APIBaseController 
+0

Ну, да. Получил эту часть. Необходимо переопределить часть HttpGet для всех вызовов. –

+0

Не уверен, что это скомпилируется, но вы можете попробовать это (редактировать)? – user1477388

Смежные вопросы