Как добавить слаг ко всем ссылкам на основной сайт asp.net? - PullRequest
0 голосов
/ 17 февраля 2019

Мне нужно иметь возможность контролировать ссылки, сгенерированные моим вызовом Url.Content("~"), чтобы иметь возможность принять Slug в начале ссылки.В основном, URL-адрес хостинга будет находиться за балансировщиком нагрузки и может находиться на корневом уровне или за более дружественным URL-адресом ...

Например: сайт настроен для работы под http://localhost:5001,, поэтомуUrl.Content("~/scripts/site.js") сгенерирует "/scripts/site.js"

Это нормально, если браузер напрямую переходит по этому URL-адресу или даже по псевдониму, например www.mysite.com.

Но я хочу, чтобы у меня была возможность разместить сайт под www.mysite.com/Slug (думаю, сертификаты и тому подобное) ...

Теперь моя сгенерированная ссылка идетна www.mysite.com/scripts.site.js, который разрешается до 404.

В идеале, слаг может быть настроен в пользовательском IUrlHelper или даже в пользовательском LinkGenerator, но я не могу показатьсяввести их и перезаписать текущие.

Я пробовал:

services.AddScoped<IUrlHelper>(x =>
            {
                var actionContext = x.GetService<IActionContextAccessor>().ActionContext;
                return new MyCustomUrlHelper(actionContext);
            });

, но мне не удалось это сделать.Когда я попытался отладить, я заметил, что если вы вызываете ту же команду в контроллере, вы получаете экземпляр Microsoft.AspNetCore.Mvc.Routing.EndpointRoutingUrlHelper.

Есть ли способ изменить это без создания пользовательского помощника (потому что в некоторых областях он будет пропущен и почти не поможет отыскать неправильно использованного помощника)

Ответы [ 3 ]

0 голосов
/ 21 февраля 2019

Можете ли вы просто использовать грубую силу в своем решении с помощью конкатенации строк, например:

public string SlugUrl(string slug, string url, bool tilde = false)
{
    if (tilde) then
    {
        return Url.Content("~" + slug + url);
    }
    else
    {
        return Url.Content(slug + url);
    }
}

[...]

string slug1 = "www.mysite.com";
string slug2 = "www.mysite.com/Slug";
string trailUrl = "/scripts/site.js";
string result1 = SomeClass.SlugUrl(slug1, trailUrl);
string result2 = SomeClass.SlugUrl(slug2, trailUrl);
string result3 = SomeClass.SlugUrl(slug1, trailUrl, true);
string result4 = SomeClass.SlugUrl(slug2, trailUrl, true);

и т. Д.

0 голосов
/ 21 февраля 2019

Связывание IUrlHelper напрямую не имеет никакого эффекта, поскольку MVC внутренне разрешает экземпляр, используя фабрику.Чтобы получить экземпляр собственного настраиваемого помощника по URL в ваших контроллерах и представлениях бритвы, вам необходимо предоставить настраиваемую реализацию IUrlHelperFactory в вашем классе запуска.

Следующие фрагменты кода позволяют вам украсить исходный URL-помощник своими собственными функциями:

В вашем классе Startup вам нужно добавить пользовательскую реализацию для IUrlHelperFactory с одноэлементной областью действия после AddMvc:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    services.AddSingleton<IUrlHelperFactory, CustomUrlHelperFactory>();
}

И пользовательская реализация может выглядеть так:

public class CustomUrlHelper : IUrlHelper
{
    private IUrlHelper _originalUrlHelper;

    public ActionContext ActionContext { get; private set; }

    public CustomUrlHelper(ActionContext actionContext, IUrlHelper originalUrlHelper)
    {
        this.ActionContext = actionContext;
        this._originalUrlHelper = originalUrlHelper;
    }

    public string Action(UrlActionContext urlActionContext)
    {
        return _originalUrlHelper.Action(urlActionContext);
    }

    public string Content(string contentPath)
    {
        return _originalUrlHelper.Content(contentPath);
    }

    public bool IsLocalUrl(string url)
    {
        return _originalUrlHelper.IsLocalUrl(url);
    }

    public string Link(string routeName, object values)
    {
        return _originalUrlHelper.Link(routeName, values);
    }

    public string RouteUrl(UrlRouteContext routeContext)
    {
        return _originalUrlHelper.RouteUrl(routeContext);
    }
}

public class CustomUrlHelperFactory : IUrlHelperFactory
{
    public IUrlHelper GetUrlHelper(ActionContext context)
    {
        var originalUrlHelperFactory = new UrlHelperFactory();
        var originalUrlHelper = originalUrlHelperFactory.GetUrlHelper(context);
        return new CustomUrlHelper(context, originalUrlHelper);
    }
}
0 голосов
/ 21 февраля 2019

IUrlHelper не может быть введен по умолчанию.

Вам придется немного изменить свой код startup.cs, как объяснено в этом блоге .

Сначала вам нужно зарегистрировать IActionContextAccessor.

Затем с помощью UrlHelperFactory вы можете внедрить свою пользовательскую реализацию, как показано ниже:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddScoped<IUrlHelper>(x => {
    var actionContext = x.GetRequiredService<IActionContextAccessor>().ActionContext;
    var factory = x.GetRequiredService<IUrlHelperFactory>();
    return factory.GetUrlHelper(actionContext);
});

Оба IActionContextAccessor и IUrlHelperFactory живут в пакете Microsoft.AspNetCore.Mvc.Core.

Если вы используете метапакет Microsoft.AspNetCore.All, на него уже должна быть ссылка.

Это должно помочь вам решить вашу проблему.

...