ASP.NET Core Web API 入門教學 - 參數化並過濾接受值


Posted by TalllKai on 2021-04-23

影片講解(有字幕):


今天要來講得稍微有點基礎進階,如果看不懂的,可以先跳過,等哪天有用到再回頭來看。

首先可以看到上一章講到的關鍵字搜尋的參數部分,我今天如果又多加兩個欄位minOrder和maxOrder,那上面參數的部分可能會變的相當多。更不用說或許會你有可能會有更多的欄位,那用這種寫法,會讓可觀性跟維護性都不太好。

[HttpGet]
public IEnumerable<TodoListSelectDto> Get(string name, bool? enable, DateTime? InsertTime,int minOrder,int maxOrder)
{ 
}

所以今天我們可以將它包成另外一個類別,例如我就創了一個TodoSelectParameter.cs

namespace Todo.Parameters
{
    public class TodoSelectParameter
    {
        public string name { get; set; }
        public bool? enable { get; set; }
        public DateTime? InsertTime { get; set; }
        public int? minOrder { get; set; }
        public int? maxOrder { get; set; }
    }
}

將上面的欄位參數都搬到這個類別來,然後我們再接受參數的地方就可以改成這個類別,如下

[HttpGet]
public IActionResult Get(TodoSelectParameter value)
{
}

這樣看起來是不是好多了呢?以後要維護欄位我們就很明確的到TodoSelectParameter.cs做維護即可。

不過光是這樣我們事無法正確的接受到GET傳來的參數,我們必須在前面加上[FromQuery],關於這個的用法我會在下一章教,這邊就先帶過。

[HttpGet]
public IEnumerable<TodoListSelectDto> Get([FromQuery] TodoSelectParameter value)
{
    var result = _todoContext.TodoLists
        .Select(a => new TodoListSelectDto
        {
            Enable = a.Enable,
            InsertEmployeeName = a.InsertEmployee.Name,
            InsertTime = a.InsertTime,
            Name = a.Name,
            Orders = a.Orders,
            TodoId = a.TodoId,
            UpdateEmployeeName = a.UpdateEmployee.Name,
            UpdateTime = a.UpdateTime
        });

    if (!string.IsNullOrWhiteSpace(value.name))
    {
        result = result.Where(a => a.Name.Contains(value.name));
    }

    if (value.enable != null)
    {
        result = result.Where(a => a.Enable == value.enable);
    }

    if (value.InsertTime != null)
    {
        result = result.Where(a => a.InsertTime.Date == value.InsertTime);
    }

    if (value.minOrder != null && value.maxOrder != null)
    {
        result = result.Where(a => a.Orders >= value.minOrder && a.Orders <=         value.maxOrder);
    }
    return result;
}

那當然我們要將原來的變數都加上value.,因為我們是接受到一包value,那這樣測試看看新加上去的order能否成功。/api/todo?minOrder=3&maxOrder=4

正確的撈出了order在3-4的資料,代表我們有正確的接收到GET參數值。那也就是說,如果今天要接收的參數真的太多了,那你就可以考慮將這一堆參數封裝成一個類別。

那接著我們要做一些變化,今天我們可能會覺得還要打minOrder=3&maxOrder=4太過麻煩,我想要濃縮成一個欄位,例如:order=3-4,這樣不僅簡化,可讀性也不錯。那我們就可以在TodoSelectParameter.cs裡進行加工,增加以下變數至那我們就可以在TodoSelectParameter.cs中。

private string _order;
public string Order
{
    get { return _order; }
    set
    {
        //2-3
        Regex regex = new Regex(@"^\d*-\d$");
        if (regex.Match(value).Success)
        {
            minOrder = Int32.Parse(value.Split('-')[0]);
            maxOrder = Int32.Parse(value.Split('-')[1]);
        }
        _order = value;
    }
}

這個意思是說,當接收到Order值的時候,我們進行一個正規表達式(Regex)的過濾,如果符合規則
,那我這邊的規則就是要符合兩邊是數字中間一條-,例如:3-4,符合規則的化我就進行minOrder和maxOrder的給值,那minOrder就會取-左邊的數字,maxOrder就會取-右邊的數字。如此我們就可以透過Order=3-4處理後變成minOrder=3和maxOrder=4。

那接口程式的部分都不用修改打上我們的新網址/api/todo?order=3-4,執行結果如下。

那當然處理order的過程要放在TodoController.cs也是可以的,但是我們放在TodoSelectParameter.cs則會提高內聚力,降低耦合性,以後再維護上我們知道有關參數的事情,就是到TodoSelectParameter.cs來做修改,會讓你的程式更為明確。

以上是今天的簡單教學,想看更完整的解說可以看影片。

新手分享學習成果,若有錯誤,煩請告知修正,感謝🙏


#ASP.NET Core #Web API #.NET 5







Related Posts

Get讀取與Post傳送比較與傳送原理

Get讀取與Post傳送比較與傳送原理

自動化測試 x Puppeteer - 玩偶QA參一咖 Day07

自動化測試 x Puppeteer - 玩偶QA參一咖 Day07

Leetcode 刷題 pattern - Breadth-First Search

Leetcode 刷題 pattern - Breadth-First Search


Comments