繁体   English   中英

URL重写中间件ASP.Net Core 2.0

[英]URL Rewriting Middleware ASP.Net Core 2.0

我无法正确写入URL重写中间件。 我认为正则表达式是正确的。 我第一次使用这个功能,也许我不明白。

示例网址:

http://localhost:55830/shop/alefajniealsdnoqwwdnanxc!@#lxncqihen41j2ln4nkzcbjnzxncas?valueId=116
http://localhost:55830/shop/whatever?valueId=116
http://localhost:55830/shop/toquestionmark?valueId=116

正则表达式:

\/shop\/([^\/?]*)(?=[^\/]*$)

启动,配置:

var rewrite = new RewriteOptions().AddRewrite(
        @"\/shop\/([^\/?]*)(?=[^\/]*$)",
        "/shop/$1",
        true
    );
app.UseRewriter(rewrite);

也许与其他方法有关的订单有问题吗?

控制器:

[Route(RouteUrl.Listing + RouteUrl.Slash + "{" + ActionFilter.Value + "?}", Name = RouteUrl.Name.ShopBase)]
public ActionResult Index(string value, int valueId)
{
    return View();
}

例如,当我重定向到:

HTTP://本地主机:55830 /店/鞋VALUEID = 116

我想像这样显示网址:

HTTP://本地主机:55830 /店/鞋

基于这篇文章: https//www.softfluent.com/blog/dev/Page-redirection-and-URL-Rewriting-with-ASP-NET-Core

在开发Web应用程序时,通常需要添加一些重定向规则。 最常见的重定向规则是:从“http”重定向到“https”,添加“www”或将网站移动到另一个域。 URL重写通常用于提供用户友好的URL。

我想解释重定向和重写之间的区别。 重定向将HTTP 301或302发送到客户端,告诉客户端它应该使用另一个URL访问该页面。 浏览器将更新地址栏中可见的URL,并使用新URL发出新请求。 另一方面,重写发生在服务器上,是一个URL到另一个URL的转换。 服务器将使用新URL来处理请求。 客户端不知道服务器已重写URL。

使用IIS,您可以使用web.config文件来定义重定向和重写规则或使用RewritePath

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Redirect to https">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="Off" />
            <add input="{REQUEST_METHOD}" pattern="^get$|^head$" />
            <add input="{HTTP_HOST}" negate="true" pattern="localhost" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

但是,这不再适用于ASP.NET Core。 相反,您可以使用新的NuGet包:Microsoft.AspNetCore.Rewrite(GitHub)。 这个包很容易使用。 打开startup.cs文件并编辑Configure方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ISiteProvider siteProvider)
{           
    app.UseRewriter(new RewriteOptions()
        .AddRedirectToHttps()
        .AddRedirect(@"^section1/(.*)", "new/$1", (int)HttpStatusCode.Redirect)
        .AddRedirect(@"^section2/(\\d+)/(.*)", "new/$1/$2", (int)HttpStatusCode.MovedPermanently)
        .AddRewrite("^feed$", "/?format=rss", skipRemainingRules: false));

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

规则基于正则表达式和替换。 正则表达式在HttpContext.Request.Path上进行评估,该函数不包括域,也不包括协议。 这意味着您无法使用此方法重定向到其他域或添加“www”,但不要担心,我会告诉您如何执行此操作!

Microsoft已决定帮助您使用此新软件包。 实际上,如果您已经有web.config文件甚至.htaccess文件(.net核心是跨平台),您可以直接导入它们:

app.UseRewriter(new RewriteOptions()
    .AddIISUrlRewrite(env.ContentRootFileProvider, "web.config")
    .AddApacheModRewrite(env.ContentRootFileProvider, ".htaccess"));

如果您有使用正则表达式无法表达的复杂规则,则可以编写自己的规则。 规则是实现Microsoft.AspNetCore.Rewrite.IRule的类:

// app.UseRewriter(new RewriteOptions().Add(new RedirectWwwRule()));

public class RedirectWwwRule : Microsoft.AspNetCore.Rewrite.IRule
{
    public int StatusCode { get; } = (int)HttpStatusCode.MovedPermanently;
    public bool ExcludeLocalhost { get; set; } = true;

    public void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;
        var host = request.Host;
        if (host.Host.StartsWith("www", StringComparison.OrdinalIgnoreCase))
        {
            context.Result = RuleResult.ContinueRules;
            return;
        }

        if (ExcludeLocalhost && string.Equals(host.Host, "localhost", StringComparison.OrdinalIgnoreCase))
        {
            context.Result = RuleResult.ContinueRules;
            return;
        }

        string newPath = request.Scheme + "://www." + host.Value + request.PathBase + request.Path + request.QueryString;

        var response = context.HttpContext.Response;
        response.StatusCode = StatusCode;
        response.Headers[HeaderNames.Location] = newPath;
        context.Result = RuleResult.EndResponse; // Do not continue processing the request        
    }
}

解决我的问题比看起来简单。 我承认我之前不知道我可以将POST与GET结合起来:

查看: - 强类型部分视图@model MainNavigationArchon

<form asp-controller="@Model.Controller" asp-action="@RouteUrl.Index" asp-route-value="@AureliaCMS.Infrastructure.Helpers.StringHelper.RemoveDiacritics(Model.Value.ToLower())" method="post">
    <input type="hidden" asp-for="@Model.ValueId" />
    <button class="btn btn-link">@Model.Value</button>
</form>

控制器:

[Route("shop" + RouteUrl.Slash + "{value}", Name = RouteUrl.Name.ShopBase)]
public ActionResult Index(int valueId)
{
    return View();
}

网址包含:

从路线属性shop

来自asp-route-value shoes

?valueId=116通过hidden字段发送asp-for="@Model.ValueId"

结果:

我发送的内容如http://localhost:55830/shop/shoes?valueId=116并显示http://localhost:55830/shop/shoes

暂无
暂无

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

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