1

We have a combo of asp. net core odata as a back-end and Angular 6 as front-end. Both are developed separately, during each release Angular files are copied to wwwroot folder. We added these two methods to Startup.Configure to allow reading static files:

app.UseDefaultFiles();
app.UseStaticFiles();

index.html is getting hit however when Angular references it's js files in app-root element (e.g. runtime.js or polyfils.js) we get 500 error:

An unhandled exception occurred while processing the request. AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied: SomeNamespace.API.Controllers.ProductRequestController.GetProductRequest (SomeNamespace.API) SomeNamespace.API.Controllers.UserProfileController.GetUserProfile (SomeNamespace.API) SomeNamespace.API.Controllers.UserRoleCategoryController.GetUserRoleCategory (SomeNamespace.API) SomeNamespace.API.Controllers.WorkflowStepController.GetWorkflowStep (SomeNamespace.API) Microsoft.AspNetCore.Mvc.Internal.ActionSelector.SelectBestCandidate(RouteContext context, IReadOnlyList candidates)

It seems that even index.html gets hit other asp. net core has issues to serve other files. We also set correct (we think) base path in head:

<base href="~/">

It looks like that instead of simply serving the file app is actually trying to find proper controller (odata in this case). Does anyone have experience what is going on and what is wrong?

Diomos
  • 420
  • 5
  • 15

1 Answers1

1

OK, so after some additional googling and desperate playing around we I got working solution. So two things:

  1. Had to add additional routing along with odata one
  2. and this one is crazy! Two methods to support static files MUST be called before routing.

So in the end it looks like this:

app.UseDefaultFiles();
app.UseStaticFiles();

app.UseHttpsRedirection();
app.UseMvc(routeBuilder =>
   {
      routeBuilder.MapODataServiceRoute("ODataRoutes", "odata", modelBuilder.GetEdmModel(app.ApplicationServices));
      routeBuilder.MapRoute(
         name: "angular", 
         template: "{*url}",
         defaults: new {controller = "Home", action = "Index"});
    });

I don't think this is OK, at least it should be mentioned in documentation somewhere. It looks like in asp.net core it you can really influence behavior of the app with just wrong order of methods call. Maybe is this discussed somewhere?

Diomos
  • 420
  • 5
  • 15
  • `~` [has no special meaning](https://stackoverflow.com/questions/6252471/what-is-the-use-of-tilde-in-url) in the *browser*. `~/` is *not* a root-relative URL. In some very old servers `~` used to refer to a *user's* home directory. If you use your browser's developer tools I bet you'd see that the *browser* treats `~` as a simple prefix so all relative URLs end up refering to `www.mysite.com/ViewName/~/` and get routed to the view's controller – Panagiotis Kanavos Mar 27 '19 at 17:36
  • Hm, we used it because we read it as a recommendation on MS own site https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-2.2 but i guess you are right. – Diomos Mar 27 '19 at 17:40
  • That article uses `~` in the element URLs. The resulting addresses are relative to the base of the HTML page. `` though changed the *base* to something else. Use the Network view in your browser or a debugging proxy like Fiddler to check which URLs are actually requested by the browser – Panagiotis Kanavos Mar 27 '19 at 17:44