Можно ли использовать точки в маршрутах Asp.Net Web Api?

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

http://server/collection/id.format

Я хотел бы следовать той же схеме URL в версии Web Api (самостоятельно размещенной) и попробовал это:

var c = new HttpSelfHostConfiguration(b);
c.Routes.MapHttpRoute(
    name: "DefaultApiRoute",
    routeTemplate: "{controller}/{id}.{format}",
    defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional },
    constraints: null
);

К сожалению, это, похоже, не разрешается (в соответствии с 404 на / foo, / foo / bar и /foo/bar.txt). Аналогичный шаблон, использующий косую черту перед «форматированием»; работает отлично:

var c = new HttpSelfHostConfiguration(b);
c.Routes.MapHttpRoute(
    name: "DefaultApiRoute",
    routeTemplate: "{controller}/{id}/{format}",
    defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional },
    constraints: null
);

Я еще не углубился в код для Web Api, и прежде чем я подумал, я хотел бы спросить здесь, чтобы узнать, является ли это известным или, возможно, даже оправданным ограничением в Web Api.

ОБНОВЛЕНИЕ: я забыл упомянуть, что & quot; id & quot; и & quot; формат & quot; являются строками, что оказывается важным для решения этого вопроса. Добавление ограничения для исключения периодов из & quot; id & quot; токен решает проблему 404.

 Silvermind15 июл. 2012 г., 20:08
Вы пытались унаследовать отController и переопределить все, что происходит черезInitialize?
 Only Bolivian Here15 июл. 2012 г., 19:49
Облицовкаvery Сама похожая проблема:stackoverflow.com/questions/11487181/… | Насколько я могу судить, точка не может быть использована в URL. Я надеюсь, что я ошибся.

Ответы на вопрос(5)

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

Чтобы использовать точку после строкового параметра, механизму маршрутизации требуются подсказки в виде ограничения:

var c = new HttpSelfHostConfiguration(b);
c.Routes.MapHttpRoute(
    name: "DefaultApiRoute",
    routeTemplate: "{controller}/{id}.{format}",
    defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional },
    constraints: new { id = "[^\\.]+" } // anything but a period
);

Добавление ограничения к предыдущему токену позволяет корректно декомпозировать и обрабатывать входящие URL-адреса. Без подсказки, "id" токен можно интерпретировать так, чтобы он соответствовал оставшемуся экстенту URL. Это всего лишь частный случай необходимости ограничений для определения границ между строковыми параметрами в целом.

Да, точки можно использовать в маршрутах URL в веб-API Asp.Net, но если они должны следовать строковому параметру, обязательно примените правильное ограничение к маршруту.

замещать"*." с"*" в system.webServer.handlers в web.config, т.е. удалить точку.

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
 01 апр. 2015 г., 20:49
Спасибо, как ты это поймал.
 13 апр. 2015 г., 09:35
Мне никогда бы не пришло в голову проверить, был ли он не для этого ответа. Весьма признателен.
 15 апр. 2016 г., 17:38
Чтобы включить его только для запросов API / *, простоadd линия<add name="ExtensionlessUrlHandler-Integrated-4.0-API" path="api/*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />, Кстати, имя не важно.
Решение Вопроса

ки:

Create a new .NET 4.0 Console Application Switch to .NET Framework 4.0 profile Install the Microsoft.AspNet.WebApi.SelfHost NuGet

Define a Product

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
}

A corresponding API Controller:

public class ProductsController : ApiController
{
    public Product Get(int id)
    {
        return new Product
        {
            Id = id,
            Name = "prd " + id
        };
    }
}

And a host:

class Program
{
    static void Main(string[] args)
    {
        var config = new HttpSelfHostConfiguration("http://localhost:8080");

        config.Routes.MapHttpRoute(
            name: "DefaultApiRoute",
            routeTemplate: "{controller}/{id}.{format}",
            defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional },
            constraints: null
        );

        using (var server = new HttpSelfHostServer(config))
        {
            server.OpenAsync().Wait();
            Console.WriteLine("Press Enter to quit.");
            Console.ReadLine();
        }
    }
}

Теперь, когда вы запускаете это консольное приложение, вы можете перейти кhttp://localhost:8080/products/123.xml, Но, конечно, вы могли бы перейти кhttp://localhost:8080/products/123.json и вы все равно получите XML. Таким образом, вопрос: как включить согласование содержимого с помощью параметра маршрута?

Вы можете сделать следующее:

    class Program
    {
        static void Main(string[] args)
        {
            var config = new HttpSelfHostConfiguration("http://localhost:8080");
            config.Formatters.XmlFormatter.AddUriPathExtensionMapping("xml", "text/html");
            config.Formatters.JsonFormatter.AddUriPathExtensionMapping("json", "application/json");

            config.Routes.MapHttpRoute(
                name: "DefaultApiRoute",
                routeTemplate: "{controller}/{id}.{ext}",
                defaults: new { id = RouteParameter.Optional, formatter = RouteParameter.Optional },
                constraints: null
            );

            using (var server = new HttpSelfHostServer(config))
            {
                server.OpenAsync().Wait();
                Console.WriteLine("Press Enter to quit.");
                Console.ReadLine();
            }
        }
    }

и теперь вы можете использовать следующие URL:

http://localhost:8080/products/123.xml
http://localhost:8080/products/123.json

Теперь вам может быть интересно, какова связь между{ext} параметр маршрута, который мы использовали в нашем определении маршрута иAddUriPathExtensionMapping метод, потому что нигде мы его не указали. Ну, угадайте, что: это жестко закодировано вUriPathExtensionMapping класс дляext и вы не можете изменить его, потому что он доступен только для чтения:

public class UriPathExtensionMapping
{
    public static readonly string UriPathExtensionKey;

    static UriPathExtensionMapping()
    {
        UriPathExtensionKey = "ext";
    }

    ...
}

Все это, чтобы ответить на ваш вопрос:

Can periods be used in Asp.Net Web Api Routes?

Да.

 24 июн. 2015 г., 10:47
formatter в качестве имени параметра по умолчанию и ext в шаблоне маршрута, что не может быть правильным?
 Lee16 июл. 2012 г., 20:01
Ваш ответ является верным, но я забыл упомянуть, что & quot; id & quot; и & quot; формат & quot; Строки Я обновлю вопрос, но могу ли я принять ваш ответ, а затем добавить другой собственный информационный ответ?

web.config вы можете настроить IIS так, чтобы он игнорировал определенные пути URL-адресов, потому что webapi будет обрабатывать запросы. Если вы хотите, чтобы IIS обрабатывал загрузки файлов, а также обрабатывал вызовы webapi, вы можете добавить конфигурацию ManagedDllExtension в system.webServer.handlers в web.config.

      <add name="ManagedDllExtension" path="collection/*.*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
 31 июл. 2014 г., 17:02
Это не правильно, и отмеченные изменения не являются необходимыми в большинстве случаев. Если у вас настроены все управляемые модули для обработки, IIS не «перехватывает» просит просто иметь точку в пути. В любом случае, это было бы глупо; Имена файлов не должны иметь точку в них, а имена каталогов / маршрутов могут. Прочитайте собственный ответ ФП о том, что на самом деле здесь происходит.

чтобы установить параметр runAllManagedModulesForAllRequests в атрибуте modules в вашем web.config

<modules runAllManagedModulesForAllRequests="true">..</modules>

В противном случае он не будет работать в IIS (возможно, он будет обрабатываться неуправляемыми обработчиками).

 19 сент. 2013 г., 23:49
У меня была похожая проблема, и это оказалось ответом в моем случае. Спасибо! +1

Ваш ответ на вопрос