Пустой href после обновления до ядра 2.2 asp.net - PullRequest
0 голосов
/ 07 декабря 2018

Мы создали веб-сайт ASP.NET Core 2.1, на котором URL-адреса, такие как www.example.org/uk и www.example.org/de, определяют, какие resx файлы и контент следует отображать.После обновления до ASP.NET Core 2.2 страницы загружаются, но все сгенерированные ссылки приводят к пустым / пустым ссылкам.

Например, такая ссылка:

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

в 2.2 приведет к созданию пустой ссылкивот так:

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

Но в 2.1 мы получаем правильный href:

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

Мы используем Карта ограничений для управления языковой функцией на основе URL -вот код:

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;
    }
}

Я сузилсяпроблема, но не могу найти способ ее решить;В основном в 2.2.некоторые параметры не установлены в вышеуказанном методе IRouteConstraint Match, например,

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

В 2.1

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

Единственное отличие, которое я сделал между 2.1 и 2.2, заключается в том, что я изменил

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

к следующему (из-за https://github.com/aspnet/AspNetCore/issues/4206)

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

Есть идеи?

Обновление Согласно https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-2.2#parameter-transformer-reference ASP.NET Core 2.2 использует EndpointRouting, тогда как 2.1 использует базовую логику IRouter. Это объясняет мою проблему. Теперь мой вопрос: как будет выглядеть код для 2.2 для использования нового EndpointRouting?

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018
// Use the routing logic of ASP.NET Core 2.1 or earlier:
services.AddMvc(options => options.EnableEndpointRouting = false)
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
0 голосов
/ 07 декабря 2018

Отличия от более ранних версий маршрутизации объясняет, что здесь происходит (выделено мое):

Генерация ссылки алгоритм аннулирования окружающего значения ведет себя по-разному, когдаиспользуется с маршрутизацией конечной точки.

Недопустимое значение окружающего значения - это алгоритм, который решает, какие значения маршрута из текущего выполняющегося запроса (значения окружения) можно использовать в операциях генерации канала.Обычная маршрутизация всегда делает недействительными дополнительные значения маршрута при связывании с другим действием.Маршрутизация атрибутов не имела такого поведения до выпуска ASP.NET Core 2.2.В более ранних версиях ASP.NET Core ссылки на другое действие, использующие те же имена параметров маршрута, приводили к ошибкам генерации ссылок.В ASP.NET Core 2.2 или более поздней версии обе формы маршрутизации делают недействительными значения при связывании с другим действием.

...

Окружающие значения не используются повторно, когда связанный объект назначениядругое действие или страница.

В вашем примере lang - это значение окружения , поэтому оно не используется повторно при переходе от Home/Index к Home/About (другое действие).Без значения, указанного для lang, соответствующее действие не выполняется, поэтому генерируется пустая ссылка.Это также описано в документации как разница между маршрутизацией конечной точки:

Однако при маршрутизации конечной точки создается пустая строка, если действия не существует. Концептуально маршрутизация конечной точки неНе предполагайте, что конечная точка существует, если действие не существует.

Если вы хотите продолжать использовать маршрутизацию конечной точки, похоже, вам нужно будет передать значение langс вашего контроллера на ваш взгляд, а затем установите его явно.Вот пример:

public class HomeController : Controller
{
    public IActionResult Index(string lang)
    {
        ViewData["lang"] = lang; // Using ViewData just for demonstration purposes.
        return View();
    }
}
<a asp-controller="Home" asp-action="Contact"
    asp-route-lang="@ViewData["lang"]">@Res.ContactUs</a>

Вы можете сделать это немного менее повторяющимся, например, с помощью фильтра действий, но концепции остаются теми же.Я не вижу, что есть другой способ справиться с этим (например, возможность пометить определенное значение как окружающее), но, возможно, кто-то еще сможет вмешаться в это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...