如何在ASP.NET Core网站中将SLUG添加到所有链接生成中



我需要能够控制我的 Url.Content("~")呼叫生成的链接,以便能够在链接开始时接受sl。基本上,托管URL将在负载平衡器后面,可能位于根级别或友好的URL后面...

例如:该站点配置为在http://localhost:5001下运行,因此Url.Content("~/scripts/site.js")将生成"/scripts/site.js"

,如果浏览器直接进入该URL甚至是www.mysite.com之类的别名,这很好。

,但我希望O可以灵活地在www.mysite.com/slug(think cent等)下托管该网站...

现在我生成的链接访问www.mysite.com/scripts.site.js,解决了404。

理想情况下,可以在自定义IUrlHelper甚至自定义LinkGenerator中配置SLUG,但我似乎无法注入这些sl,并覆盖当前的sl。

我尝试过:

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

,但无法注入。当我尝试调试时,我注意到,如果您在控制器中调用同一命令,则将获得Microsoft.AspNetCore.Mvc.Routing.EndpointRoutingUrlHelper的实例。

是否可以在不创建自定义助手的情况下进行更改(因为在某些方面会错过这一点,并且会使调试几乎无法找到滥用的助手)

绑定IUrlHelper直接没有效果,因为MVC内部使用工厂解决了实例。要在控制器和剃须刀视图中获取自己的自定义URL助手的实例,您需要在启动类中提供IUrlHelperFactory的自定义实现。

以下代码段允许您使用自己的功能装饰原始URL助手:

在您的Startup类中,您需要在 AddMvc之后使用singleton scope 添加IUrlHelperFactory的自定义实现:

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

默认情况下不可注入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);
});

IActionContextAccessorIUrlHelperFactory都活在Microsoft.AspNetCore.Mvc.Core软件包中。

如果您使用的是 Microsoft.AspNetCore.All metapackage,则应该已经引用了此。

这应该帮助您解决问题。

您不仅可以用像这样的字符串串联施加弹性的灵活性:

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

等...

最新更新