Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Routing to an ApiController in a razor page app?

I created a ASP.NET Core Razor page app (asp.net version 2.1.1). It works just fine with the normal Pages but I also want an ApiController as in this tutorial: https://learn.microsoft.com/en-us/aspnet/core/tutorials/web-api-vsc?view=aspnetcore-2.1

However, when I create my controller just as in the example above, I get a 404 page whenever I try to reach it.

Is there something I am missing from the startup class?

public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddDbContext<DomainDbContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

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

            app.UseMvc();
        }

And my apicontroller class:

    [Route("api/[controller]")]
    [ApiController]
    class DomainController : ControllerBase 
    {
        private readonly DomainDbContext _context;

        public DomainController (DomainDbContext context) 
        {
            _context = context;
        }

        [HttpGet]
        public ActionResult<List<Domain>> GetAll()
        {
            return new List<Domain> {new Domain() {Name ="Hello", Tld = ".se", Expiration = DateTime.UtcNow.AddDays(35)}};
        }
}

Everything looks like the guides as far as I can see, but obviously something is not correct since I get 404 for all pages. Even if I create a new method it doesn't really quite work as intended and is unreachable.

The main path I've tried is /api/domain.

Thanks for your help in advance!

like image 389
Ms01 Avatar asked Jun 25 '18 20:06

Ms01


People also ask

How do I add an API to my Razor page?

Adding the Web API In order to add a Web API Controller you will need to Right Click the Project in the Solution Explorer and click on Add and then New Item. Now from the Add New Item window, choose the API Controller – Empty option as shown below. Then give it a suitable name and click Add.

How do I specify a route in Web API?

The default route template for Web API is "api/{controller}/{id}". In this template, "api" is a literal path segment, and {controller} and {id} are placeholder variables. When the Web API framework receives an HTTP request, it tries to match the URI against one of the route templates in the routing table.

What does the ApiController attribute do?

The [ApiController] attribute applies inference rules for the default data sources of action parameters. These rules save you from having to identify binding sources manually by applying attributes to the action parameters.

What is the difference between controller and ApiController?

They work similarly in Web API, but controllers in Web API derive from the ApiController class instead of Controller class. The first major difference you will notice is that actions on Web API controllers do not return views, they return data. ApiControllers are specialized in returning data.


2 Answers

You need to have a public controller class.

So instead of:

[Route("api/[controller]")]
[ApiController]
class DomainController : ControllerBase
{
    [...]
} 

You should have this:

[Route("api/[controller]")]
[ApiController]
public class DomainController : ControllerBase // <-- add a public keyword
{
    [...]
} 
like image 197
CodeNotFound Avatar answered Oct 22 '22 10:10

CodeNotFound


Just add endpoints.MapControllers() to the UseEndpoints options:

app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
                endpoints.MapControllers();
            });
like image 24
Nhan Phan Avatar answered Oct 22 '22 08:10

Nhan Phan