簡體   English   中英

具有多個可選參數的 Asp.net 核心路由調用不同的操作

[英]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.

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