簡體   English   中英

可以在Asp.Net Web Api路由中使用句點嗎?

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

我正在從原始的http處理程序移動API項目,我在路徑中使用句點:

http://server/collection/id.format

我想在Web Api(自托管)版本中遵循相同的URL架構,並嘗試這樣做:

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

不幸的是,這似乎沒有解決(在/ foo,/ foo / bar和/foo/bar.txt上一致的404')。 在'format'之前使用斜杠的類似模式工作正常:

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中已知的,甚至是合理的限制。

更新:我忽略了提到“id”和“format”是字符串,這對於解決這個問題很重要。 添加約束以從“id”標記中排除句點可解決404問題。

通過執行以下操作,我能夠實現此目的:替換"*." 在web.config中的system.webServer.handlers中使用"*" ,即刪除句點。

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

請注意在web.config中的modules屬性中設置runAllManagedModulesForAllRequests選項

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

否則它將無法在IIS中運行(可能由非托管處理程序處理)。

我無法重現這個問題。 這應該工作。 這是我的設置:

  1. 創建一個新的.NET 4.0控制台應用程序
  2. 切換到.NET Framework 4.0配置文件
  3. 安裝Microsoft.AspNet.WebApi.SelfHost NuGet
  4. 定義Product

     public class Product { public int Id { get; set; } public string Name { get; set; } } 
  5. 相應的API控制器:

     public class ProductsController : ApiController { public Product Get(int id) { return new Product { Id = id, Name = "prd " + id }; } } 
  6. 和主持人:

     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();
            }
        }
    }

現在您可以使用以下網址:

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";
    }

    ...
}

這一切都是為了回答你的問題:

可以在Asp.Net Web Api路由中使用句點嗎?

是。

我接受了達林的答案(是的,句號可用於路線網址)因為它對我的例子特別正確,但對我沒有幫助。 這是我的錯,因為沒有明確指出“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的剩余范圍。 這只是需要約束來描述字符串參數之間的邊界的特定情況。

是的,可以在Asp.Net Web API中的URL路由中使用句點,但如果要遵循字符串參數,請確保對路徑應用正確的約束。

IIS以文件下載的周期攔截請求。 在您的web.config中,您可以將IIS配置為忽略特定的URL路徑,因為webapi將處理請求。 如果希望IIS處理文件下載以及處理webapi調用,可以將webagedDllExtension配置添加到web.config中的system.webServer.handlers。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM