Blazor Server + WebApi

Blazor Server App 啟用 WebApi 並開啟 XSS CORS。有時 Blazor Server 也有對外開放 Web API 的需求,故需額外啟用 Web API 功能與允許跨源(EnableCors)要求。

參考文件

關鍵程式碼節錄

Startup.cs
public class Startup
{
	...

	public void ConfigureServices(IServiceCollection services)
	{
		// 設定CORS Policy
		services.AddCors(options =>
		{
			// 設定預設CORS Policy
			options.AddDefaultPolicy(builder =>
				builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().Build());

			// 設定其他的CORS Policy 並命名識別。
			options.AddPolicy("CorsPolicy", builder =>
				builder.WithOrigins("http://example.com", "http://www.contoso.com")
					.AllowAnyHeader()
					.AllowAnyMethod());
		});


		// for enable WebApi ※這裡的效果等同只開放WebApi的功能而已
		services.AddMvc(setupAction: options => options.EnableEndpointRouting = false)
			.SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);

		services.AddRazorPages();
		services.AddServerSideBlazor();
		...
	}

	// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
	public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
	{
		...

		app.UseRouting();

		app.UseMvcWithDefaultRoute(); // for enable WebApi

		app.UseEndpoints(endpoints =>
		{
			endpoints.MapBlazorHub();
			endpoints.MapFallbackToPage("/_Host");
		});
	}
}

在 Web API 使用EnableCorsAttribute

YourWebApiController.cs
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;

namespace YourBlazorServer.Pages
{
    [Route("api/[controller]")]
    [ApiController]
    public class YourWebApiController : ControllerBase
    {
	readonly ILogger<YourWebApiController> logger;
	readonly SubscriptionStoreService subsStore;
		
        public YourWebApiController(ILogger<YourWebApiController> _logger)
        {
	    logger = _logger;
            subsStore = _subsStore;
        }

        // POST api/YourWebApi
        //[EnableCors("CorsPolicy")] // 使用指定的CORS Policy
        [EnableCors] // 使用預設CORS Policy
        [HttpPost]
        public ErrMsg Post(UserSubscriptionInfo userSubs)
        {
            try
            {
                subsStore.UpdateSubscription(userSubs);
                return new ErrMsg { errType = "SUCCESS" };
            }
            catch (Exception ex)
            {
                return new ErrMsg { errType = "EXCEPTION", errMsg = ex.Message };
            }
        }
    }
}

Last updated