带有 URL 不友好字符的路径参数 [英] path parameters w/ URL unfriendly characters

查看:31
本文介绍了带有 URL 不友好字符的路径参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用服务堆栈 3.9.21.在 IIS 7.5 中托管应用程序.使用集成的 4.0.30319 ASP.NET 应用程序池.

出于说明目的,假设我有以下路径(由 DTO 和相应的请求处理程序支持):

/cars/{id}

有些汽车的 ID 中包含一些字符,我想这些字符必须经过 URL 编码 - 管道、| 就是其中之一.当我发送请求以获取例如 ID 为1|2"的汽车时,我得到了一个很好的旧 500,并带有以下堆栈跟踪:

[ArgumentException]:路径中有非法字符.在 System.IO.Path.CheckInvalidPathChars(String path)在 System.IO.Path.GetFileName(String path)在 ServiceStack.MiniProfiler.UI.MiniProfilerHandler.MatchesRequest(IHttpRequest request) 在 C:\src\ServiceStack\src\ServiceStack\MiniProfiler\UI\MiniProfilerHandler.cs:line 24在 ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory.GetHandler(HttpContext context, String requestType, String url, String pathTranslated) 在 C:\src\ServiceStack\src\ServiceStack\WebHost.Endpoints\ServiceStackHttpHandlerFactory.cs:line 153在 System.Web.HttpApplication.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()在 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

无论我是否对路径中的管道进行 URL 编码,我都会得到这个.我该如何解决这个问题?

更多详情

DTO

使用 ServiceStack.ServiceHost;命名空间 SSUEB{[Route("/cars/{id}", "GET")]公共类 ById{公共字符串 ID { 获取;放;}}}

端点

using System.Collections.Generic;使用 System.Net;使用 ServiceStack.Common.Web;使用 Stack = ServiceStack.ServiceInterface;命名空间 SSUEB{公共类汽车:Stack.Service{公共对象 Get(ById byId){return new HttpResult(new Dictionary {{"id", byId.Id}}, HttpStatusCode.OK);}}}

应用

使用 ServiceStack.WebHost.Endpoints;命名空间 SSUEB{公共类 SSUEB:AppHostBase{public SSUEB() : base("ServiceStack toy service", typeof(SSUEB).Assembly){}公共覆盖无效配置(Funq.Container容器){ServiceStack.Text.JsConfig.EmitCamelCaseNames = true;SetConfig(new EndpointHostConfig { DebugMode = true });}}}

请求

这个:

curl -v -X GET -H "Accept: application/json" http://localhost:80/dealership/cars/123%20456

获得预期的 200 响应:

{"id":"123 456"}

但是这个:

curl -v -X GET -H "Accept: application/json" http://localhost:80/dealership/cars/123%7C456

导致最初报告的问题.

IIS 请求日志 显示 %7C 被解码为管道,而 %20 被解码(在日志中至少是一个加号).后者导致 200(OK)响应,前者 - 500(内部服务器错误).

2012-12-03 22:21:20 127.0.0.1 GET/dealership/cars/123|456 - 80 - 127.0.0.1 curl/7.27.0 500 0 0 52012-12-03 22:21:25 127.0.0.1 GET/dealership/cars/123+456 - 80 - 127.0.0.1 curl/7.27.0 200 0 0 1

解决方案

我看过这个,我们在 ServiceStack 中没有任何可以做的事情,因为它是由 ASP.NET 生成的预先验证的异常,请参阅 Scott Hanselman 的帖子,了解如何在 IIS/ASP.NET 中允许无效字符.>

注意:由于它不通过 ASP.NET,因此 ServiceStack 的自托管是允许的,如下所示 HttpListener 集成测试.

Using service stack 3.9.21. Hosting the app in IIS 7.5. Using an Integrated 4.0.30319 ASP.NET app pool.

For illustration purposes let's say I have the following path (that is backed by a DTO and a corresponding request handler):

/cars/{id}

Some cars' ids have characters in them that I suppose have to be URL encoded - pipe, |, is one of them. When I send requests to fetch a car with for example an id of '1|2' I get a good old 500 with the following stack trace:

[ArgumentException]: Illegal characters in path.
   at System.IO.Path.CheckInvalidPathChars(String path)
   at System.IO.Path.GetFileName(String path)
   at ServiceStack.MiniProfiler.UI.MiniProfilerHandler.MatchesRequest(IHttpRequest request) in C:\src\ServiceStack\src\ServiceStack\MiniProfiler\UI\MiniProfilerHandler.cs:line 24
   at ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory.GetHandler(HttpContext context, String requestType, String url, String pathTranslated) in C:\src\ServiceStack\src\ServiceStack\WebHost.Endpoints\ServiceStackHttpHandlerFactory.cs:line 153
   at System.Web.HttpApplication.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

I get this regardless of whether I URL encode the pipe in the path or not. How can I solve this problem?

More details

DTO

using ServiceStack.ServiceHost;

namespace SSUEB
{
    [Route("/cars/{id}", "GET")]
    public class ById
    {
        public string Id { get; set; }
    }
}

Endpoint

using System.Collections.Generic;
using System.Net;
using ServiceStack.Common.Web;
using Stack = ServiceStack.ServiceInterface;

namespace SSUEB
{
    public class Cars : Stack.Service
    {
        public object Get(ById byId)
        {
            return new HttpResult(new Dictionary<string, string> {{"id", byId.Id}}, HttpStatusCode.OK);
        }
    }
}

App

using ServiceStack.WebHost.Endpoints;

namespace SSUEB
{
    public class SSUEB : AppHostBase
    {
        public SSUEB() : base("ServiceStack toy service", typeof(SSUEB).Assembly)
        {
        }

        public override void Configure(Funq.Container container)
        {
            ServiceStack.Text.JsConfig.EmitCamelCaseNames = true;
            SetConfig(new EndpointHostConfig { DebugMode = true });
        }
    }
}

Requests

This one:

curl -v -X GET -H "Accept: application/json" http://localhost:80/dealership/cars/123%20456

Gets the expected 200 response:

{"id":"123 456"}

But this one:

curl -v -X GET -H "Accept: application/json" http://localhost:80/dealership/cars/123%7C456

results in the originally reported issue.

IIS Request Log shows that the %7C gets decoded as a pipe and that the %20 gets decoded (in the log at least as a plus). The latter results in a 200 (OK) response, the former - 500 (Internal Server Error).

2012-12-03 22:21:20 127.0.0.1 GET /dealership/cars/123|456 - 80 - 127.0.0.1 curl/7.27.0 500 0 0 5
2012-12-03 22:21:25 127.0.0.1 GET /dealership/cars/123+456 - 80 - 127.0.0.1 curl/7.27.0 200 0 0 1

解决方案

I've had a look at this and there's nothing that we can do in ServiceStack to allow this as it's a pre-validated exception generated by ASP.NET, see Scott Hanselman's post on how to allow invalid chars in IIS/ASP.NET.

Note: As it doesn't go through ASP.NET this is allowed with ServiceStack's self-host as seen from this HttpListener integration test.

这篇关于带有 URL 不友好字符的路径参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