点字符“。” 在MVC Web API 2中用于请求如api / people / STAFF.45287

我试图让工作的url是: http ://somedomain.com/api/people/staff.33311(就像LAST.FM这样的网站允许在他们的RESTFul和网页url上的各种标志,例如“ http://www.last.fm/artist/psy'aviah ”是LAST.FM的有效url)。

什么工程是以下scheme: – http://somedomain.com/api/people/ – 返回所有的人 – http://somedomain.com/api/people/staff33311 – 将工作,但它不是我所“ m之后,我想要的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. 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 } ); } 

我已经试过了这个博客http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx的所有提示,但它仍然不会工作..我也认为这是相当繁琐的,我不知道是否没有另一个,更好,更安全的方式。

我们有我们的Id这样的内部,所以我们将不得不find一个解决scheme来适应这个或那个点,最好是“。”的样式。 但我打开替代的build议,如果需要的url…

在您的web.config文件中设置以下内容应该可以解决您的问题:

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

用斜杠后缀URL,例如http://somedomain.com/api/people/staff.33311/而不是http://somedomain.com/api/people/staff.33311

我真的不知道自己在做什么,但是在玩过之前的回答之后,我提出了另一个更合适的解决scheme:

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

我发现在标准ExtensionlessUrlHandler为我解决这个问题之前 添加以下内容:

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

我不认为这个名字真的很重要,除非你的IDE(在我的情况下为Visual Studio)pipe理你的站点configuration可能会有所帮助。

H / T到https://stackoverflow.com/a/15802305/264628

我发现我需要做的不仅仅是将runAllManagedModulesForAllRequests属性设置为true 。 我还必须确保将无扩展的URL处理程序configuration为查看所有path。 此外,还有一个额外的奖励configuration设置,可以帮助在某些情况下添加。 这是我的工作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.0将其path属性设置为*而不是*. (例如)。

我发现这两种方式适用于我:要么将runAllManagedModulesForAllRequests设置为true或添加ExtentionlessUrlHandler如下。 最后,我select添加extensionUrLHandler,因为runAllManagedModulesForAllRequests确实对网站有性能影响。

 <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和网站configuration相关的设置的情况。 所以我只能通过在代码级别进行更改来使其工作。

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

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

看看下面的URL用户input他的用户名来获取他的个人信息:

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

由于您只需从服务器获取一些数据,我们使用http GET动词。 使用GET调用时,只能在URL片段中传递任何input参数。

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

 { "userid" : "foo.bar" } 

改变你的方法定义如下:

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

注意 :更多关于何时使用GET动词以及何时使用POST动词。