簡體   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