点字符'。'在MVC Web API 2中请求诸如api / people / STAFF.45287之类的请求

问题描述 投票:96回答:8

我试图让工作的网址是: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 - 也会起作用,但它不是我想要的网址后接受一个“点”,如下面的例子 - 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. 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 } ); }

我已经尝试过关注qazxsw poi这篇博文的所有提示,但它仍然无法工作......我也认为这很乏味,我想知道是否有其他更好,更安全的方式。

我们内部有这样的Id,所以我们必须找到一种解决方案,以这种或那种方式适合点,最好是“。”的风格。但如果需要,我愿意接受网址的其他建议......

c# asp.net-mvc-4 asp.net-web-api asp.net-mvc-routing asp.net-web-api2
8个回答

126
投票

使用斜杠替换URL,例如<configuration> <system.webServer> <modules runAllManagedModulesForAllRequests="true" /> 而不是http://somedomain.com/api/people/staff.33311/


30
投票

我发现在标准http://somedomain.com/api/people/staff.33311之前添加以下内容为我解决了这个问题:

ExtensionlessUrlHandler

我认为名称实际上并不重要,除非你的IDE(在我的情况下是Visual Studio)管理你的站点配置可能会有所帮助。

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


23
投票

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

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

8
投票

我发现我需要做的不仅仅是将<system.webServer> <modules> <remove name="UrlRoutingModule-4.0" /> <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" /> </modules> </system.webServer> 属性设置为runAllManagedModulesForAllRequests。我还必须确保将无扩展名URL处理程序配置为查看所有路径。此外,您还可以添加一个额外的奖励配置设置,这在某些情况下会有所帮助。这是我的工作Web.config:

true

特别要注意的是,<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.0属性设置为path而不是*(例如)。


2
投票

我陷入了这种情况,但在URL结尾附加*.对我来说并不干净。

所以只需在web.config /标签中添加以下内容即可。

handlers

1
投票

我发现这两种方式都适用于我:将runAllManagedModulesForAllRequests设置为true或者如下所示添加ExtentionlessUrlHandler。最后,我选择添加extensionUrLHandler,因为runAllManagedModulesForAllRequests确实对站点有性能影响。

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

0
投票

我遇到了同样的问题和我所处的情况,我不应该使用IIS和网站配置相关的设置。因此,我必须通过仅在代码级别进行更改来使其工作。

简单的一点是,最常见的情况是,您最终会在URL中获得点字符,这是当您从用户那里获得一些输入并将其作为查询字符串或url片段传递给操作方法中的参数时传递一些参数你的控制器。

<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>

查看以下URL,用户输入其用户ID以获取其个人详细信息:

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

由于您必须简单地从服务器获取一些数据,我们使用http http://mywebsite:8080/getuserdetailsbyuserid/foo.bar 动词。使用GET调用时,任何输入参数都只能在URL片段中传递。

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

POST

更改方法定义如下:

{
  "userid" : "foo.bar"
}

注意:更多关于何时使用public class GetuserdetailsbyuseridController : ApiController { [Post] string getuserdetailsbyuserid([FromBody] string userId) { //some code to get user details } } 动词以及何时使用GET动词POST

© www.soinside.com 2019 - 2024. All rights reserved.