Aspnetcore: API Controllers routes isn't working on Blazor Server Side

Created on 16 Apr 2019  路  8Comments  路  Source: dotnet/aspnetcore

Describe the bug

Defining routes / endpoints for API Controllers on a Blazor Server-Side project isn`t working. I had it working on previous Blazor versions but can't it to work on 0.9.0-preview3-19154-02.

To Reproduce

startup.cs code:

        public void ConfigureServices(IServiceCollection services)
        {
   services.AddMvc().AddNewtonsoftJson().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);
        services.AddRazorPages();
        services.AddServerSideBlazor();`

        //services.AddAuthentication(o => o.DefaultAuthenticateScheme = AzureADB2CDefaults.CookieScheme)
        //    .AddAzureADB2C(options => Configuration.Bind("AzureADB2C", options))
        //    .OnLogin(principal =>
        //    {
        //        services.BuildServiceProvider().GetRequiredService<LoginCommand>()
        //            .Execute(principal, principal.AzureID(), principal.Email(), principal.DisplayName());
        //    });

        services.AddBlazorModal();
        AddRepositories(services);
        AddCommands(services);
        AddHttpClient(services);
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        //app.UseAuthentication();
        //app.UseMvcWithDefaultRoute();

        app.UseRouting();

        //app.UseMvc();

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

            endpoints.MapControllers();
            //endpoints.MapRazorPages();

            endpoints.MapBlazorHub();
            endpoints.MapFallbackToPage("/_Host");
        });
    }

API Controller:

        [Produces("application/json")]
        [Route("api/[controller]")]
        [ApiController]
        public class DataController : Controller
        {
        [HttpPost]
        [Route("UploadPhoto")]
        public async Task<string> UploadFile(UploadFileParameters file)
        {
              return null;
        }

    [HttpGet]
    [Route("Test")]
    public string Test()
    {
        return "abc";
    }
}`

Expected behavior

Posting to https://localhost:xxxxx/api/Data/UploadPhoto
Or getting from: https://localhost:xxxxx/api/Data/Test should work.

area-mvc

Most helpful comment

@baartho I installed VS2019 16.1.0 Preview 1.0 along with the nightly build of the dotnet SDK 3.0.100-preview4-011223, Created a BlazorComponent solution and changed the Startup.cs to be as below and I was able to call a MVC controller without problems. I will assume that this will work for an API controller as well. Hope this helps.

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using WebApplication1.Data;

namespace WebApplication1
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options => options.EnableEndpointRouting = false)
                .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddSingleton<WeatherForecastService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseStaticFiles();

            app.UseRouting();

            app.UseMvcWithDefaultRoute();

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

All 8 comments

I had a similar problem when I tried to call a Razor Page from a Blazor Component using Server side Blazor. What worked for me was to add/re-add 'app.UserMvcDefaultRoute();' in the Configure method, Like you, I couldn't get it working with 'routes.MapControllers();' which I have seen being used on other examples like below:

            app.UseMvcWithDefaultRoute();

            app.UseRouting(routes =>
            {
                //routes.MapControllers();
                routes.MapRazorPages();
                routes.MapComponentHub<App>("app");
            });

Once I added 'app.UseMvcWithDefaultRoute();', my Blazor component with a NavLink was able to call href="home" which in turn hit my HomeController's Index.cshtml view.

Thanks for taking the time @iamgmd!!

If I re-add app.UserMvcDefaultRoute(); I get the following error:

System.InvalidOperationException: 'Endpoint Routing does not support 'IApplicationBuilder.UseMvc(...)'. To use 'IApplicationBuilder.UseMvc' set 'MvcOptions.EnableEndpointRouting = false' inside 'ConfigureServices(...).'

This exception can be easily fixed by changing from:

services.AddMvc().AddNewtonsoftJson().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);

to:

services.AddMvc(x => x.EnableEndpointRouting = false).AddNewtonsoftJson().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);

But I'm still unable to POST/GET anything to my API Controller.

It is also worth noting that I can't use app.UseRouting(); with arguments. There are no overloads for app.UseRouting() as you can see on the screenshot.

No overload for method 'UseRouting' takes 1 arguments

New Bitmap Image

P.S #2: All the blazor pages are working fine. It is just the controller that isn't. I'm unable to make any calls to it.

This is my current using statements on the Startup class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using System.Net.Http;
using Microsoft.AspNetCore.Components;

@baartho I have tested calling an API controller using Preview 3 and don't seem to be having any issues after making the change. I am using a standard BlazorComponents project. Your Startup class seems to be a lot more advanced.

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using WebApplication1.Components;
using WebApplication1.Services;

namespace WebApplication1
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc()
                .AddNewtonsoftJson();

            services.AddRazorComponents();

            services.AddSingleton<WeatherForecastService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseMvcWithDefaultRoute();

            app.UseRouting(routes =>
            {
                //routes.MapControllers();
                routes.MapRazorPages();
                routes.MapComponentHub<App>("app");
            });
        }
    }
}

@baartho I installed VS2019 16.1.0 Preview 1.0 along with the nightly build of the dotnet SDK 3.0.100-preview4-011223, Created a BlazorComponent solution and changed the Startup.cs to be as below and I was able to call a MVC controller without problems. I will assume that this will work for an API controller as well. Hope this helps.

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using WebApplication1.Data;

namespace WebApplication1
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options => options.EnableEndpointRouting = false)
                .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddSingleton<WeatherForecastService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseStaticFiles();

            app.UseRouting();

            app.UseMvcWithDefaultRoute();

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

You can download the nightly build of dotnet from:

https://github.com/dotnet/core-sdk

From: baartho
Sent: 17 April 2019 17:34
To: aspnet/AspNetCore
Cc: Geoff Davis
Subject: Re: [aspnet/AspNetCore] API Controllers routes isn't working on Blazor Server Side (#9437)

I'm sorry but where did you download the SDK preview 4? I even looked for other branches of .NET Core on github but couldn't find.

https://github.com/dotnet/core/tree/master/release-notes

@iamgmd thank you very much!!

I was able to POST and GET from a API Controller just fine!

@iamgmd I managed to complete the first part of this tutorial (https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/adding-controller?view=aspnetcore-3.0&tabs=visual-studio) following your code example.

This problem is still present with the latest out-of-the-box Visual Studio 2019 setup as of today.
I'm not sure if it affects every project template, but I built mine with Blazor MVC and I had to add the lines from your comment for my controllers to work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FourLeafClover picture FourLeafClover  路  3Comments

UweKeim picture UweKeim  路  3Comments

farhadibehnam picture farhadibehnam  路  3Comments

mj1856 picture mj1856  路  3Comments

markrendle picture markrendle  路  3Comments