首页 > 解决方案 > 如何将标签 img src 从外部商店 ASP net Core 2 转换为 url?

问题描述

我的项目中有很多页面,带有图像的视图。目前,在项目中,图像是从项目的本地文件夹中获取的。例子:

<img src="images/banner.jpeg" class="img-responsive" alt="banner">

路径是相对的。另外,有静态文件的文件夹不是wwwroot,而是不同的:

StaticFileOptions options = new StaticFileOptions();
options.FileProvider = new PhysicalFileProvider(staticFolder.Value);
options.RequestPath = new PathString(staticFolder.Key);
options.OnPrepareResponse = ctx =>
{
    ctx.Context.Response.Headers[HeaderNames.CacheControl] =
        "public,max-age=" + websiteSettings.ImageCacheControlDurationInSeconds;
};

app.UseStaticFiles(options);

我需要让图片看绝对路径,例如,https://cdntest.azureedge.net/content/products/images/banner.jpeg

在整个项目中将 src 更改为 img 不是一种选择。

也许我可以以某种方式使用中间件拦截它并更改路径或通过 url 重写来完成。

我找到了 url rewrite 的示例,但它不起作用:

        <outboundRules>
            <rule name="cdn" preCondition="html">
                <match filterByTags="Img" pattern="^images/(.*)" />
                <action type="Rewrite" value="https://cdntest.azureedge.net/content/products/images/banner.jpeg" />
            </rule>
            <preConditions>
                <preCondition name="html">
                    <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
                </preCondition>
            </preConditions>
        </outboundRules>

如果有任何帮助,我将不胜感激。

标签: c#asp.net-coreurl-rewritingmiddleware

解决方案


我在回答@TimothyMacharia Code 时找到了解决问题的方法:

public class RedirectImageRule : IRule
{
    private readonly string _extension;
    private readonly WebsiteSettingsBase _websiteSettings;

    public RedirectImageRule(string extension,
        IConfiguration configuration)
    {
        if (string.IsNullOrEmpty(extension))
        {
            throw new ArgumentException(nameof(extension));
        }

        if (!Regex.IsMatch(extension, @"^\.(png|jpg|gif|svg)$"))
        {
            throw new ArgumentException("Invalid extension", nameof(extension));
        }

        _extension = extension;
        _websiteSettings = configuration.GetSection("WebsiteSettings").Get<WebsiteSettingsBase>();
    }

    public void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;

        if (request.Path.Value.EndsWith(_extension, StringComparison.OrdinalIgnoreCase))
        {
            var response = context.HttpContext.Response;
            response.StatusCode = (int)HttpStatusCode.MovedPermanently;
            context.Result = RuleResult.EndResponse;

           if (request.Path.Value.StartsWith("/images"))
            {
                response.Headers[HeaderNames.Location] =
                    CreateUri(request.Path.Value);
            }
            else
            {
                response.Headers[HeaderNames.Location] =
                    CreateUri(request.Path.Value, isAddFolder: true);
            }
        }
    }

    private string CreateUri(string path, bool isAddFolder = false)
    {
        var baseUri = new Uri(_websiteSettings.CdnStoragePath);

        if (!isAddFolder)
        {
            return new Uri(baseUri, path).AbsoluteUri;
        }

        if (path.StartsWith("/"))
        {
            return $"{_websiteSettings.CdnStorageContentFolderPath}{path}";
        }

        return $"{_websiteSettings.CdnStorageContentFolderPath}/{path}";
    }
}

并使用它:

var options = new RewriteOptions();

options.AddIISUrlRewrite(env.ContentRootFileProvider, "IISUrlRewrite.xml")
.Add(new RedirectImageRule(".png", configuration))
.Add(new RedirectImageRule(".jpg", configuration))
.Add(new RedirectImageRule(".svg", configuration));

推荐阅读