繁体   English   中英

如何将slug添加到asp.net核心网站中的所有Link生成?

[英]How to add the slug to all Link generation in an asp.net core website?

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

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

如果浏览器直接访问该URL或甚至是别名(如www.mysite.com),这都没问题。

但我希望o能够灵活地在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的实例。

有没有办法在不创建自定义帮助程序的情况下更改它(因为在某些区域会丢失并且几乎不可能找到被滥用的帮助程序)

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

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

Startup类中,您需要 AddMvc 之后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元数据包,那么您应该已经引用了它。

这应该可以帮助您解决问题。

您是否可以通过字符串连接强制一些灵活性进入您的解决方案,如下所示:

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

等等...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM