Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API Controllers routes isn't working on Blazor Server Side #9437

Closed
baartho opened this issue Apr 16, 2019 · 8 comments
Closed

API Controllers routes isn't working on Blazor Server Side #9437

baartho opened this issue Apr 16, 2019 · 8 comments
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates

Comments

@baartho
Copy link

baartho commented Apr 16, 2019

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.

@Eilon Eilon added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Apr 16, 2019
@iamgmd
Copy link

iamgmd commented Apr 17, 2019

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.

@baartho
Copy link
Author

baartho commented Apr 17, 2019

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;

@iamgmd
Copy link

iamgmd commented Apr 17, 2019

@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");
            });
        }
    }
}

@iamgmd
Copy link

iamgmd commented Apr 17, 2019

@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");
            });
        }
    }
}

@iamgmd
Copy link

iamgmd commented Apr 17, 2019 via email

@baartho
Copy link
Author

baartho commented Apr 18, 2019

@iamgmd thank you very much!!

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

@baartho baartho closed this as completed Apr 18, 2019
@Zenexer
Copy link
Contributor

Zenexer commented Apr 28, 2019

@natrist
Copy link

natrist commented Oct 13, 2019

@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.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates
Projects
None yet
Development

No branches or pull requests

5 participants