asp.net .net核心,如何处理带有额外前导斜杠的路由

ovfsdjhp  于 2023-10-21  发布在  .NET
关注(0)|答案(4)|浏览(143)

我需要处理一个传入的请求,其形式为://ohif/study/1.1/series注意前面的exta斜杠
我的控制器签名是:

[Route("ohif/study/{studyUid}/series")]
[HttpGet]
public IActionResult GetStudy(string studyUid)

如果我将传入的请求修改为/ohif/study/1.1/series,则可以正常工作
但是,当我使用//ohif/study/1.1/series时,路由不会被命中
此外,我还尝试:[给药途径(“/ohif/study/{studyUid}/series”)]和[给药途径(“//ohif/study/{studyUid}/series”)]
两个都失败了。不幸的是,我无法更改传入的请求,因为它来自外部应用程序。这条路线有什么诀窍吗?我在用.NET Core 3.0。

**更新注意:**我激活了日志记录,我看到asp.net核心正在分析路由,我收到消息:未找到记录器Microsoft.AspNetCore.Routing. EndpointallingMiddleware的请求路径“//ohif/study/1.1/series”的候选项

mwkjh3gx

mwkjh3gx1#

处理双斜杠的中间件怎么样?

app.Use((context, next) =>
            {
                if (context.Request.Path.Value.StartsWith("//"))
                {
                    context.Request.Path = new PathString(context.Request.Path.Value.Replace("//", "/"));
                }
                return next();
            });
s3fp2yjn

s3fp2yjn2#

在Web服务器级别重写URL,例如:对于IIS,您可以使用URL重写模块将//ohif/study/1.1/series自动重定向到/ohif/study/1.1/series。这不是你申请的工作

kmbjn2e3

kmbjn2e33#

我接受了Ravi的回答,并充实了一个中间件。中间件很好,因为它是封装的,易于测试,可以注入日志,更具可读性等。

app.UseDoubleSlashHandler();

代码和测试:

public class DoubleSlashMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<DoubleSlashMiddleware> _logger;

    public DoubleSlashMiddleware(RequestDelegate next, ILogger<DoubleSlashMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        _logger.LogInformation($"Invoking {nameof(DoubleSlashMiddleware)} on {context.Request.Path}");

        context.Request.Path = context.Request.Path.FixDoubleSlashes();

        // Call the next delegate/middleware in the pipeline.
        await _next(context);
    }
}

public static class DoubleSlashMiddlewareExtensions
{
    public static IApplicationBuilder UseDoubleSlashHandler(
        this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<DoubleSlashMiddleware>();
    }
}

[TestClass()]
public class DoubleSlashMiddlewareTests
{
    private DoubleSlashMiddleware _sut;
    private ILogger<DoubleSlashMiddleware> _logger;
    private bool _calledNextMiddlewareInPipeline;

    [TestInitialize()]
    public void TestInitialize()
    {
        _logger = Substitute.For<ILogger<DoubleSlashMiddleware>>();
        Task Next(HttpContext _)
        {
            _calledNextMiddlewareInPipeline = true;
            return Task.CompletedTask;
        }
        _sut = new DoubleSlashMiddleware(Next, _logger);
    }

    [TestMethod()]
    public async Task InvokeAsync()
    {
        // Arrange
        _calledNextMiddlewareInPipeline = false;

        // Act
        await _sut.InvokeAsync(new DefaultHttpContext());

        // Assert
        _logger.ReceivedWithAnyArgs(1).LogInformation(null);
        Assert.IsTrue(_calledNextMiddlewareInPipeline);
    }
}

执行替换的字符串方法:

public static class RoutingHelper
{
    public static PathString FixDoubleSlashes(this PathString path)
    {
        if (string.IsNullOrWhiteSpace(path.Value))
        {
            return path;
        }
        if (path.Value.Contains("//"))
        {
            return new PathString(path.Value.Replace("//", "/"));
        }
        return path;
    }
}

[TestClass()]
public class RoutingHelperTests
{
    [TestMethod()]
    [DataRow(null, null)]
    [DataRow("", "")]
    [DataRow("/connect/token", "/connect/token")]
    [DataRow("//connect/token", "/connect/token")]
    [DataRow("/connect//token", "/connect/token")]
    [DataRow("//connect//token", "/connect/token")]
    [DataRow("/connect///token", "/connect/token")]
    public void FixDoubleSlashes(string input, string expected)
    {
        // Arrange
        var path = new PathString(input);

        // Act
        var actual = path.FixDoubleSlashes();

        // Assert
        Assert.AreEqual(expected, actual.Value);
    }
}
swvgeqrz

swvgeqrz4#

This SO answer类似的问题描述了另一个更简单的解决方案:使用内置的URL Rewriting Middleware。例如,双斜杠可以通过以下方式替换为单斜杠:

var options = new RewriteOptions().AddRewrite(@"(.*)\/\/(.*)", "$1/$2", false);
app.UseRewriter(options);

相关问题