ASP.NET Core: Xây dựng API web với hỗ trợ OData bằng ASP.NET Core


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Trong bài viết mẫu này:

Cảnh báo

Một máy khách độc hại hoặc ngây thơ có thể tạo một truy vấn tiêu tốn quá nhiều tài nguyên. Truy vấn như vậy có thể làm gián đoạn quyền truy cập vào dịch vụ của bạn. Xem lại Hướng dẫn bảo mật cho ASP.NET Core Web API OData trước khi bắt đầu hướng dẫn này.

Đăng ký OData

Thêm gói NuGet Microsoft.AspNetCore.OData vào dự án.

Cập nhật phương thức ConfigureServices trong Startup.cs với phần code được đánh dấu sau:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    // requires using Microsoft.AspNet.OData.Extensions;
    services.AddOData();
}

Mã trước đăng ký dịch vụ OData trong  bộ chứa nội xạ phụ thuộc (DI)  .

Định cấu hình middleware

OData có thể thực hiện sắp xếp, lọc, truy vấn dữ liệu liên quan, v.v. Mỗi khả năng này có thể được bật hoặc tắt bằng middleware.

Cập nhật Configure với phần code được đánh dấu sau:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        // The default HSTS value is 30 days. You may want to change this for 
        // production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseDefaultFiles();
    app.UseStaticFiles();
    app.UseHttpsRedirection();
    app.UseMvc(routeBuilder =>
    {
        routeBuilder.EnableDependencyInjection();
        routeBuilder.Select().OrderBy().Filter();
    });
}

Trong đoạn code trên:

  • Cho phép ghi đè lên các điểm cuối hiện có thông qua DI để tạo route, thay vì hiển thị điểm cuối OData truyền thống.
  • Cho phép chọn, sắp xếp theo thứ tự và lọc đối với trình tạo route.

Cập nhật controller

Thêm [EnableQuery()] vào phương thức public ActionResult<IQueryable<TodoItem>> GetTodoItems() trong TodoController:

// GET: api/Todo
[EnableQuery()]  // requires using Microsoft.AspNet.OData;
[HttpGet]
public ActionResult<IQueryable<TodoItem>> GetTodoItems()
{
    return _context.TodoItems;
}

Trả về System.Linq.IQueryable hoặc ActionResult<IQueryable> cho phép OData dịch truy vấn sang truy vấn SQL bằng các khả năng của ef core. Trả về các kiểu khác, chẳng hạn như IEnumerable khiến OData thực hiện các truy vấn trong ứng dụng.

Truy vấn tài nguyên bằng OData

Đăng một số dữ liệu lên ứng dụng API web, sử dụng công cụ như HTTP REPL hoặc Postman.

Gửi 5 Post request tới https://localhost:5001/api/todo với 5 mục bên dưới trong phần yêu cầu.

{
    "name": "test OData",
    "isComplete": false,
    "Type": "work",
    "priority": 1,
    "DueDate": "2019-04-18 00:00:01"
}

{
    "name": "test 2",
    "isComplete": true,
    "Type": "shopping",
    "priority": 2,
    "DueDate": "2019-04-18 08:00:01"
}

{
    "name": "test 3",
    "isComplete": true,
    "Type": "work",
    "priority": 1,
    "DueDate": "2019-04-18 09:00:01"
}

{
    "name": "test 4",
    "isComplete": false,
    "Type": "shopping",
    "priority": 3,
    "DueDate": "2019-04-18 12:00:01"
}

{
    "name": "test 5",
    "isComplete": false,
    "Type": "work",
    "priority": 2,
    "DueDate": "2019-04-18 15:00:01"
}

Gửi một Get request để xác minh dữ liệu trước đó đã được lưu. Ví dụ, http://localhost:5001/api/todo?$select=name,isComplete.

$select

Tùy chọn $select chỉ định một tập hợp con các property để đưa vào nội dung phản hồi. Ví dụ: để chỉ nhận name và isComplete của từng mục, hãy thêm ?$select=name,isComplete vào cuối đường dẫn yêu cầu.

Yêu cầu trên trả về dữ liệu sau:

[
    {
        "Name": "Item1",
        "IsComplete": false
    },
    {
        "Name": "test 5",
        "IsComplete": false
    },
    {
        "Name": "test OData",
        "IsComplete": false
    },
    {
        "Name": "test 2",
        "IsComplete": true
    },
    {
        "Name": "test 3",
        "IsComplete": true
    },
    {
        "Name": "test 4",
        "IsComplete": false
    }
]

$orderBy

Tùy chọn $orderBy có thể tiêu tốn quá nhiều tài nguyên. Cân nhắc sử dụng [Queryable(AllowedQueryOptions=AllowedQueryOptions.{Option})] để vô hiệu hóa $orderBy. Xem Hướng dẫn bảo mật cho ASP.NET Core Web API OData để biết thêm thông tin.

$orderBy sắp xếp dữ liệu dựa trên một hoặc nhiều property. Ví dụ: để sắp xếp dữ liệu dựa trên mức độ ưu tiên của từng mục, hãy thêm ?$orderBy=priority vào yêu cầu. Ví dụ,  http://localhost:5001/api/todo?$orderBy=priority.

