2017-01-10 9 views
1

Я создаю прототип, с помощью которого я размещаю свой веб-сайт ASP.NET Core (стандартные контроллеры/представления и т. Д.) И API в рамках одного и того же проекта.ASP.NET Core отдельное промежуточное ПО для контроллеров области

Я хотел бы использовать следующую схему маршрута:

  • blah.com/xxxx - контроллеры и действия сайта.
  • blah.com/api/xxxx - api контроллеры и действия.

Мой подход до сих пор, чтобы посмотреть на местности и маршрут конфиг ниже работает отлично:

app.UseMvc(routes => 
{ 
    routes.MapRoute(
     name: "areaDefault", 
     template: "{area:exists}/{controller=Values}/{action=Index}"); 

    routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
}); 

Теперь я хочу расширить это использовать один набор промежуточного программного обеспечения при обращении к API и другой набор когда доступ к веб-сайту. На самом деле это использование разных настроек проверки подлинности между областями. Google-fu привел меня к методу IApplicationBuilder.Map, и в этом моя проблема.

Конфигурационный ниже работает для маршрута по умолчанию, Home/Index выполняется, но ничего после/API возвращает 404.

// TODO: Add common middleware. 

app.Map("/api", builder => 
{ 
    // TODO: Add api specific middleware. 

    app.UseMvc(routes => 
    { 
     routes.MapRoute(
      name: "apiDefault", 
      template: "api/{controller=Values}/{action=Index}"); 
    }); 
}); 

// TODO: Add website specific middleware. 

app.UseMvc(routes => 
{ 
    routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
}); 

Маршруты я пытавшиеся без успеха:

  • foo.com/апи
  • foo.com/api/values ​​
  • foo.com/api/values/index
  • foo.com/api/api
  • foo.com/api/api/values ​​
  • foo.com/api/api/values/index

ValuesController находится под Области папки/Api/Контроллеры и определяется как:

[Area("api")] 
public class ValuesController : Controller 
{ 
    public IActionResult Index() 
    { 
     return Json(new { test = 1 }); 
    } 
} 

полный источник воспроизвести это доступно здесь: https://github.com/AntSwift/ApiRouteTest

Могу ли я отправиться вниз правильный путь с этим, есть что-то очевидно, что я не хватает, или то, что я attemptin g просто невозможно.

ответ

1

Предлагаю сделать это по-другому и не смешивать их вместе. Просто создайте свою область api или используйте api routing так, как вы хотите. Затем создайте промежуточное ПО и назовите его «ApiAuthenticationMiddleware». Поместите его где-нибудь наверху конвейера configure. В этом промежуточном программном обеспечении рассматриваются различные свойства в httpcontext. В httpcontext есть много полезных значений. В вашем случае вы можете использовать свойство «путь», чтобы узнать, куда идет запрос.

Если на пути есть «/ api /». Это означает, что он идет к вашим апи. В противном случае он перейдет к вашим нормальным контроллерам. В этом случае вам нужно коротко замыкаться до следующего шага в трубопроводе.

Опять же в вашем случае вы можете использовать ниже фрагмент в своем промежуточном программном обеспечении в качестве примера.Вы должны изменить его так, как вы хотите:

public async Task Invoke(HttpContext httpContext, YourDbContext dbContext) 
    { 
     string requestPath = httpContext.Request.Path.Value; 

     if(!requestPath.Contains("/api/")) 
      await _next.Invoke(httpContext); 

     string authHeader = httpContext.Request.Headers["Authorization"]; 
     if (authHeader != null && authHeader.StartsWith("Basic")) 
     { 
      //Extract credentials 
      // other stuff 

      // example when no authorization header exists and want to reject. 
      httpContext.Response.StatusCode = 401; //Unauthorized 
      return; 


     // Call the next delegate/middleware in the pipeline 
     await _next.Invoke(httpContext); 
     } 
    } 
0

Проверьте это в разделе карты заменить app.UseMvc с builder.UseMvc

app.Map("/api", builder => 
{ 
    // TODO: Add api specific middleware. 

    app.UseMvc(routes => // should be builder.UseMvc(routes 
    { 
     routes.MapRoute(
      name: "apiDefault", 
      template: "api/{controller=Values}/{action=Index}"); 
    }); 
});