[英]Asp.net core Routing with multiple optional parameters calling different action
在 Asp.net WebApi2 中
當調用 api/values/9b858599-7639-45da-acd6-a1323fb019b5 時,調用 get Action。
帶有可選參數的操作。
當調用 api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100 或 api/values/?maxRecords=100 GetProducts Action 時。
在 Asp.net Core 中
但是在 asp.net 核心中,當 api/values/9b858599-7639-45da-acd6-a1323fb019b5 被調用時,GetProducts 動作被調用。 我想在不更改現有 url 的情況下調用 Get 操作。
如何在 Asp.net core 2.0 中解決此問題
控制器
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
//https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5
[HttpGet("{productId:Guid}", Order = 1)]
public ActionResult<string> Get(Guid productId)
{
return "value1";
}
//https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100
//https://localhost:44323/api/values/?maxRecords=100
[HttpGet("{startRecordId:Guid?}")]
public ActionResult<IEnumerable<string>> GetProducts(Guid? startRecordId, int maxRecords, DateTimeOffset? minimumChangeDate = null)
{
return new string[] { "value1", "value2" };
}
}
啟動文件
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute("DefaultApi", "api/{controller}/{id?}");
});
雖然不理想,這是一個臨時的鞋拔,直到您可以更新客戶端調用。 你可以試試這個,如果你可以假設你必須有一個 maxRecords QueryString。 因為如果它默認為 0,則它是無用的,除非在它為 0 的情況下您有適當的邏輯。
//https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5
[HttpGet("{productId:Guid}", Order = 1)]
public ActionResult<string> Get(Guid productId)
{
return "value1";
}
//https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100
//https://localhost:44323/api/values/?maxRecords=100
[HttpGet("{startRecordId:Guid?}")]
public ActionResult<IEnumerable<string>> GetProducts(Guid? startRecordId, [FromQuery] int maxRecords, [FromQuery] DateTimeOffset? minimumChangeDate = null)
{
if (!Request.GetDisplayUrl().Contains(nameof(maxRecords)) &&
startRecordId.HasValue)
{
return Get(startRecordId.Value);
}
return new string[] { "value1", "value2" };
}
您可以組合您的操作並根據具有提供值的參數更改行為;
//https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5
//https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100
//https://localhost:44323/api/values/?maxRecords=100
[HttpGet("{startRecordId:Guid?}")]
public ActionResult<IEnumerable<string>> GetProducts(Guid? startRecordId, int? maxRecords, DateTimeOffset? minimumChangeDate = null)
{
if (startRecordId.HasValue && !maxRecords.HasValue)
return "value";
else
return new string[] { "value1", "value2" };
}
您的 URI 未遵循 RESTful 約定。 坦率地說,我一開始看不出你是如何完成這項工作的,因為同樣的問題應該會導致 ASP.NET Web Api,但你可能只是因為在 ASP.NET 中完成路由的方式很幸運網絡 API。 ASP.NET Core 以完全不同的方式處理路由。
無論如何,對於多個產品的列表中的路徑不應包含在實際的URI的ID。 換句話說:
/api/values - Multiple values
/api/values/{id} - Single value
對於過濾、排序等多條記錄,這些應該是查詢字符串的一部分。 這包括類似startRecordId
:
/api/values?startRecordId={id}
消除路線中的歧義,您就沒有問題了。 無論是長還是短,您都不能讓兩條路線在同一路徑段中都接受Guid
,即使它在一個路線上是可選的。 將startRecordId
移動到查詢字符串中,無論如何這是正確的方法,您很高興。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.