Символ точки '.'в MVC Web API 2 для запроса, такого как api/people/STAFF.Сорок пять тысяч двести восемьдесят семь


URL-адрес, я пытаюсь показать работы в стиле: http://somedomain.com/api/people/staff.33311 (просто как сайтов, как в прошлом.ФМ разрешить все знаки в их спокойный & URL-адреса веб-страницы, например "http://www.last.fm/artist/psy'aviah" является допустимым URL-адресов для последних.ФМ).

что работает следующие сценарии: - 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. 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 уже пробовал следовать всем советам этого блога http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx но это все равно не сработает.. Я также думаю, что это довольно утомительно, и мне интересно, нет ли другого, лучшего и более безопасного способа.

у нас есть внутренний идентификатор, поэтому нам придется найти решение, чтобы соответствовать точке так или иначе, предпочтительно в стиле "." но Я открыт для альтернативных предложений по URL-адресам, если это необходимо...

8 82

8 ответов:

параметр в файле web.config файл должен исправить вашу проблему:

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

суффикс URL с косой чертой, например http://somedomain.com/api/people/staff.33311/ вместо http://somedomain.com/api/people/staff.33311.

Я нашел это добавлять следующее до стандартный ExtensionlessUrlHandler решает проблему для меня:

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

Я не думаю, что имя действительно имеет большое значение, за исключением того, что оно, вероятно, помогает, если ваша IDE (Visual Studio в моем случае) управляет конфигурацией вашего сайта.

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

Я не знаю, что я делаю на самом деле, но после игры с предыдущего ответа немного, я придумал другое, возможно более подходящее решение:

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

я обнаружил, что мне нужно было сделать больше, чем просто установить до true. Я также должен был убедиться, что обработчик URL без расширения был настроен для просмотра всех путей. Кроме того, вы можете добавить еще один бонусный параметр конфигурации, который поможет в некоторых случаях. Вот моя рабочая сеть.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 имеет значение * в противоположность *. (например).

Я застрял в этой ситуации, но с добавлением / в конце URL не выглядел чистым для меня.

Так что просто добавьте ниже в web.конфигурацииhandlers тег и вы будете хорошо идти.

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

Я обнаружил, что оба способа работают для меня: либо установка runAllManagedModulesForAllRequests в true, либо добавление ExtentionlessUrlHandler следующим образом. Наконец, я решил добавить 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 и website config. Поэтому мне пришлось заставить его работать, внося изменения только на уровне кода.

простой момент заключается в том, что наиболее распространенный случай, когда вы в конечном итоге будете иметь точечный символ в URL-адресе, - это когда вы получаете некоторый ввод от пользователя и передаете его как строку запроса или фрагмент url, чтобы передать некоторый аргумент параметрам в методе действия вашего контроллер.

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

посмотрите на URL ниже, где пользователь вводит свой идентификатор пользователя, чтобы получить его личные данные:

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 глагол здесь.