Yêu cầu trên trả về dữ liệu sau:

[
    {
        "id": 1,
        "name": "Item1",
        "isComplete": false,
        "type": null,
        "priority": 0,
        "dueDate": "0001-01-01T00:00:00"
    },
    {
        "id": 3,
        "name": "test OData",
        "isComplete": false,
        "type": "work",
        "priority": 1,
        "dueDate": "2019-04-18T00:00:01"
    },
    {
        "id": 5,
        "name": "test 3",
        "isComplete": true,
        "type": "work",
        "priority": 1,
        "dueDate": "2019-04-18T09:00:01"
    },
    {
        "id": 2,
        "name": "test 5",
        "isComplete": false,
        "type": "work",
        "priority": 2,
        "dueDate": "2019-04-18T15:00:01"
    },
    {
        "id": 4,
        "name": "test 2",
        "isComplete": true,
        "type": "shopping",
        "priority": 2,
        "dueDate": "2019-04-18T08:00:01"
    },
    {
        "id": 6,
        "name": "test 4",
        "isComplete": false,
        "type": "shopping",
        "priority": 3,
        "dueDate": "2019-04-18T12:00:01"
    }
]

Dữ liệu có thể được sắp xếp dữ liệu dựa trên nhiều property. Ví dụ: ?$orderBy=type,priority desc" sắp xếp các mục dựa trên type và sau đó priority theo thứ tự giảm dần.

$filter

Tùy chọn $filter có thể tiêu tốn quá nhiều tài nguyên. Cân nhắc sử dụng [Queryable(AllowedQueryOptions=AllowedQueryOptions.{Option})] để vô hiệu hóa $filter. Xem Hướng dẫn bảo mật cho ASP.NET Core Web API OData để biết thêm thông tin.

$filter lọc dữ liệu dựa trên điều kiện boolean. Ví dụ: để chỉ nhận các mục có giá trị priority lớn hơn 1, hãy thêm ?$filter=priority gt 1 vào đường dẫn yêu cầu.

Yêu cầu trên trả về dữ liệu sau:

[
    {
        "id": 2,
        "name": "test 5",
        "isComplete": false,
        "type": "work",
        "priority": 2,
        "dueDate": "2019-04-18T15:00:01"
    },
    {
        "id": 4,
        "name": "test 2",
        "isComplete": true,
        "type": "shopping",
        "priority": 2,
        "dueDate": "2019-04-18T08:00:01"
    },
    {
        "id": 6,
        "name": "test 4",
        "isComplete": false,
        "type": "shopping",
        "priority": 3,
        "dueDate": "2019-04-18T12:00:01"
    }
]

Các điều kiện Boolean sau đây có thể được sử dụng với OData $filter:

Condition Mô t Ví dụ
eq Tương đương với $filter=priority eq 1
ne không bằng $filter=priority ne 1
gt Lớn hơn $filter=priority gt 1
ge Lớn hơn hoặc bằng $filter=priority ge 1
lt Ít hơn $filter=priority lt 1
le Nhỏ hơn hoặc bằng $filter=priority le 1
and logic and $filter=priority gt 1 and priority lt 10
or logic or $filter=priority gt 1 or priority lt 10
not logic not $filter=not endswith(name,'task')

Các hàm chuỗi có thể được sử dụng với OData $filter. Để biết thêm thông tin, hãy xem  phần Quy ước URI OData' $filter.

$skip

$skip bỏ qua các bản ghi được chỉ định. Ví dụ: để bỏ qua 4 mục đầu tiên, hãy thêm ?$skip=4 vào yêu cầu.

Yêu cầu trên trả về dữ liệu sau:

[
    {
        "id": 5,
        "name": "test 3",
        "isComplete": true,
        "type": "work",
        "priority": 1,
        "dueDate": "2019-04-18T09:00:01"
    },
    {
        "id": 6,
        "name": "test 4",
        "isComplete": false,
        "type": "shopping",
        "priority": 3,
        "dueDate": "2019-04-18T12:00:01"
    }
]

Truy vấn theo chuỗi

Các truy vấn theo chuỗi có thể tiêu tốn quá nhiều tài nguyên. Cân nhắc sử dụng [Queryable(AllowedQueryOptions=AllowedQueryOptions.{Option})] để vô hiệu hóa các hoạt động tốn kém. Cân nhắc giới hạn $orderby các property trong chỉ mục nhóm. Xem Hướng dẫn bảo mật cho ASP.NET Core Web API OData để biết thêm thông tin.

Các truy vấn OData có thể được xâu chuỗi để tạo một truy vấn phức tạp. Ví dụ: nối thêm ?$skip=2&$select=name,priority&$orderBy=priority desc&filter=priority gt 1 sẽ trả về dữ liệu sau:

[
    {
        "Name": "test 2",
        "priority": 2
    },
    {
        "Name": "test OData",
        "priority": 1
    },
    {
        "Name": "test 3",
        "priority": 1
    },
    {
        "Name": "Item1",
        "priority": 0
    }
]

Tài nguyên bổ sung

Nguồn: learn.microsoft.com
» Tiếp: Hướng dẫn bảo mật cho ASP.NET Core Web API OData
« Trước: Tạo API web với ASP.NET Core dựa trên controller
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!