[英]Multiple optional parameters routing
我的webapi項目中有以下路由定義。 我有問題,其中一個參數未通過。 例如;
當我調用/ Controller / Action / param2 / startdate / enddate時,我為param2傳遞的值是param1,反之亦然。問題是,RoutingModule無法檢測到提供的路由值是param2而不是param1
如果我在url中使用查詢字符串但不想使用查詢字符串,它可以工作。 感謝您的幫助。
有沒有辦法達到我的期望?
config.Routes.MapHttpRoute(
name: "RetrieveHistory",
routeTemplate: "{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}",
defaults: new
{
controller = "Vend",
action = "RetrieveUtrnHistory",
param1 = RouteParameter.Optional,
param2 = RouteParameter.Optional,
starDate = RouteParameter.Optional,
endDate = RouteParameter.Optional
});
謝謝
要解決您的問題,您必須考慮以下事項:
/
作為分隔符之外的東西,使路線的某些部分可以區分 由於您沒有告訴您的網址如何,我會向您展示我自己的示例。
假設您有一個TestController
Web API Controller類,其操作如下:
// GET api/Test/TestAction/ ...
[HttpGet]
public object TestAction(int param1, DateTime startDate, DateTime endDate,
int? param2 = null)
{
return new
{
param1 = param1,
param2 = param2,
startDate = startDate,
endDate = endDate
}.ToString();
}
注意:對於HTTP GET,可以使用默認路由Web API控制器的名為GetXxx
的方法,HTTP POST可以使用名為PostXxx
的方法,依此類推。 但是,一旦在URL模板中包含Controller
和Action
,就必須使用[HttpXxx]
屬性使您的方法可用於所需的HTTP方法。
在第一個例子中,我認為param1
和param2
都是整數, stardDate
和endDate
是日期:
http://myhost/api/Mycontroller/Myaction/12/22/2014-12-01/2014-12-31
http://myhost/api/Mycontroller/Myaction/22/2014-12-01/2014-12-31
如果您希望第一個URL匹配以下參數:
param1 = 12; param2 = 22; startDate = 2014-12-01; endData = 2014-12-31
第二個像這樣:
param1 = 12; param2 = null; startDate = 2014-12-01; endData = 2014-12-31
您需要注冊兩個路由,一個匹配每個可能的URL結構,即
// for the 1st
routeTemplate: "api/{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}"
// for the 2nd
routeTemplate: "api/{controller}/{action}/{param1}/{startDate}/{endDate}"
請注意,在這種情況下,兩個路由是互斥的,即單個URL只能匹配其中一個路由,因此您可以在任何其他路由中注冊它們。
但是,您必須注意第二個URL沒有為param2
定義值, TestAction
方法需要它。 這不起作用:您必須在控制器的方法和路徑注冊中包含此參數的默認值:
int? param2 = null
int? param2 = null
(C#要求可選參數為最后一個)。 defaults: new { param2 = RouteParameter.Optional }
這是解決中間問題中可選參數的方法。 通常,您需要定義多個路由,具體取決於有多少可選參數,並在Web API操作方法中使用默認值聲明此參數。
注意:正如我上面所寫,在MVC中,您無需在方法參數中指定默認值即可使用
指定路由參數的約束有兩個結果:
您只需在路由注冊上添加constraint
參數,如下所示:
config.Routes.MapHttpRoute(
name: "Multiparam2",
routeTemplate: "api/{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}",
constraints: new
{
startDate = @"20\d\d-[0-1]?\d-[0-3]?\d", // regex
endDate = @"20\d\d-[0-1]?\d-[0-3]?\d" // regex
},
defaults: new object { }
);
請注意,必須指定defaults
參數,即使它是空的。
注意:在這種情況下的約束是一個正則表達式,只匹配20XX年份的日期,表示為單個數字的月份,或0x或1x,日期作為單個數字或0x,1x,2x或3x,分開破折號。 所以這個正則表達式將匹配2012-1-1
或2015-12-30
,但不是1920-12-30
。 你應該根據你的需要調整正則表達式。
到這時我已經解釋了如何支持可選參數,以及如何為它們指定格式(約束),以匹配路由模板。
定義可選參數的常用方法是在URL模板的末尾執行此操作,在這種情況下,如果路徑中缺少參數,則它們必須全部位於路徑的末尾。 (將其與中間的可選項進行比較:它們需要不同的路線)。
在此示例中,如果要使param2
和startDate
和endDate
可選,則必須在路徑注冊中定義它們,並在action方法中設置默認參數值。
最終的代碼如下所示:
[HttpGet]
public object TestAction(int param1, int? param2 = null, DateTime? startDate = null,
DateTime? endDate = null)
{
return new
{
param1 = param1,
param2 = param2,
startDate = startDate,
endDate = endDate
}.ToString();
}
config.Routes.MapHttpRoute(
name: "Multiparam1",
routeTemplate: "api/{controller}/{action}/{param1}/{startDate}/{endDate}",
constraints: new
{
startDate = @"20\d\d-[0-1]?\d-[0-3]?\d",
endDate = @"20\d\d-[0-1]?\d-[0-3]?\d"
},
defaults: new
{
param2 = RouteParameter.Optional,
startDate = RouteParameter.Optional,
endDate = RouteParameter.Optional
}
);
config.Routes.MapHttpRoute(
name: "Multiparam2",
routeTemplate: "api/{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}",
constraints: new
{
startDate = @"(20\d\d-[0-1]?\d-[0-3]?\d)?",
endDate = @"(20\d\d-[0-1]?\d-[0-3]?\d)?"
},
defaults: new
{
startDate = RouteParameter.Optional,
endDate = RouteParameter.Optional
}
);
請注意,在這種情況下:
Multiparam2
路由,則會錯誤地處理如下URL: http://localhost:1179/api/test/testaction/1/2014-12-12/2015-1-1
,其中param1=1; param2="2014-12-12"; startDate="2015-1-1"
param1=1; param2="2014-12-12"; startDate="2015-1-1"
param1=1; param2="2014-12-12"; startDate="2015-1-1"
。 (您可以通過對param2的附加約束來避免這種情況,該約束僅接受數字,例如param2=@"\\d+"
) startDate
和endDate
默認值。 您可以仔細處理不同位置的默認參數:
如果您仔細計划路線的樣子,您可以通過幾條路線和可選參數獲得所需的路線。
JotaBe答案很好而且完整。 只需要考慮參數是否可選,您必須使用從最低參數到最高參數的順序編寫routeTemplate。
就像 :
// for the 1st
routeTemplate: "api/{controller}/{action}/{param1}/{startDate}/{endDate}"
// for the 2nd
routeTemplate: "api/{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.