Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Empty href after upgrading to asp.net core 2.2

We have built an ASP.NET Core 2.1 website where URLs like www.example.org/uk and www.example.org/de determine what resx file and content to show. After upgrading to ASP.NET Core 2.2, pages load but all links generated produce blank/empty href's.

For example, a link this:

<a asp-controller="Home" asp-action="Contact">@Res.ContactUs</a>

will in 2.2 produce an empty href like so:

<a href="">Contact us</a>

But in 2.1 we get correct href:

<a href="/uk/contact">Contact us</a>

We are using a Constraint Map to manage the URL-based language feature - here is the code:

Startup.cs

// configure route options {lang}, e.g. /uk, /de, /es etc
services.Configure<RouteOptions>(options =>
{
    options.LowercaseUrls = true;
    options.AppendTrailingSlash = false;
    options.ConstraintMap.Add("lang", typeof(LanguageRouteConstraint));
 });

 ...

app.UseMvc(routes =>
{
    routes.MapRoute(
       name: "LocalizedDefault",
       template: "{lang:lang}/{controller=Home}/{action=Index}/{id?}");
}

LanguageRouteConstraint.cs

public class LanguageRouteConstraint : IRouteConstraint
{
    private readonly AppLanguages _languageSettings;

    public LanguageRouteConstraint(IHostingEnvironment hostingEnvironment)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(hostingEnvironment.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

        IConfigurationRoot configuration = builder.Build();

        _languageSettings = new AppLanguages();
        configuration.GetSection("AppLanguages").Bind(_languageSettings);
    }

    public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (!values.ContainsKey("lang"))
        {
            return false;
        }

        var lang = values["lang"].ToString();
        foreach (Language lang_in_app in _languageSettings.Dict.Values)
        {
            if (lang == lang_in_app.Icc)
            {
                return true;
            }
        }
        return false;
    }
}

I narrowed down the problem but can't find a way to solve it; Basically in 2.2. some parameters are not set in the above IRouteConstraint Match method, e.g.

httpContext = null
route = {Microsoft.AspNetCore.Routing.NullRouter)

In 2.1

 httpContext = {Microsoft.AspNetCore.Http.DefaultHttpContext}
 route = {{lang:lang}/{controller=Home}/{action=Index}/{id?}}

The only difference I made between 2.1 and 2.2 is that I changed

var builder = new ConfigurationBuilder()
   .SetBasePath(Directory.GetCurrentDirectory())
   .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

to the following (due to https://github.com/aspnet/AspNetCore/issues/4206)

 var builder = new ConfigurationBuilder()
    .SetBasePath(hostingEnvironment.ContentRootPath) // using IHostingEnvironment 
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

Any ideas?

Update According to https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-2.2#parameter-transformer-reference ASP.NET Core 2.2 uses EndpointRouting whereas 2.1 uses IRouter basic logic. That explains my problem. Now, my question would then what will code look like for 2.2 to use the new EndpointRouting?

like image 946
Sha Avatar asked Dec 07 '18 02:12

Sha


1 Answers

You need to explicitly pass the values from the route data:

@using Microsoft.AspNetCore.Routing;
<a ... asp-route-storeId="@this.Context.GetRouteValue("storeId")">Pay Button</a>
like image 164
Nicolas Dorier Avatar answered Oct 16 '22 01:10

Nicolas Dorier