MVC Web API 2中的点字符“ .”用于诸如 API/people/STAFF.45287之类的请求

我试图让工作的 URL 是一个样式: http://somedomain.com/api/people/staff.33311(就像网站 LAST.FM 允许所有种类的标志在他们的 RESTFul & WebPage 网址,例如“ http://www.last.fm/artist/psy'aviah”是一个有效的网址 LAST.FM)。

有效的方案如下: - http://somedomain.com/api/people/-返回所有人 - http://somedomain.com/api/people/staff33311-也行,但不是我想要的 我希望 url 接受一个“点”,就像下面的例子一样 - http://somedomain.com/api/people/staff.33311-但这给了我一个

HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

我安排了以下事情:

  1. 控制器“ PeopleController”

    public IEnumerable<Person> GetAllPeople()
    {
    return _people;
    }
    
    
    public IHttpActionResult GetPerson(string id)
    {
    var person = _people.FirstOrDefault(p => p.Id.ToLower().Equals(id.ToLower()));
    if (person == null)
    return NotFound();
    
    
    return Ok(person);
    }
    
  2. The WebApiConfig.cs

    public static void Register(HttpConfiguration config)
    {
    // Web API configuration and services
    
    
    // Web API routes
    config.MapHttpAttributeRoutes();
    
    
    config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
    );
    }
    

I already tried following all the tips of this blogpost http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx but it still won't work.. I also think it's quite tedious and I wonder if there isn't another, better and more secure way.

We have our Id's internally like this, so we're going to have to find a solution to fit the dot in one way or another, preferably in the style of "." but I'm open to alternative suggestions for urls if need be...

55760 次浏览

web.config文件中的以下设置应该可以修复您的问题:

<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />

我不知道自己到底在做什么,但在回想了一下之前的答案之后,我想出了另一个或许更合适的解决方案:

<system.webServer>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
</system.webServer>

在 URL 后面加一个斜杠,例如 http://somedomain.com/api/people/staff.33311/而不是 http://somedomain.com/api/people/staff.33311

我发现我需要做的不仅仅是将 runAllManagedModulesForAllRequests属性设置为 true。我还必须确保将无扩展 URL 处理程序配置为查看所有路径。此外,还有一个额外的配置设置,您可以添加,这将有助于在某些情况下。下面是我正在使用的 Web.config:

<system.web>
<httpRuntime relaxedUrlToFileSystemMapping="true" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="WebDAV" />
<remove name="OPTIONSVerbHandler" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0"  path="*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>

特别要注意的是,ExtensionlessUrlHandler-Integrated-4.0path属性设置为 *,而不是 *.(例如)。

我发现 增加以下 之前标准 ExtensionlessUrlHandler为我解决了这个问题:

<add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
path="api/*"
verb="*"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />

我认为名称实际上并不那么重要,除非它可能会有所帮助,如果您的 IDE (在我的例子中是 VisualStudio)正在管理您的站点配置。

呼叫 https://stackoverflow.com/a/15802305/264628

我发现这两种方法对我都适用: 要么将 runAllManagedModulesForAllRequest 设置为 true,要么像下面这样添加 ExtentionlesUrlHandler。最后,我选择添加 extsionUrLHandler,因为 runAllManagedModulesForAllRequest 确实会对站点的性能产生影响。

<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<remove name="WebDAV" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

我也面对过这个问题。我是在一种情况下,我不应该发挥与 IIS 和网站配置相关的设置。所以我只能通过在代码级别进行更改来使其工作。

The point is that the most common case where you would end up having dot character in the URL is when you get some input from the user and pass it as a query string or url fragment to pass some argument to the parameters in the action method of your controller.

public class GetuserdetailsbyuseridController : ApiController
{
string getuserdetailsbyuserid(string userId)
{
//some code to get user details
}
}

看看下面的 URL,用户输入他的用户 ID 来获得他的个人信息:

http://mywebsite:8080/getuserdetailsbyuserid/foo.bar

因为您必须从服务器获取一些数据,所以我们使用 http GET谓词。使用 GET调用时,任何输入参数都只能在 URL 片段中传递。

所以为了解决我的问题,我把动作的 http 动词改成了 POST。Http POST谓词还具有在主体中传递任何用户或非用户输入的功能。因此,我创建了一个 JSON 数据,并将其传递到 http POST请求的主体中:

{
"userid" : "foo.bar"
}

更改方法定义如下:

public class GetuserdetailsbyuseridController : ApiController
{
[Post]
string getuserdetailsbyuserid([FromBody] string userId)
{
//some code to get user details
}
}

注意 : 更多关于何时使用 GET动词和何时使用 POST动词 给你

我被困在这种情况下,但附加 / at the end of URL wasn't look clean for me.

所以只需在下面的 Web.config handlers标签中添加 你就可以走了。

<add name="Nancy" path="api" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />

我会在 Web.config 文件中使用它:

<add name="ManagedSpecialNames" path="api/people/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

before standard "ExtensionlessUrlHandler".

例如,在我的例子中,我把它放在这里:

<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ManagedFiles" path="api/people/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

因此,您可以强制这种模式的 URL 由您来管理,而不是将其作为应用程序目录树中的文件进行标准管理。