2016-02-17 2 views
0

По этому вопросу я не могу immplement IHttpModule когда само hsoting веб апите на службе оконкак добавить этот код в самообслуживание api?

Is there a way to add an httpModule when webApi is running with the HttpSelfHostServer?

Однако, мне еще нужно добавить этот код где-то в моей самодостаточна Web API. Я нашел этот блог о том, как исправить это: http://www.silver-it.com/node/182

код выглядит следующим образом, однако я не могу иметь IHttpModule реализован на aself прошел API

public class CORSPreflightModule : IHttpModule 
    { 
     private const string OPTIONSMETHOD = "OPTIONS"; 
     private const string ORIGINHEADER = "ORIGIN"; 
     private const string ALLOWEDORIGIN = "https://yourspodomain.sharepoint.com"; 
     void IHttpModule.Dispose() 
     { 

     } 
     void IHttpModule.Init(HttpApplication context) 
     {     
      context.PreSendRequestHeaders += (sender, e) => 
      { 
       var response = context.Response; 

       if (context.Request.Headers[ORIGINHEADER] == ALLOWEDORIGIN) 
       { 
        response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");      
        response.Headers.Add("Access-Control-Allow-Headers", "Content-Type");           
       } 
       if (context.Request.HttpMethod.ToUpperInvariant() == OPTIONSMETHOD && context.Request.Headers[ORIGINHEADER] == ALLOWEDORIGIN) 
       { 
        response.Headers.Clear(); 
        response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); 
        response.Headers.Add("Access-Control-Allow-Origin", "https://yourspodomain.sharepoint.com"); 
        response.Headers.Add("Access-Control-Allow-Credentials", "true"); 
        response.Headers.Add("Access-Control-Allow-Headers", "Content-Type"); 
        response.Clear(); 
        response.StatusCode = (int)HttpStatusCode.OK; 
       }                
      }; 

     }   

    } 

Мой самодостаточно Web API, как это :

Program.cs

static void Main() 
{ 
    try 
    { 
     ServiceBase[] ServicesToRun; 
     ServicesToRun = new ServiceBase[] 
     { 
      new APIServiceTest() 
     }; 
     ServiceBase.Run(ServicesToRun); 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
} 


class Startup 
    { 
     // Hack from https://stackoverflow.com/a/17227764/19020 to load controllers in 
     // another assembly. Another way to do this is to create a custom assembly resolver 
     //Type valuesControllerType = typeof(OWINTest.API.ValuesController); 

     // This code configures Web API. The Startup class is specified as a type 
     // parameter in the WebApp.Start method. 
     public void Configuration(IAppBuilder appBuilder) 
     { 
      try 
      { 
       //Debugger.Launch(); 
       // Configure Web API for self-host. 
       HttpConfiguration config = new HttpConfiguration(); 

       config.MessageHandlers.Add(new CustomHeaderHandler()); 
       var corsAttr = new EnableCorsAttribute(System.Configuration.ConfigurationManager.AppSettings["DominioSharePoint"].ToString(), "*", "*"); 
       config.EnableCors(corsAttr); 

       // Enable attribute based routing 
       // http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2 
       config.MapHttpAttributeRoutes(); 

       config.Routes.MapHttpRoute(
        name: "DefaultApi", 
        routeTemplate: "api/{controller}/{id}", 
        defaults: new { id = RouteParameter.Optional } 
       ); 

       appBuilder.UseWebApi(config); 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 

     } 
    } 

Мой контроллер:

[EnableCors(origins: "https://xx.sharepoint.com", headers: "*", methods: "*")] 
    public class CuentasCobroController : ApiController 
    { 

Однако из-за его самодостаточно я не могу реализовать IHttpModule там, как описано выше, но я могу создать пользовательский обработчик, как я могу implemente код выше из блога в пользовательский обработчик?

public class CustomHeaderHandler : DelegatingHandler 
    { 
     protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
     { 
      return base.SendAsync(request, cancellationToken) 
       .ContinueWith((task) => 
       { 
        HttpResponseMessage response = task.Result; 
        response.Headers.Add("Access-Control-Allow-Origin", "*"); 
        return response; 
       }); 
     } 
    } 

Вопрос в том, как я могу интегрировать первый код в запуск моей службы Windows?

ответ

3

Вы почти здесь, используя DelegatingHandler вместо IHttpModule.

config.MessageHandlers.Add(new CorsHeaderHandler()); 

ДелегированиеHandler.SendAsync может получать как запрос, так и ответ.

1

Проще говоря, вы не можете использовать IHttpModule с самообслуживанием Web API или что-либо, что не является IIS. IHttpModule - это только концепция IIS.

Что вы можете сделать, как вы обнаружили, вы можете изменить конвейер веб-API и вместо этого вставить свой код (или эквивалент веб-API). Это можно сделать с помощью DelegatingHandler или фильтра действий.

Простейшим решением, однако, было бы просто использовать пакет NuGet Microsoft.AspNet.WebApi.Cors. С объектом HttpConfiguration позвоните по номеру .EnableCors(...) и передайте объект EnableCorsAttribute в соответствии с the instructions here от Microsoft.

Это то, что вы уже сделали в своем коде выше, но, похоже, вы также пытаетесь добавить в пользовательский код CORS из своего HTTP-модуля. Если вы удалите атрибут EnableCors с вашего контроллера и удалите CustomHeaderHandler, он должен работать так, как вы ожидали.

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