Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
В прошлых темах было рассмотрено использование CORS в простом проекте ASP.NET Core по типу Empty. Но в ASP.NET Core MVC есть некоторые дополнительные возможности, поэтому рассмотрим их отдельно.
В MVC можно настроить CORS глобально для всего приложения, отдельно для каждого контроллера или даже отдельно для каждого действия контроллера.
Само подключение CORS осуществляется также, как и в проекте Empty с помощью метода AddCors. В частности, определим в проекте MVC следующий класс Startup:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace CorsMvcApp { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddCors(options => { options.AddPolicy("AllowAllOrigin", builder => builder.AllowAnyOrigin()); }); } public void Configure(IApplicationBuilder app) { app.UseDeveloperExceptionPage(); app.UseStaticFiles(); app.UseRouting(); app.UseCors(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } } }
Здесь определяется политика "AllowAllOrigin", при которой приложение будут принимать запросы от всех адресов.
Для применения CORS к методу контроллера используется атрибут [EnableCors]:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Cors; public class HomeController : Controller { [EnableCors("AllowAllOrigin")] public IActionResult Index() { return Content("Hello from ASP.NET Core MVC"); } public IActionResult Test() { return Content("Test from ASP.NET Core MVC"); } }
Атрибуту EnableCors передается название политики, которая была определена в классе Startup через вызов services.AddCors, то есть AllowAllOrigin. И теперь сторонние приложения могут обращаться к этому методу, естественно, если их запросы соответствуют политике AllowAllOrigin.
В отличие от метода Index другой метод контроллера - метод Test атрибута EnableCors не имеет, соответственно мы не сможем обратиться к методу Test из других приложений. То есть с помощью данного атрибута мы можем детально указать, к каким имеенно ресурсам приложения мы хотим предоставить доступ
Чтобы распространить действие CORS на весь контроллер, к нему также применяется атрибут EnableCors, в который передается название политики:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Cors; namespace CorsMvcApp.Controllers { [EnableCors("AllowAllOrigin")] public class HomeController : Controller { public IActionResult Index() { return Content("Hello from ASP.NET Core MVC"); } public IActionResult Test() { return Content("Test from ASP.NET Core MVC"); } } }
Теперь политика AllowAllOrigin применяется ко всем методам контроллера.
При использовании метода app.UseEndpoints()
для определения маршрутов мы можем указать настройки CORS для отдельных маршрутов с помощью метода RequireCors():
using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace CorsMvcApp { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddCors(options => { options.AddPolicy("AllowAllOrigin", builder => builder.AllowAnyOrigin()); }); } public void Configure(IApplicationBuilder app) { app.UseDeveloperExceptionPage(); app.UseStaticFiles(); app.UseRouting(); app.UseCors(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}") .RequireCors(options => options.AllowAnyOrigin()); // или передать название политики endpoints.MapControllerRoute( name: "api", pattern: "api/{controller=Home}/{action=Index}/{id?}") .RequireCors("AllowAllOrigin"); }); } } }
Чтобы распространить политику Cors на все приложение со всеми его контроллерами, достаточно в метод UseCors передать соответствующие настройки:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Cors; namespace CorsMvcApp { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddCors(); } public void Configure(IApplicationBuilder app) { app.UseStaticFiles(); app.UseRouting(); // Установка CORS для всех ресурсов app.UseCors(options => options.AllowAnyOrigin()); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } } }
В этом случае все методs всех контроллеров будет иметь возможность принимать запросы от всех других приложений. И нам не надо устанавливать для методов и контроллеров атрибут EnableCors. Если мы вдруг захотим исключить какой-то метод или контроллер из применения CORS, то к этому методу или контроллеру следует применить атрибут [DisableCors]:
public class HomeController : Controller { [DisableCors] public IActionResult Index() { return Content("Hello from ASP.NET Core MVC"); } }
Также если мы захотим применить к какому-то методу или контроллеру какую-ту специфическую политику CORS, то опять мы можем применять атрибут EnableCors. При этом настройки для метода контроллера имеют больший приоритет чем настройки для контроллера. А настройки для контроллера имеют больший приоритет, чем глобальные настройки.