Trong phần này sẽ tìm hiểu về Map ánh xạ URL request đến một Middleware xử lý, đọc các thông tin mà yêu cầu gửi đến server (Request), Xử lý upload file, đọc và ghi cookie, trả về nội dung Json.
- Tạo dự án ASP.NET Core, tích hợp Webpack
- Rẽ nhánh pipeline xử lý yêu cầu
- RequestDelegate và điểm cuối của pipeline
- Rẽ nhánh bởi EndpointMiddleware
- Rẽ nhánh truy vấn với IApplicationBuilder.Map
- Ứng dụng Route, tìm hiều Request, Response, Upload File, Cookies, Json
- Sử dụng Route
- Xây dựng lớp HtmlHelper
- Đọc thông tin HttpRequest
- Đọc thông Post từ Form HTML và xử lý Upload File
- Sử dụng HtmlEncoder
- Sử dụng Cookies
- Trả về Json
Tạo dự án thực hành - ứng dụng Web với .NET Core - sử dụng Webpack đóng gói CSS, JS
Để thực hành tạo lại dự án một ứng dụng Web với .NET Core, ứng dụng Web này là dạng cơ bản để tìm hiểu chi tiết về các nguyên lý
nên chưa sử dụng .NET Core MVC
. Tạo một thư mục lưu code dự án, ví dụ WebApp
, hãy vào
thư mục đó, gõ lệnh sau để tạo cấu trúc dự án
dotnet new web
Mở thư mục đó ra bằng Visual Studio Code (code .
), Tại VSC chọ menu View > Command Palette ...
rồi chọn .NET: Generate Assets for Build and Debug
để VSC sinh ra cấu hình build ở thư mục .vscode
Sử dụng Webpack để đóng gói JS, CSS, SCSS
Ở ví dụ trước bạn đã sử dụng BuildBundlerMinifier
để gộp CSS, JS. Tuy nhiên để linh hoạt hơn từ phần này
sẽ sử dụng Webpack
với .NET Core (về Webpack xem chi tiết tại:
Sử dụng Webpack
), sẽ thực hiện từng bước để tích hợp BootStrap, JQuery và một file nguồn SCSS tự động build thành CSS.
Gõ các lệnh sau
npm init -y # tạo file package.json cho dự án npm i -D webpack webpack-cli # cài đặt Webpack npm i node-sass postcss-loader postcss-preset-env # cài đặt các gói để làm việc với SCSS npm i sass-loader css-loader cssnano # cài đặt các gói để làm việc với SCSS, CSS npm i mini-css-extract-plugin cross-env file-loader # cài đặt các gói để làm việc với SCSS npm install copy-webpack-plugin # cài đặt plugin copy file cho Webpack npm install npm-watch # package giám sát file thay đổi npm install bootstrap # cài đặt thư viện bootstrap npm install jquery # cài đặt Jquery npm install popper.js # thư viện cần cho bootstrap
Sau các lệnh này các package trên được tải về lưu tại node_modules
, giờ đến bước cấu hình Webpack
để khi chạy nó có được mục đích sau:
- Copy
jquery.min.js
từ package jquery ra thư mụcwwwroot/js
- Copy
popper.min.js
từ package popper.js ra thư mụcwwwroot/js
- Copy
bootstrap.min.js
từ package bootstrap ra thư mụcwwwroot/js
- Biên dịch file
src/scss/site.scss
thành filewwww/css/site.min.css
(đã gộp cả CSS của Bootstrap)
src/scss/site.scss
có nội dung cơ bản như sau:
//Gộp Bootstrap // Có thể thiết lập các biến biến như màu $warning ... @import '../../node_modules/bootstrap/scss/bootstrap.scss'; // Thêm code SCSS .mainbackground { background-color: #673ab7; }
webpack.config.js
có nội dung cơ bản như sau:
Nội dung file webpack.config.js
package.json
- mở file này, đảm bảo thêm vào những dòng
bôi đậm sau:
{ /... "main": "index.js", "watch": { "build": "src/scss/site.scss" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "watch": "npm-watch" }, "keywords": [], /... }
Nội dung file đầy đủ tại Package.json
npm run buildNó sẽ sinh ra các file
.js, .css
tương ứng lưu ở wwwwroot/css
hay wwwroot/js
Hoặc nếu muốn, tự động mỗi khi cập nhật site.scss
thì Webpack tự chạy thì kích hoạt script
npm run watch
Startup
, phương thức Configure
,
cần có dòng code sau để truy cập được file tĩnh (nhờ middleware StaticFileMiddleware)app.UseStaticFiles();
Rẽ nhánh pipeline xử lý yêu cầu truy vấn
RequestDelegate và điểm cuối trong pipeline
Ở phần trước nói về Middleware Middleware và Pipeline C# NET CORE chúng ta đã biết khi một yêu cầu gửi đến ứng dụng thì một đối tượng HttpContext sẽ lần lượt đi qua các Middleware, tất nhiên nó có thể rẽ nhánh ở một Middleware nào đó, cho tới một Middleware cuối cùng.
RequestDelegate là một delegate có tham số là HttpContext bạn có thể tạo ra đối tượng này và cấu hình để nó trở thành điểm cuối của pipeline, điểm cuối của các nhánh trong pipeline. Ta thực hiện những điều này trong phương thức Configure của lớp Startup
Để có một phương thức kiểu RequestDelegate thường viết dưới dạng Anonymous như sau:
async (HttpContext context) => { /... code thi hành trong RequestDelegate } // Hoặc async (context) => { /... code thi hành trong RequestDelegate }
Trong đường pipeline bạn có thể thêm vào điểm cuối một RequestDelegate trong trường hợp không bị rẽ nhánh bởi EndpointMiddleware, ví dụ:
public void Configure (IApplicationBuilder app, IWebHostEnvironment env) { /.. các cấu hình khác // Điểm cuối của pipeline không bị rẽ nhánh, HttpContext đi qua tất cả các Middleware đến điểm cuối này // Thường là trường hợp yêu cầu truy vấn không đúng địa chỉ (not found)s app.Run (async (HttpContext context) => { context.Response.StatusCode = StatusCodes.Status404NotFound; await context.Response.WriteAsync ("Nội dung"); }); }
Phương thức IApplicationBuilder.Run để tạo một điểm cuối trong pipeline
Rẽ nhánh pipeline bởi EndpointMiddleware
EndpointRoutingMiddleware có chức năng phân tích yêu cầu gửi đến (Url, Method ...) và chuyển hướng yêu cầu đến một RequestDelegate phù hợp định nghĩa bởi endpoint - là điểm cuối của nhánh, có nghĩa tại đây pipeline có thể được chia ra nhiều nhánh.
Để đưa EndpointRoutingMiddleware là một điểm trong pipeline sửa dụng
app.UseRouting();
Sau khi đưa EndpointRoutingMiddleware vào pipeline, các điểm rẽ nhánh được định nghĩa bằng sử dụng phương thức IApplicationBuilder.UseEndpoints với cú pháp
app.UseEndpoints ((IEndpointRouteBuilder endpoints) => { // Tại đây là code, sử dụng endpoints (IEndpointRouteBuilder) tạo các điểm cuối // Hình thành lên các nhánh rẽ ra từ EndpointRoutingMiddleware });
IEndpointRouteBuilder có nhiều phương thức để tạo ra điều hướng tức là thêm vào các đối tượng lớp RouteEndpoint phù hợp với yêu cầu gửi đến, một vài trong số đó là:
-
Map(pattern, requestDelegate) : pattern là chuỗi với Url gửi đến, requestDelegate là RequestDelegate
thi hành. Ví dụy tạo RouteEndpoint phù hợp khi truy vấn đến địa chỉ
/Abc
endpoints.Map("/Abc", async httpcontext => { await httpcontext.Response.WriteAsync ("Truy cập /Abc"); });
Chuỗi
/Abc
định nghĩa là khi Url truy cập phù hợp với nó (bằng nó), tuy nhiên nó được định nghĩa còn phức tạp hơn gọi là các mẫu định tuyển (route template).Hãy xem ví dụ:
endpoints.Map("/product/{productid:int}", async httpcontext => { // Đọc giá trị productid gửi đến var idproduct = httpcontext.Request.RouteValues["productid"]; // Đọc giá trị Query var numberorder = httpcontext.Request.Query["order"]; await httpcontext.Response.WriteAsync ($"Sản phẩm {idproduct}, order = {numberorder}"); });
Với định nghĩa trên thì các url truy cập tới có dạng
/product/123
,/product/567?order=10
... là phù hợp với RouteEndpoint này. Trong đóproductid
là tên giá trị route nó như một biến,:int
là ràng buộc (cho biết productid phải là một số nguyên), bạn có thể viết nhiều dàng buộc liên tiếp nhau, dàng buộc rất phong phú như:alpha
,:regex
... - xem thêm tại: route-constraint-reference -
Các phương thức MapGet(pattern, requestDelegate),
MapDelete(pattern, requestDelegate),
MapPost(pattern, requestDelegate),
MapPut(pattern, requestDelegate)
có cách sử dụng tương tự Map, chỉ có điều khác là nó phù hợp với phương thức truy vấn đến cụ thể
get
,delete
,post
,put
-
MapMethods(pattern, httpMethods, requestDelegate) dùng khi muốn chỉ định chấp nhận các phương thức cụ thể khai báo trong danh sách httpMethods. Ví dụ, chấp nhận yêu cầu có phương thức
put
,delete
,post
:endpoints.MapMethods("/cart", new string[] {"put", "post", "delete"}, async context => { var method = context.Request.Method; await context.Response.WriteAsync ("Method: {method}"); });
Ngoài ra còn có các phương thức mở rộng khi dùng với MVC ... sẽ nói khi đến phần đó nhứ:
- IEndpointRouteBuilder.MapControllers - ánh xạ URL tới Controller - tìm hiểu ở các phần sau
- IEndpointRouteBuilder.MapRazorPages - ánh xạ URL tới trang Razor - tìm hiểu phần sau
Rẽ nhánh pipeline bởi IApplicationBuilder.Map
Bạn có thể tạo điểm rẽ nhánh trong pipeline bằng cách sử dụng trực tiếp phương thức Map trong IApplicationBuilder, điểm rẽ nhánh này tương tự cách sử dụng EndpointMiddleware ở trên. Cú pháp như sau:
app.Map(pathMatch, (IApplicationBuilder app) => { // Sử dụng app để xử lý yêu cầu, ví dụ tạo endpoint app.Run(async context => { await context.Response.WriteAsync ("Xin chào! (app.Map)"); }); });
Trong đó pathMatch
là chuỗi mẫu phù hợp cho Url
Ứng dụng Route, tìm hiều Request, Response, Upload File, Cookies, Json
Phần này ta sẽ xây dựng ứng dụng mẫu trên áp dụng các kỹ thuật Route đã trình bày, qua đó tìm hiểu thêm về HttpContext, HttpRequest, HttpReposee, thực hiệ upload file dữ liệu, sử dụng cookie và trả về nội dung JSON ...
Sử dụng Route xây dựng các địa chỉ Url gửi đến
Ứng dụng sẽ xây dựng với yêu cầu gồm các Urls nó phục vụ như sau:
URL | Chức năng |
---|---|
/RequestInfo |
Đọc và hiện thị các thông tin về Request truy cập |
/Encoding |
Demo tính năng encoding dữ liệu khi xuất HTML |
/Cookies |
Demo - Đọc và ghi cookie |
/Json |
Demo trả về dữ liệu JSON |
/Form |
Demo - Hiện thị Form HTML, xử lý đọc thông tin từ Form, kể cả xử lý upload file |
Với yêu cầu cho các Route trên là:
/RequestInfo
,/Encoding
,Cookies
được điều hướng bởiEndpointMiddleware /Json
và/Form
được điều hướng do rẽ nhánh bởi app.Map
Đáp ứng yêu cầu trên, trước mắt cấu trúc Route xây dựng được như sau:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace _03.RequestResponse { public class Startup { // Đăng ký các dịch vụ sử dụng bởi ứng dụng, services là một DI container public void ConfigureServices(IServiceCollection services) { services.AddDistributedMemoryCache(); services.AddSession(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure (IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment ()) { app.UseDeveloperExceptionPage (); } app.UseStaticFiles(); app.UseSession(); // Điều hướng route bởi EndpointMiddleware // Rẽ nhánh nếu Url phù hợp định nghĩa trong UseEndpoints, nếu không chuyển đến Middleware tiếp app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Trang chủ"); }); endpoints.Map("/RequestInfo", async context => { // xây dựng chức năng /RequestInfo ở đây await context.Response.WriteAsync("/RequestInfo"); }); endpoints.MapGet("/Encoding", async context => { // xây dựng chức năng Encoding ở đây await context.Response.WriteAsync("/Encoding"); }); endpoints.MapGet("/Cookies/{*action}", async context => { // xây dựng chức năng Cookies ở đây await context.Response.WriteAsync("/Cookies"); }); }); // Điểm rẽ nhánh pipeline khi URL là /Json app.Map("/Json", app => { app.Run(async context => { // code ở đây await context.Response.WriteAsync("/Json"); }); }); // Điểm rẽ nhánh pipeline khi URL là /Form app.Map("/Form", app => { app.Run(async context => { // code ở đây await context.Response.WriteAsync("/Form"); }); }); app.Run (async (HttpContext context) => { context.Response.StatusCode = StatusCodes.Status404NotFound; await context.Response.WriteAsync ("Page not found!"); }); } } }
Hãy truy cập các Url để kiểm tra
Xây dựng lớp tiện ích HtmlHelper
Để hỗ trợ sinh ra HTML nhanh chóng và có sử dụng Bootstrap trình bày, xây dựng lớp tĩnh với các
phương thức phát sinh HTML như sau: Tạo file HtmlHelper.cs
và định nghĩa lớp
như tại HtmlHelper.cs (copy code này và lưu lại).
Lớp tĩnh HtmlHelper xây dựng trên có vài phương thức để hỗ trợ sinh trang HTML nhanh hơn cho ví dụ này,
gồm:
HtmlHelper.HtmlDocument(string title, string content)
|
Trả về chuỗi HTML của trang, content là phần nằm trong thẻ body, trang đã tích hợp CSS Bootstrap |
String.HtmlTag(string tag = "p", string _class = null) |
Tạo thẻ, nội dung trong thẻ chuỗi gốc. |
Ngoài ra còn có các phương thức như: MenuTop
, DefaultMenuTopItems
, HtmlTrangchu
...
xem chi tiết trong mã nguồn
Mở Startup
, cập nhật ánh xạ khi truy cập trang chủ theo url là /
/.. app.UseEndpoints (endpoints => { /.. endpoints.MapGet ("/", async context => { string menu = HtmlHelper.MenuTop (HtmlHelper.DefaultMenuTopItems (), context.Request); string content = HtmlHelper.HtmlTrangchu (); string html = HtmlHelper.HtmlDocument ("Trang chủ", menu + content); await context.Response.WriteAsync (html); }); /.. } /..
Gõ lệnh dotnet run
, kiểm tra http://localhost:5000
Trang trên có dùng Bootstrap, nên giao diện của nó cũng responsive
(thay đổi phù hợp kích thức màn hình)
Đọc thông tin HttpRequest cơ bản
Tra truy vấn đến trang web, thông tin của nó sẽ chứa trong đối tượng lớp HttpRequest
,
đối tượng này lấy được từ HttpContext là tham số của RequestDelegate. Từ đối tượng lớp HttpRequest
chỉ việc đọc các thuộc tính, ta sẽ biết được thông tin request như: Phương thức gì (POST, GET, UPDATE ...),
Path, Query ...
Xây dựng một lớp, để đọc thông tin này như sau - lớp tĩnh đặt tên là RequestProcess
,
đầu tiên là định nghĩa phương thức RequestInfo
:
using System.Linq; using System.Text; using Microsoft.AspNetCore.Http; namespace _03.RequestResponse { public static class RequestProcess { // Đọc các thông tin cơ bản của Request // Trả về HTML trình bày các thông tin đó public static string RequestInfo(HttpRequest request) { var sb = new StringBuilder(); // Lấy http scheme (http|https) var scheme = request.Scheme; sb.Append(("scheme".td() + scheme.td()).tr()); // HOST Header var host = (request.Host.HasValue ? request.Host.Value : "no host"); sb.Append(("host".td() + host.td()).tr()); // Lấy pathbase (URL Path - cho Map) var pathbase = request.PathBase.ToString(); sb.Append(("pathbase".td() + pathbase.td()).tr()); // Lấy Path (URL Path) var path = request.Path.ToString(); sb.Append(("path".td() + path.td()).tr()); // Lấy chuỗi query của URL var QueryString = request.QueryString.HasValue ? request.QueryString.Value : "no query string"; sb.Append(("QueryString".td() + QueryString.td()).tr()); // Lấy phương thức var method = request.Method; sb.Append(("Method".td() + method.td()).tr()); // Lấy giao thức var Protocol = request.Protocol; sb.Append(("Protocol".td() + Protocol.td()).tr()); // Lấy ContentType var ContentType = request.ContentType; sb.Append(("ContentType".td() + ContentType.td()).tr()); // Lấy danh sách các Header và giá trị của nó, dùng Linq để lấy // Header gửi đến lưu trong thuộc tính Header kiểu Dictionary var listheaderString = request.Headers.Select((header) => $"{header.Key}: {header.Value}".HtmlTag("li")); var headerhmtl = string.Join("", listheaderString).HtmlTag("ul"); // nối danh sách thành 1 sb.Append(("Header".td() + headerhmtl.td()).tr()); // Lấy danh sách các Header và giá trị của nó, dùng Linq để lấy var listcokie = request.Cookies.Select((header) => $"{header.Key}: {header.Value}".HtmlTag("li")); var cockiesHtml = string.Join("", listcokie).HtmlTag("ul"); sb.Append(("Cookies".td() + cockiesHtml.td()).tr()); // Lấy tên và giá trí query var listquery = request.Query.Select((header) => $"{header.Key}: {header.Value}".HtmlTag("li")); var queryhtml = string.Join("", listquery).HtmlTag("ul"); sb.Append(("Các Query".td() + queryhtml.td()).tr()); //Kiểm tra thử query tên abc có không Microsoft.Extensions.Primitives.StringValues abc; bool existabc = request.Query.TryGetValue("abc", out abc); string queryVal = existabc ? abc.FirstOrDefault() : "không có giá trị"; sb.Append(("abc query".td() + queryVal.ToString().td()).tr()); string info = "Thông tin Request".HtmlTag("h2") + sb.ToString().HtmlTag("table", "table table-sm table-bordered"); return info; } } }
Tiếp theo, mở lớp Startup
thêm vào RequestDelegate - chuyên xử lý Url truy vấn /RequestInfo
thì gọi đến RequestInfo
ở trên để lấy HTML chứa thông tin Request
app.UseEndpoints(endpoints => { /.. endpoints.Map ("/RequestInfo", async context => { string menu = HtmlHelper.MenuTop (HtmlHelper.DefaultMenuTopItems (), context.Request); string requestinfo = RequestProcess.RequestInfo (context.Request).HtmlTag ("div", "container"); string html = HtmlHelper.HtmlDocument ("Thông tin Request", (menu + requestinfo)); await context.Response.WriteAsync (html); }); /.. });
Truy cập http://localhost:5000/RequestInfo/abc/xyz?id=10
Đọc thông Post từ Form HTML và xử lý Upload File
Trước tiên tạo một file formtest.html
chứa Form sẽ hiện thị, nội dung file đó như sau:
Form Test
(lưu file này lại).
Nó sẽ được đọc vào bằng phương thức File.ReadAllTextAsync("formtest.html")
khi cần nội dung của nó.
Khi Form submit, dữ liệu Form gửi đến biểu diễn bằng đối tượng kiểu IFormCollection
tại
thuộc tính HttpRequest.Form
Từ đối tượng này để đọc một dữ liệu có tên trên Form HTML nào đó thì sử dụng indexer để truy cập,
ví dụ lấy giá trị phần tử Form tên abc
var abc = _form["abc"].FirstOrDefault() ?? null;
Đối với file, thì các file upload lưu tại thuộc tính HttpRequest.Files
,
nó là danh sách các phần tử kiểu IFormFile
- có thể duyệt qua Files
để xử lý tất cả các file upload đến.
Từ đối tượng IFormFile
, toàn bộ dữ liệu file có thể chuyển vào một stream (file trên server, hay bộ nhớ ..
tùy cách tạo ra stream) bằng
IFormFile.CopyToAsync(stream);
Tiếp tục, xây dựng phương thức FormProcess
để xử lý khi Form gửi đến (submit) như sau:
public static class RequestProcess { /.. // Xử lý khi HTML Form post dữ liệu public static async Task<string> FormProcess(HttpRequest request) { //Xử lý đọc dữ liệu Form - khi post - dữ liệu này trình bày trên Form string hovaten = ""; bool luachon = false; string email = ""; string password = ""; string thongbao = ""; // Đọc dữ liệu từ Form do truy vấn gửi đến (chỉ xử lý khi là post) if (request.Method == "POST") { IFormCollection _form = request.Form; email = _form["email"].FirstOrDefault() ?? ""; hovaten = _form["hovaten"].FirstOrDefault() ?? ""; password = _form["password"].FirstOrDefault() ?? ""; luachon = (_form["luachon"].FirstOrDefault() == "on"); thongbao = $@"Dữ liệu post - email: {email} - hovaten: {hovaten} - password: {password} - luachon: {luachon} "; // var filePath = Path.GetTempFileName(); // Xử lý nếu có file upload (hình ảnh, ... ) if (_form.Files.Count > 0) { string thongbaofile = "Các file đã upload: "; foreach (IFormFile formFile in _form.Files) { if (formFile.Length > 0) { var filePath = "wwwroot/upload/"+formFile.FileName; // Lấy tên file if (!Directory.Exists("wwwroot/upload/")) Directory.CreateDirectory("wwwroot/upload/"); thongbaofile += $"{filePath} {formFile.Length} bytes"; using (var stream = new FileStream(filePath, FileMode.Create)) // Mở stream để lưu file, lưu file ở thư mục wwwroot/upload/ { await formFile.CopyToAsync(stream); } } } thongbao += "<br>" + thongbaofile; } } string format = await File.ReadAllTextAsync("formtest.html"); // Đọc nội dung HTML từ file string formhtml = string.Format(format, hovaten, email, luachon ? "checked" : ""); return formhtml + thongbao; } /.. }
Tiếp theo, mở lớp Startup
thêm vào:
// Điểm rẽ nhánh pipeline khi URL là /Form app.Map ("/Form", app => { app.Run (async context => { string menu = HtmlHelper.MenuTop (HtmlHelper.DefaultMenuTopItems (), context.Request); string formhtml = await RequestProcess.FormProcess (context.Request); formhtml = formhtml.HtmlTag ("div", "container"); string html = HtmlHelper.HtmlDocument ("Form Post", (menu + formhtml)); await context.Response.WriteAsync (html); }); });
Truy cập http://localhost:5000/Form
, điền thông tin và chọn file rồi bấm Submit kiểm tra:
Chú ý: mặc định kích thước file lớn nhất cho Upload là 30MB, nếu muốn điều chỉnh thì điều chỉnh
tại lớp Program
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>() .UseKestrel(options => { options.Limits.MaxRequestBodySize = 104857600; // 100 MB - Cho phép upload }); });
Sử dụng HtmlEncoder trong C#
Khi dữ liệu xuất không thuộc cấu trúc HTML đã kiểm duyệt, bạn cần encode để an toàn, hoặc
bạn muốn in các chuỗi với những ký tự như <
, >
...
Để Encode chuỗi nào đó, sử dụng
stringencode = HtmlEncoder.Default.Encode(stringvalue);
Tiếp tục cho phương thức sau vào lớp RequestProcess
public static string Encoding(HttpRequest request) { Microsoft.Extensions.Primitives.StringValues data; bool existdatavalue = request.Query.TryGetValue("data", out data); string datavalue = existdatavalue ? data.FirstOrDefault() : "không có giá trị"; Microsoft.Extensions.Primitives.StringValues e; bool existevalue = request.Query.TryGetValue("e", out e); string evalue = existevalue ? e.FirstOrDefault() : "không có giá trị"; string dataout; if (evalue == "0") { // Không encode dữ liệu xuất dataout = datavalue; } else { // encode dữ liệu xuất dataout = HtmlEncoder.Default.Encode(datavalue); } string encoding_huongdan = File.ReadAllText("encoding.html"); return dataout.HtmlTag("div", "alert alert-danger") + encoding_huongdan; }
Trong đó, file encoding.html
có nội dung:
encoding.html
Startup
app.UseEndpoints(endpoints => { /.. endpoints.MapGet ("/Encoding", async context => { string menu = HtmlHelper.MenuTop (HtmlHelper.DefaultMenuTopItems (), context.Request); string htmlec = RequestProcess.Encoding (context.Request).HtmlTag ("div", "container"); string html = HtmlHelper.HtmlDocument ("Encoding", (menu + htmlec)); await context.Response.WriteAsync (html); }); /.. });
Sử dụng Cookie
Định nghĩa về Cookie xem tại Cookie
Phương thức sau thêm vào lớp RequestProcess, có lưu và đọc Cookie
public static string Cookies(HttpRequest request, HttpResponse response) { string tb = ""; switch (request.Path) { case "/Cookies/read": var listcokie = request.Cookies.Select((header) => $"{header.Key}: {header.Value}".HtmlTag("li")); tb = string.Join("", listcokie).HtmlTag("ul"); break; case "/Cookies/write": response.Cookies.Append("masanpham", "12345", new CookieOptions { Path = "/Cookies", Expires = DateTime.Now.AddDays(1)} ); tb = "Đã lưu Cookie - masanpham - hết hạn 1 ngày".HtmlTag("div", "alert alert-danger"); break; } string cookies_huongdan = File.ReadAllText("cookies.html"); return tb + cookies_huongdan; }
File cookies.html
có nội dung cookies.html
Startup
app.UseEndpoints(endpoints => { /.. endpoints.MapGet("/Cookies/{*action}", async (context) => { string menu = HtmlHelper.MenuTop(HtmlHelper.DefaultMenuTopItems(), context.Request); string cookies = RequestProcess.Cookies(context.Request, context.Response).HtmlTag("div", "container"); string html = HtmlHelper.HtmlDocument("Đọc / Ghi Cookies", (menu + cookies)); await context.Response.WriteAsync(html); }); /.. });
Trả về nội dung Json
Trả về nội dung Json (nhất là khi xây dựng cá API ứng dụng), để làm việc với Json thì cần cài đặt
thêm Newtonsoft.Json
dotnet add package Newtonsoft.Json
Sau đó để sử dụng cần nạp namespace
using Newtonsoft.Json;
Ở đây, để chuyển đối tượng lớp vô danh thành Json thì làm như sau với JsonConvert.SerializeObject
:
public static string GetJson() { var productjson = new { name = "IPhone 11", price = 1000 }; return JsonConvert.SerializeObject(productjson); }
Một Respone thiết lập cho biết nó trả về Json thì cần gán ContentType
của Response bằng "application/json"
Startup
// Điểm rẽ nhánh pipeline khi URL là /Json app.Map ("/Json", app => { app.Run (async context => { string Json = RequestProcess.GetJson(); context.Response.ContentType = "application/json"; await context.Response.WriteAsync(Json); }); });
Chú ý, với .NET Core 3.0 có hỗ trợ xử lý JSON mà không cần cài đặt thêm các Package.
Ví dụ System.Text.Json.JsonSerializer.Serialize(productjson)
tương đương với JsonConvert.SerializeObject(productjson)
ở trên.
Mã nguồn ASP_NET_CORE/03.RequestResponse hoặc tải về tại ex049