1、Corecss
1,防止過分發布html
2,Mainjquery
3,Startupweb
4,添加過濾器ajax
5,依賴注入正則表達式
6,中間件sql
7,靜態文件數據庫
8,路由json
9,環境bootstrap
①TryUpdateModelAsync
public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } var emptyStudent = new Student(); if (await TryUpdateModelAsync<Student>(emptyStudent, "student", s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate)) { _context.Students.Add(emptyStudent); await _context.SaveChangesAsync(); return RedirectToPage("./Index"); } return null; }
[BindProperty] public Student Student { get; set; } public async Task<IActionResult> OnPostAsync(int? id) { if (!ModelState.IsValid) { return Page(); } var studentToUpdate =await _context.Students.FindAsync(id); if (await TryUpdateModelAsync<Student>(studentToUpdate, "student", s => s.LastName, s => s.EnrollmentDate)) { await _context.SaveChangesAsync(); return RedirectToPage("./Index"); } return Page(); }
僅更新TryUpdateModelAsync列出的值
在上述示例中:
"student", // Prefix
) 是用於查找值的前綴。 該自變量不區分大小寫。Student
模型中的類型。②經過屬性名稱匹配
using System; namespace ContosoUniversity.Models { public class StudentVM { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } } }
[BindProperty] public StudentVM StudentVM { get; set; } public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } var entry = _context.Add(new Student()); entry.CurrentValues.SetValues(StudentVM); await _context.SaveChangesAsync(); return RedirectToPage("./Index"); }
using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; namespace aspnetcoreapp { public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); } }
UseHttpSys:用於在 HTTP.sys 中託管應用
UseContentRoot:用於指定根內容目錄
Build
和 Run
方法生成 IWebHost
對象,該對象託管應用並開始偵聽 HTTP 請求
UseStartup:指定Startup
類
ConfigureServices
定義應用所使用的服務(如 ASP.NET Core MVC、Entity Framework Core 和Identity)(可選擇)
Configure
定義請求管道的中間件(必須)
ConfigureServices在 Configure以前執行
UseMvc
擴展方法將路由中間件添加到請求管道,並將 MVC 配置爲默認設置。
①定義Middleware
using System; using System.Net; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using WebApplication1.Models; namespace WebApplication1 { public class RequestSetOptionsMiddleware { private readonly RequestDelegate _next; private IOptions<AppOptions> _injectedOptions; public RequestSetOptionsMiddleware( RequestDelegate next, IOptions<AppOptions> injectedOptions) { _next = next; _injectedOptions = injectedOptions; } public async Task Invoke(HttpContext httpContext) { Console.WriteLine("RequestSetOptionsMiddleware.Invoke"); var option = httpContext.Request.Query["option"]; if (!string.IsNullOrWhiteSpace(option)) { _injectedOptions.Value.Option = WebUtility.HtmlEncode(option); } await _next(httpContext); } } }
②實現IStartupFilter
using Microsoft.AspNetCore.Hosting; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; namespace WebApplication1 { public class RequestSetOptionsStartupFilter : IStartupFilter { public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next) { return builder => { builder.UseMiddleware<RequestSetOptionsMiddleware>(); next(builder); }; } } }
③在 ConfigureServices
的服務容器中註冊 IStartupFilter
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddTransient<IStartupFilter, RequestSetOptionsStartupFilter>(); services.AddMvc(); }
①註冊案例
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(options => options.UseInMemoryDatabase() ); // Add framework services. services.AddMvc(); // Register application services. services.AddScoped<ICharacterRepository, CharacterRepository>(); services.AddTransient<IOperationTransient, Operation>(); services.AddScoped<IOperationScoped, Operation>(); services.AddSingleton<IOperationSingleton, Operation>(); services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty)); services.AddTransient<OperationService, OperationService>(); }
①中間件排序
②Use、Run 和 Map
Run:不會調用next方法。後面的管道將不會執行
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.Run(async (context)=>{ await context.Response.WriteAsync("Map Test 1"); }); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } //使用wwwroot app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
Use:若是中間件不調用next方法,會使管道短路。
Map:若是請求路徑以給定路徑開頭,則執行分支。
public class Startup { private static void HandleMapTest1(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Map Test 1"); }); } private static void HandleMapTest2(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Map Test 2"); }); } public void Configure(IApplicationBuilder app) { app.Map("/map1", HandleMapTest1); app.Map("/map2", HandleMapTest2); app.Run(async context => { await context.Response.WriteAsync("Hello from non-Map delegate. <p>"); }); } }
public class Startup { private static void HandleBranch(IApplicationBuilder app) { app.Run(async context => { var branchVer = context.Request.Query["branch"]; await context.Response.WriteAsync($"Branch used = {branchVer}"); }); } public void Configure(IApplicationBuilder app) { app.MapWhen(context => context.Request.Query.ContainsKey("branch"), HandleBranch); app.Run(async context => { await context.Response.WriteAsync("Hello from non-Map delegate. <p>"); }); } }
app.Map("/level1", level1App => { level1App.Map("/level2a", level2AApp => { // "/level1/level2a" //... }); level1App.Map("/level2b", level2BApp => { // "/level1/level2b" //... }); });
app.Map("/level1/level2", HandleMultiSeg);
③自定義Middleware
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using System.Globalization; using System.Threading.Tasks; namespace IocDemo { public class CustomMiddleware { private readonly RequestDelegate _next; public CustomMiddleware(RequestDelegate next) { _next=next; } public Task InvokeAsync(HttpContext context) { this._next.Invoke(context); context.Response.WriteAsync("CustomMiddleware"); return Task.CompletedTask; } } public static class CustomMiddlewareExtensions { public static IApplicationBuilder UseCustomer(this IApplicationBuilder budiler) { return budiler.UseMiddleware<CustomMiddleware>(); } } }
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.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace IocDemo { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } //使用自定義middleware app.UseCustomer(); //使用wwwroot app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }
①提供 Web 根目錄外的文件
請求 http://<server_address>/StaticFiles/images/banner1.svg 提供 banner1.svg 文件
public void Configure(IApplicationBuilder app) { app.UseStaticFiles(); // For the wwwroot folder app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")), RequestPath = "/StaticFiles" }); }
②設置 HTTP 響應標頭
public void Configure(IApplicationBuilder app) { app.UseStaticFiles(new StaticFileOptions { OnPrepareResponse = ctx => { // Requires the following import: // using Microsoft.AspNetCore.Http; ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=600"); } }); }
③靜態文件受權方法
新建個靜態文件根文件夾
[Authorize] public IActionResult BannerImage() { var file = Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles", "images", "banner1.svg"); return PhysicalFile(file, "image/svg+xml"); }
④默認提供文檔
public void Configure(IApplicationBuilder app) { app.UseDefaultFiles(); app.UseStaticFiles(); }
要提供默認文件,必須在 UseStaticFiles
前調用 UseDefaultFiles
。 UseDefaultFiles
實際上用於重寫 URL,不提供文件。 經過 UseStaticFiles
啓用靜態文件中間件來提供文件。
public void Configure(IApplicationBuilder app) { // Serve my app-specific default file, if present. DefaultFilesOptions options = new DefaultFilesOptions(); options.DefaultFileNames.Clear(); options.DefaultFileNames.Add("mydefault.html"); app.UseDefaultFiles(options); app.UseStaticFiles(); }
routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id:int}");
①尾隨句點 . 是可選: files/{filename}.{ext?}
②*全方位參數: blog/{*slug}
將匹配以 /blog
開頭且其後帶有任何值(將分配給 slug
路由值)的 URI
ASP.NET Core 在應用程序啓動時讀取環境變量 ASPNETCORE_ENVIRONMENT(若是未設置
ASPNETCORE_ENVIRONMENT
,將默認爲 Production
)
ASPNETCORE_ENVIRONMENT值:
nuget Microsoft.Extensions.Configuration
①讀取json文件
nuget Microsoft.Extensions.Configuration.Json
using System; using System.IO; // Requires NuGet package // Microsoft.Extensions.Configuration.Json using Microsoft.Extensions.Configuration; public class Program { public static IConfiguration Configuration { get; set; } public static void Main(string[] args = null) { var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); Configuration = builder.Build(); Console.WriteLine($"option1 = {Configuration["Option1"]}"); Console.WriteLine($"option2 = {Configuration["option2"]}"); Console.WriteLine( $"suboption1 = {Configuration["subsection:suboption1"]}"); Console.WriteLine(); Console.WriteLine("Wizards:"); Console.Write($"{Configuration["wizards:0:Name"]}, "); Console.WriteLine($"age {Configuration["wizards:0:Age"]}"); Console.Write($"{Configuration["wizards:1:Name"]}, "); Console.WriteLine($"age {Configuration["wizards:1:Age"]}"); Console.WriteLine(); Console.WriteLine("Press a key..."); Console.ReadKey(); } }
{ "option1": "value1_from_json", "option2": 2, "subsection": { "suboption1": "subvalue1_from_json" }, "wizards": [ { "Name": "Gandalf", "Age": "1000" }, { "Name": "Harry", "Age": "17" } ] }
節點由冒號 : 分隔: Configuration["subsection:suboption1"]
獲取數組值: Configuration["wizards:0:Name"]
②讀取xml文件
nuget Microsoft.Extensions.Configuration.Xml
using System; using Microsoft.Extensions.Configuration; using System.IO; namespace ConsoleDemo { class Program { static void Main(string[] args) { var builder= new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddXmlFile("test.xml"); var configuration=builder.Build(); Console.WriteLine(configuration["wizard:Harry:age"]); } } }
<wizards> <wizard name="Gandalf"> <age>1000</age> </wizard> <wizard name="Harry"> <age>17</age> </wizard> </wizards>
③json綁定到對象裏面
nuget Microsoft.Extensions.Configuration.Binder
using System; using Microsoft.Extensions.Configuration; using System.IO; using System.Collections.Generic; namespace ConsoleDemo { class Program { static void Main(string[] args) { var dic=new Dictionary<string,string>(); dic.Add("Person:Name","hunter"); dic.Add("Person:Age","10"); var builder=new ConfigurationBuilder() .AddInMemoryCollection(dic); IConfiguration configuration=builder.Build(); var person=new Person(); configuration.GetSection("Person").Bind(person); Console.WriteLine(person.Name); Console.WriteLine(person.Age); } } public class Person{ public string Name{get;set;} public int Age{get;set;} } }
④在razor視圖獲取mvc視圖中使用configuration
@page @model IndexModel @using Microsoft.Extensions.Configuration @inject IConfiguration Configuration <!DOCTYPE html> <html lang="en"> <head> <title>Index Page</title> </head> <body> <h1>Access configuration in a Razor Pages page</h1> <p>Configuration["key"]: @Configuration["key"]</p> </body> </html>
@using Microsoft.Extensions.Configuration @inject IConfiguration Configuration <!DOCTYPE html> <html lang="en"> <head> <title>Index View</title> </head> <body> <h1>Access configuration in an MVC view</h1> <p>Configuration["key"]: @Configuration["key"]</p> </body> </html>
④注入option配置
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"Option":{
"option1":"value1_from_json",
"option2":-1
}
}
public class MyOption{
public string option1{get;set;}
public int option2{get;set;}
}
services.Configure<MyOption>(Configuration.GetSection("Option"));
private IOptions<MyOption> _option; public BlogController(IOptions<MyOption> option) { _option=option; _option.Value.option1+_option.Value.option2 }
①建立日誌
nuget Microsoft.Extensions.Logging
public class TodoController : Controller { private readonly ITodoRepository _todoRepository; private readonly ILogger _logger; public TodoController(ITodoRepository todoRepository, ILogger<TodoController> logger) { _todoRepository = todoRepository; _logger = logger; }
public IActionResult GetById(string id) { _logger.LogInformation(LoggingEvents.GetItem, "Getting item {ID}", id); var item = _todoRepository.Find(id); if (item == null) { _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({ID}) NOT FOUND", id); return NotFound(); } return new ObjectResult(item); }
②事件ID
LoggingEvents本身定義例如:
public class LoggingEvents { public const int GenerateItems = 1000; public const int ListItems = 1001; public const int GetItem = 1002; public const int InsertItem = 1003; public const int UpdateItem = 1004; public const int DeleteItem = 1005; public const int GetItemNotFound = 4000; public const int UpdateItemNotFound = 4001; }
public IActionResult GetById(string id) { _logger.LogInformation(LoggingEvents.GetItem, "Getting item {ID}", id); var item = _todoRepository.Find(id); if (item == null) { _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({ID}) NOT FOUND", id); return NotFound(); } return new ObjectResult(item); }
using Microsoft.AspNetCore.Http
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; namespace MvcDemo { public class Startup { public Startup(IConfiguration configuration, IHostingEnvironment env) { Configuration = configuration; HostingEnvironment=env; } public IConfiguration Configuration { get; } public IHostingEnvironment HostingEnvironment{get;} // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { var physicalProvider= HostingEnvironment.ContentRootFileProvider; services.AddSingleton<IFileProvider>(physicalProvider); services.AddSession(option=>{ option.IdleTimeout=TimeSpan.FromSeconds(10); option.Cookie.HttpOnly=true;//指示客戶端腳本是否能夠訪問cookie。 }); services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseSession();//要在UseMvc以前調用 app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using MvcDemo.Models; using Microsoft.Extensions.FileProviders; using Microsoft.AspNetCore.Http; namespace MvcDemo.Controllers { public class SesstionController : Controller { public string Index(string str) { HttpContext.Session.SetString("str",str); return "sesstion已經設置"; } public string GetSession() { var val= HttpContext.Session.GetString("str"); return val; } } }
nuget OrchardCore.Localization.Core
①配置Startup
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; namespace MvcDemo { public class Startup { public Startup(IConfiguration configuration, IHostingEnvironment env) { Configuration = configuration; HostingEnvironment=env; } public IConfiguration Configuration { get; } public IHostingEnvironment HostingEnvironment{get;} // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { var physicalProvider= HostingEnvironment.ContentRootFileProvider; services.AddSingleton<IFileProvider>(physicalProvider); services.AddSession(option=>{ option.IdleTimeout=TimeSpan.FromSeconds(10); option.Cookie.HttpOnly=true;//指示客戶端腳本是否能夠訪問cookie。 }); services.AddLocalization(option=>{ }); services.AddMvc() .AddViewLocalization(); services.AddPortableObjectLocalization(options=>{ options.ResourcesPath="Localization"; }); services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("en"), new CultureInfo("fr-FR"), new CultureInfo("fr"), new CultureInfo("zh-CHS") }; options.DefaultRequestCulture = new RequestCulture("zh-CHS"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseSession();//要在UseMvc以前調用 app.UseStaticFiles(); app.UseRequestLocalization(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }
②使應用內容可本地化
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using MvcDemo.Models; using Microsoft.Extensions.Localization; using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNetCore.Builder; using System.Globalization; using Microsoft.AspNetCore.Localization; namespace MvcDemo.Controllers { public class LocalizationController : Controller { private readonly IStringLocalizer<LocalizationController> _localization; public LocalizationController(IStringLocalizer<LocalizationController> localization) { _localization=localization; } public string Index() { return _localization["Localization"]; } public string Get() { return _localization["Test{0}",1]; } } }
③視圖本地化
@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ ViewData["Title"] = "Home Page"; } <p>@Localizer["Localization"]</p> <p>@Localizer["Test{0}",1]</p>
④DataAnnotations本地化
⑤po文件
msgid "Localization" msgstr "Localization" msgid "Home" msgstr "Home" msgid "Test{0}" msgstr "Test{0}"
msgid "Localization" msgstr "本地化" msgid "Home" msgstr "主頁" msgid "Test{0}" msgstr "測試{0}"
msgid:鍵
msgstr:值
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNetCore.Owin; using System.Text; using System.IO; using System.Globalization; namespace AspNetCoreOwin { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseOwin(pipeline=>{ pipeline(next=>OwinHello); }); app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } public Task OwinHello(IDictionary<string,object> environment) { string responseText="hello owin"; byte[] responseBytes=Encoding.UTF8.GetBytes(responseText); var responseStream=(Stream)environment["owin.ResponseBody"]; var responseHeaders=(IDictionary<string,string[]>)environment["owin.ResponseHeaders"]; responseHeaders["Content-Length"]=new string[]{responseBytes.Length.ToString(CultureInfo.InvariantCulture)}; responseHeaders["Content-Type"]=new string[] {"text/plain"}; return responseStream.WriteAsync(responseBytes,0,responseBytes.Length); } } }
案例下載:https://pan.baidu.com/s/1FLfBuqsMuKnv7wSF3BSW4w
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNetCore.WebSockets; using System.Net.WebSockets; using Microsoft.AspNetCore.Http; using System.Threading; using System.Collections.Concurrent; namespace WebSocketsDemo { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseDefaultFiles(); app.UseStaticFiles(); var webSocketOption=new WebSocketOptions() { KeepAliveInterval=TimeSpan.FromSeconds(120),//向客戶端發送「ping」幀的頻率,以確保代理保持鏈接處於打開狀態 ReceiveBufferSize=4*1024//用於接收數據的緩衝區的大小 }; app.UseWebSockets(webSocketOption); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); app.Use(async (context,next)=>{ if(context.Request.Path=="/ws") { if(context.WebSockets.IsWebSocketRequest)//判斷是不是websocket請求 { //將TCP鏈接升級到WebSocket鏈接,並提供websocket對象 WebSocket webSocket=await context.WebSockets.AcceptWebSocketAsync(); WebSockets.TryAdd(webSocket,"1"); await Echo(context,webSocket); } else { context.Response.StatusCode=400; } } else { await next(); } }); } private async Task Echo(HttpContext context,WebSocket websocket) { var buffer=new byte[4*1024]; WebSocketReceiveResult result=await websocket.ReceiveAsync(new ArraySegment<byte>(buffer),CancellationToken.None); while(!result.CloseStatus.HasValue) { //廣播 foreach(var ws in WebSockets) { if(!ws.Key.CloseStatus.HasValue) { await ws.Key.SendAsync(new ArraySegment<byte>(buffer,0,buffer.Length),result.MessageType,result.EndOfMessage,CancellationToken.None); } else { string value; WebSockets.TryRemove(ws.Key,out value); } //await ws.SendAsync(new ArraySegment<byte>(buffer,0,buffer.Length),result.MessageType,result.EndOfMessage,CancellationToken.None); } result=await websocket.ReceiveAsync(new ArraySegment<byte>(buffer),CancellationToken.None); } await websocket.CloseAsync(result.CloseStatus.Value,result.CloseStatusDescription,CancellationToken.None); } //能夠開一個線程去檢測WebSocket是否掉線,掉線則從字典中刪除 private static ConcurrentDictionary<WebSocket,string> WebSockets=new ConcurrentDictionary<WebSocket,string>(); } }
<!doctype html> <html lang="en"> <head> <title>Title</title> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <script src="lib/jquery/dist/jquery.min.js"></script> </head> <body> <input type="text" id="message"/><input type="button" id="send" value="發送"/> <div id="context"></div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> </body> <script> var ws; if("WebSocket" in window) { ws=new WebSocket("ws://localhost:5000/ws"); ws.onopen=function(){ alert("開始") } ws.onmessage=function(res){ $("#context").append(res.data+"<br/>") } ws.onclose=function(){ alert("退出") } } else { alert("不支持websocket"); } $(function(){ $("#send").click(function(){ ws.send($("#message").val()) }) }) </script> </html>
案例下載:https://pan.baidu.com/s/1C5CLrtD6Mr66oiM7sfEHaw
nuget Microsoft.Extensions.Caching.Memory
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.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Caching; namespace CacheDemo { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMemoryCache(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using CacheDemo.Models; using Microsoft.Extensions.Caching.Memory; namespace CacheDemo.Controllers { public class HomeController : Controller { private IMemoryCache _cache; public HomeController(IMemoryCache cache) { _cache=cache; } public IActionResult Index() { DateTime date; if(_cache.TryGetValue("date",out date)) { ViewData["date"]=date; } else { ViewData["date"]="未設置緩存"; } return View(); } public IActionResult Set() { _cache.Set<DateTime>("date",DateTime.Now); return RedirectToAction("Index"); } } }
案例下載:https://pan.baidu.com/s/1DEpF-_HLlEQFWswPyb-WkA
使上下文加載 Student.Enrollments
導航屬性,並在每一個註冊中加載 Enrollment.Course
導航屬性
public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public Grade? Grade { get; set; } public Course Course { get; set; } public Student Student { get; set; } } public class Course { //主鍵 [DatabaseGenerated(DatabaseGeneratedOption.None)] public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } public ICollection<Enrollment> Enrollments { get; set; } }
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<SchoolContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddMvc(); }
配置鏈接字符串
{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity1;ConnectRetryCount=0;Trusted_Connection=True;MultipleActiveResultSets=true" }, "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" } } }
ConnectRetryCount=0
來防止 SQLClient 掛起
using ContosoUniversity.Models; using System; using System.Linq; namespace ContosoUniversity.Data { public static class DbInitializer { public static void Initialize(SchoolContext context) { context.Database.EnsureCreated(); // Look for any students. if (context.Students.Any()) { return; // DB has been seeded } var students = new Student[] { new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")}, new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")}, new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")}, new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")}, new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")}, new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")}, new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")}, new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")} }; foreach (Student s in students) { context.Students.Add(s); } context.SaveChanges(); var courses = new Course[] { new Course{CourseID=1050,Title="Chemistry",Credits=3}, new Course{CourseID=4022,Title="Microeconomics",Credits=3}, new Course{CourseID=4041,Title="Macroeconomics",Credits=3}, new Course{CourseID=1045,Title="Calculus",Credits=4}, new Course{CourseID=3141,Title="Trigonometry",Credits=4}, new Course{CourseID=2021,Title="Composition",Credits=3}, new Course{CourseID=2042,Title="Literature",Credits=4} }; foreach (Course c in courses) { context.Courses.Add(c); } context.SaveChanges(); var enrollments = new Enrollment[] { new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A}, new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C}, new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B}, new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B}, new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F}, new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F}, new Enrollment{StudentID=3,CourseID=1050}, new Enrollment{StudentID=4,CourseID=1050}, new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F}, new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C}, new Enrollment{StudentID=6,CourseID=1045}, new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A}, }; foreach (Enrollment e in enrollments) { context.Enrollments.Add(e); } context.SaveChanges(); } } }
// Unused usings removed using System; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.DependencyInjection; using ContosoUniversity.Data; namespace ContosoUniversity { public class Program { public static void Main(string[] args) { var host = BuildWebHost(args); using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; try { var context = services.GetRequiredService<SchoolContext>(); DbInitializer.Initialize(context); } catch (Exception ex) { var logger = services.GetRequiredService<ILogger<Program>>(); logger.LogError(ex, "An error occurred while seeding the database."); } } host.Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); } }
第一次運行該應用時,會使用測試數據建立並填充數據庫。 更新數據模型時:
modelBuilder.Entity<Department>() .HasOne(d => d.Administrator) .WithMany() .OnDelete(DeleteBehavior.Restrict)
public class CourseAssignment { public int InstructorID { get; set; } public int CourseID { get; set; } public Instructor Instructor { get; set; } public Course Course { get; set; } }
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<CourseAssignment>() .HasKey(c => new { c.CourseID, c.InstructorID }); }
①調用返回實體的查詢
public async Task<IActionResult> Details(int? id) { if (id == null) { return NotFound(); } string query = "SELECT * FROM Department WHERE DepartmentID = {0}"; var department = await _context.Departments .FromSql(query, id) .Include(d => d.Administrator) .AsNoTracking() .SingleOrDefaultAsync(); if (department == null) { return NotFound(); } return View(department); }
②調用返回其餘類型的查詢
public async Task<ActionResult> About() { List<EnrollmentDateGroup> groups = new List<EnrollmentDateGroup>(); var conn = _context.Database.GetDbConnection(); try { await conn.OpenAsync(); using (var command = conn.CreateCommand()) { string query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount " + "FROM Person " + "WHERE Discriminator = 'Student' " + "GROUP BY EnrollmentDate"; command.CommandText = query; DbDataReader reader = await command.ExecuteReaderAsync(); if (reader.HasRows) { while (await reader.ReadAsync()) { var row = new EnrollmentDateGroup { EnrollmentDate = reader.GetDateTime(0), StudentCount = reader.GetInt32(1) }; groups.Add(row); } } reader.Dispose(); } } finally { conn.Close(); } return View(groups); }
③調用更新查詢
[HttpPost] public async Task<IActionResult> UpdateCourseCredits(int? multiplier) { if (multiplier != null) { ViewData["RowsAffected"] = await _context.Database.ExecuteSqlCommandAsync( "UPDATE Course SET Credits = Credits * {0}", parameters: multiplier); } return View(); }
1,路由
<a asp-action="Edit" asp-route-studentID="@item.ID">Edit</a> <a href="/Students/Edit?studentID=6">Edit</a>
2,命令搭建基架
參考文檔:https://docs.microsoft.com/zh-cn/aspnet/core/data/ef-rp/intro#add-scaffold-tooling
3,SelectList
using ContosoUniversity.Data; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using System.Linq; namespace ContosoUniversity.Pages.Courses { public class DepartmentNamePageModel : PageModel { public SelectList DepartmentNameSL { get; set; } public void PopulateDepartmentsDropDownList(SchoolContext _context, object selectedDepartment = null) { var departmentsQuery = from d in _context.Departments orderby d.Name // Sort by name. select d; DepartmentNameSL = new SelectList(departmentsQuery.AsNoTracking(), "DepartmentID", "Name", selectedDepartment); } } } <div class="form-group"> <label asp-for="Course.Department" class="control-label"></label> <select asp-for="Course.DepartmentID" class="form-control" asp-items="@Model.DepartmentNameSL"> <option value="">-- Select Department --</option> </select> <span asp-validation-for="Course.DepartmentID" class="text-danger" /> </div>
①經常使用的驗證屬性
[CreditCard]
:驗證屬性是否具備信用卡格式。
[Compare]
:驗證某個模型中的兩個屬性是否匹配。
[EmailAddress]
:驗證屬性是否具備電子郵件格式。
[Phone]
:驗證屬性是否具備電話格式。
[Range]
:驗證屬性值是否落在給定範圍內。
[RegularExpression]
:驗證數據是否與指定的正則表達式匹配。
[Required]
:將屬性設置爲必需屬性。
[StringLength]
:驗證字符串屬性是否最多具備給定的最大長度。
[Url]
:驗證屬性是否具備 URL 格式。
①Razor語法
<p>Last week this time: @(DateTime.Now - TimeSpan.FromDays(7))</p>
@{ var joe = new Person("Joe", 33); } <p>Age@(joe.Age)</p>
@Html.Raw("<span>Hello World</span>")
@for (var i = 0; i < people.Length; i++) { var person = people[i]; <text>Name: @person.Name</text> }
@for (var i = 0; i < people.Length; i++) { var person = people[i]; @:Name: @person.Name }
@if (value % 2 == 0) { <p>The value was even.</p> } else if (value >= 1337) { <p>The value is large.</p> } else { <p>The value is odd and small.</p> }
@switch (value) { case 1: <p>The value is 1!</p> break; case 1337: <p>Your number is 1337!</p> break; default: <p>Your number wasn't 1 or 1337.</p> break; }
@for (var i = 0; i < people.Length; i++) { var person = people[i]; <p>Name: @person.Name</p> <p>Age: @person.Age</p> }
@foreach (var person in people) { <p>Name: @person.Name</p> <p>Age: @person.Age</p> }
@{ var i = 0; } @while (i < people.Length) { var person = people[i]; <p>Name: @person.Name</p> <p>Age: @person.Age</p> i++; }
@{ var i = 0; } @do { var person = people[i]; <p>Name: @person.Name</p> <p>Age: @person.Age</p> i++; } while (i < people.Length);
@using (Html.BeginForm()) { <div> email: <input type="email" id="Email" value=""> <button>Register</button> </div> }
@try { throw new InvalidOperationException("You did something invalid."); } catch (Exception ex) { <p>The exception message: @ex.Message</p> } finally { <p>The finally statement.</p> }
②@inherits 指令對視圖繼承的類提供徹底控制
using Microsoft.AspNetCore.Mvc.Razor; public abstract class CustomRazorPage<TModel> : RazorPage<TModel> { public string CustomText { get; } = "Gardyloo! - A Scottish warning yelled from a window before dumping a slop bucket on the street below."; }
@inherits CustomRazorPage<TModel> <div>Custom text: @CustomText</div>
<div>Custom text: Gardyloo! - A Scottish warning yelled from a window before dumping a slop bucket on the street below.</div>
③@functions
指令容許 Razor 頁面將 C# 代碼塊添加到視圖中
@functions { public string GetHello() { return "Hello"; } } <div>From method: @GetHello()</div>
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Razor; public class _Views_Home_Test_cshtml : RazorPage<dynamic> { // Functions placed between here public string GetHello() { return "Hello"; } // And here. #pragma warning disable 1998 public override async Task ExecuteAsync() { WriteLiteral("\r\n<div>From method: "); Write(GetHello()); WriteLiteral("</div>\r\n"); } #pragma warning restore 1998
④_ViewImports.cshtml導入共享指令
支持的指令:
@addTagHelper
@removeTagHelper
@tagHelperPrefix
@using
@model
@inherits
@inject
針對 ASP.NET Core MVC 應用的 _ViewImports.cshtml
文件一般放置在 Views
文件夾中
①@addTagHelper
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper MvcDemo2.TagHelpers.EmailTagHelper,MvcDemo2
@addTagHelper以後第一個參數:須要加載的標記幫助類(*表示全部)
第二個參數:標記幫助類所在的程序集
②簡單的將 <email>hunter</email> 變成 <a>hunter</a>
using Microsoft.AspNetCore.Razor.TagHelpers; using System.Threading.Tasks; namespace MvcDemo2.TagHelpers { //EmailTagHelper 的根名稱是 email,所以 <email> 標記將做爲目標名稱 public class EmailTagHelper:TagHelper { public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName="a";//用<a>標籤替換<email> } } }
@using MvcDemo2 @using MvcDemo2.Models @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper MvcDemo2.TagHelpers.EmailTagHelper,MvcDemo2
這時,在頁面上的 <email>hunter</email> 會變成<a>hunter</a>
③設置自結束標籤 <email/>
[HtmlTargetElement("email",TagStructure=TagStructure.WithoutEndTag)] public class EmailTagHelper:TagHelper
若是存在不是自結束標籤,就會報錯
④將 <email mail-to="hunter"></email> 變成 <a href="hunter@qq.com">hunter@qq.com</a>
using Microsoft.AspNetCore.Razor.TagHelpers; using System.Threading.Tasks; namespace MvcDemo2.TagHelpers { //EmailTagHelper 的根名稱是 email,所以 <email> 標記將做爲目標名稱 public class EmailTagHelper:TagHelper { public const string EmailDomain="qq.com"; //能夠經過<email mail-to =「...」/>傳遞 //標記幫助程序採用 Pascal 大小寫格式的類和屬性名將轉換爲各自相應的小寫短橫線格式 public string MailTo{get;set;} public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName="a";//用<a>標籤替換<email> var address=MailTo+"@"+EmailDomain; //給標籤添加屬性 output.Attributes.SetAttribute("href",address); //設置<email></email>裏面的內容 output.Content.SetContent(address); } } }
⑤將 <email>hunter</email> 變成<a href="hunter@qq.com">hunter@qq.com</a>
using Microsoft.AspNetCore.Razor.TagHelpers; using System.Threading.Tasks; namespace MvcDemo2.TagHelpers { //EmailTagHelper 的根名稱是 email,所以 <email> 標記將做爲目標名稱 public class EmailTagHelper:TagHelper { public const string EmailDomain="qq.com"; //能夠經過<email mail-to =「...」/>傳遞 public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName="a";//用<a>標籤替換<email> var content=await output.GetChildContentAsync();//獲取標籤裏的內容 var tagter=content.GetContent()+"@"+EmailDomain; //給標籤添加屬性 output.Attributes.SetAttribute("href",tagter); //設置<email></email>裏面的內容 output.Content.SetContent(tagter); } } }
⑥將頁面中的 <bold>bbbb</bold> 替換爲 <strong>bbbb</strong>
using Microsoft.AspNetCore.Razor.TagHelpers; namespace MvcDemo2.TagHelpers { public class BoldTagHelper:TagHelper { public override void Process(TagHelperContext context, TagHelperOutput output) { output.Attributes.RemoveAll("bold"); output.PreContent.SetHtmlContent("<strong>"); output.PostContent.SetHtmlContent("</strong>"); } } }
③將model傳入標記幫助程序
using System; namespace MvcDemo2.Models { public class WebsiteContext { public Version Version{get;set;} public int CopyrightYear{get;set;} public bool Approved{get;set;} public int TagsToShow{get;set;} } }
using Microsoft.AspNetCore.Razor.TagHelpers; using MvcDemo2.Models; namespace MvcDemo2.TagHelpers { //使用<website-information /> public class WebsiteInformationTagHelper:TagHelper { public WebsiteContext Info{get;set;} public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName="section"; output.Content.SetHtmlContent( $@"<ul><li><strong>版本:</strong> {Info.Version}</li> <li><strong>版權 年:</strong> {Info.CopyrightYear}</li> <li><strong>是否批准:</strong> {Info.Approved}</li> <li><strong>顯示的標籤:</strong> {Info.TagsToShow}</li></ul>" ); } } }
<website-information info="new WebsiteContext(){ Version=new Version(1,3), CopyrightYear=10, Approved=true, TagsToShow=131 }"></website-information>
⑥.NET 類型和生成的 HTML 類型
.NET 類型 | 輸入類型 |
---|---|
Bool | type=」checkbox」 |
String | type=」text」 |
DateTime | type=」datetime」 |
Byte | type=」number」 |
Int | type=」number」 |
Single、Double | type=」number」 |
⑦數據註解和生成的 HTML 類型
特性 | 輸入類型 |
---|---|
[EmailAddress] | type=」email」 |
[Url] | type=」url」 |
[HiddenInput] | type=」hidden」 |
[Phone] | type=」tel」 |
[DataType(DataType.Password)] | type=」password」 |
[DataType(DataType.Date)] | type=」date」 |
[DataType(DataType.Time)] | type=」time」 |
⑧驗證標記幫助程序
<span asp-validation-for="Email"></span>
針對具備 asp-validation-summary 屬性的 <div> 元素
asp-validation-summary | 顯示的驗證消息 |
---|---|
ValidationSummary.All | 屬性和模型級別 |
ValidationSummary.ModelOnly | 模型 |
ValidationSummary.None | 無 |
實例:
@model RegisterViewModel @{ ViewData["Title"] = "Home Page"; } <a bold>aaa</a> <bold>bbbb</bold> <!--Razor 知道 info 屬性是一個類,而不是字符串,而且你想要編寫 C# 代碼。 編寫任何非字符串標記幫助程序屬性時,都不該使用 @@ 字符。--> <website-information info="new WebsiteContext(){ Version=new Version(1,3), CopyrightYear=10, Approved=true, TagsToShow=131 }"></website-information> <form asp-action="Register" method="POST" role="form"> <legend>註冊</legend> <div asp-validation-summary="ModelOnly"></div> <div class="form-group"> <input asp-for="Email" class="form-control" placeholder="Input field"> <span asp-validation-for="Email"></span> </div> <div class="form-group"> <input asp-for="Password" class="form-control" placeholder="Input field"> <span asp-validation-for="Password"></span> </div> <button type="submit" class="btn btn-primary">Submit</button> </form>
[HttpPost] public IActionResult Register(RegisterViewModel model) { return View("Index"); }
⑨選擇標記幫助程序
using System.Collections.Generic; using Microsoft.AspNetCore.Mvc.Rendering; namespace MvcDemo2.Models { public class CountryViewModel { public string Country{get;set;} public List<SelectListItem> Countries {get;}=new List<SelectListItem>(){ new SelectListItem(){Value="MX",Text="墨西哥"}, new SelectListItem(){Value="CA",Text="加拿大"}, new SelectListItem(){Value="US",Text="美國"} }; } }
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using MvcDemo2.Models; namespace MvcDemo2.Controllers { public class HomeController : Controller { public IActionResult Index() { var country=new CountryViewModel(); country.Country="US"; return View(country); } [HttpPost] public IActionResult Index(CountryViewModel model) { return View(model); } } }
@model CountryViewModel <form method="POST" asp-action="Index"> <select asp-for="Country" asp-items="Model.Countries"></select> <input type="submit" value="提交" /> </form>
⑩枚舉綁定
public enum CountryEnum { [Display(Name = "墨西哥合衆國")] Mexico, [Display(Name = "美國")] USA, Canada, France, Germany, Spain }
<select asp-for="Country" asp-items="Html.GetEnumSelectList<CountryEnum>()"></select>
⑩選項分組
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Mvc.Rendering; namespace MvcDemo2.Models { public class CountryViewModel { public string Country{get;set;} public List<SelectListItem> Countries {get;}=new List<SelectListItem>(){ new SelectListItem(){Value="MX",Text="墨西哥",Group=new SelectListGroup(){Name="分組一"}}, new SelectListItem(){Value="CA",Text="加拿大",Group=new SelectListGroup(){Name="分組二"}}, new SelectListItem(){Value="US",Text="美國",Group=new SelectListGroup(){Name="分組三"}} }; } }
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using MvcDemo2.Models; namespace MvcDemo2.Controllers { public class HomeController : Controller { public IActionResult Index() { var country=new CountryViewModel(); country.Country="US"; return View(country); } [HttpPost] public IActionResult Index(CountryViewModel model) { return View(model); } } }
<select asp-for="Country" asp-items="Model.Countries"></select>
⑩多重選擇
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Mvc.Rendering; namespace MvcDemo2.Models { public class CountryViewModel { public IEnumerable<string> Countrys{get;set;} public List<SelectListItem> Countries {get;}=new List<SelectListItem>(){ new SelectListItem(){Value="MX",Text="墨西哥"}, new SelectListItem(){Value="CA",Text="加拿大"}, new SelectListItem(){Value="US",Text="美國"} }; } }
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using MvcDemo2.Models; namespace MvcDemo2.Controllers { public class HomeController : Controller { public IActionResult Index() { var country=new CountryViewModel(); country.Countrys=new []{"US","MX"}; return View(country); } [HttpPost] public IActionResult Index(CountryViewModel model) { return View(model); } } }
@model CountryViewModel <form method="POST" asp-action="Index"> <select asp-for="Countrys" asp-items="Model.Countries"></select> <input type="submit" value="提交" /> </form>
⑩無選定內容
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Mvc.Rendering; namespace MvcDemo2.Models { public class CountryViewModel { public string Country{get;set;} public List<SelectListItem> Countries {get;}=new List<SelectListItem>(){ new SelectListItem(){Value="MX",Text="墨西哥"}, new SelectListItem(){Value="CA",Text="加拿大"}, new SelectListItem(){Value="US",Text="美國"} }; } }
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using MvcDemo2.Models; namespace MvcDemo2.Controllers { public class HomeController : Controller { public IActionResult Index() { var country=new CountryViewModel(); return View(country); } [HttpPost] public IActionResult Index(CountryViewModel model) { return View(model); } } }
@model CountryViewModel <form method="POST" asp-action="Index"> <select asp-for="Country" asp-items="Model.Countries"> <option value="">--none--</option> </select> <input type="submit" value="提交" /> </form>
①asp-all-route-data
@{ var parms = new Dictionary<string, string> { { "speakerId", "11" }, { "currentYear", "true" } }; } <a asp-route="speakerevalscurrent" asp-all-route-data="parms">Speaker Evaluations</a>
<a href="/Speaker/EvaluationsCurrent?speakerId=11¤tYear=true">Speaker Evaluations</a>
[Route("/Speaker/EvaluationsCurrent", Name = "speakerevalscurrent")] public IActionResult Evaluations( int speakerId, bool currentYear) => View();
②asp-fragment
可定義要追加到 URL 的 URL 片斷
<a asp-controller="Speaker" asp-action="Evaluations" asp-fragment="SpeakerEvaluations">Speaker Evaluations</a>
<a href="/Speaker/Evaluations#SpeakerEvaluations">Speaker Evaluations</a>
③asp-area
設置相應路由的區域名稱
<a asp-area="Blogs" asp-controller="Home" asp-action="AboutBlog">About Blog</a>
<a href="/Blogs/Home/AboutBlog">About Blog</a>
④asp-protocol
在URL 中指定協議(好比 https
)
<a asp-protocol="https" asp-controller="Home" asp-action="About">About</a>
<a href="https://localhost/Home/About">About</a>
⑤asp-host
在 URL 中指定主機名
<a asp-protocol="https" asp-host="microsoft.com" asp-controller="Home" asp-action="About">About</a>
<a href="https://microsoft.com/Home/About">About</a>
⑥緩存標記幫助程序
<cache enabled="true">@DateTime.Now</cache>
屬性expires-after:設置過時時間
<cache expires-after="@TimeSpan.FromSeconds(120)"> Current Time Inside Cache Tag Helper: @DateTime.Now </cache>
屬性expires-sliding:設置多久未被訪問過時設置
<cache expires-sliding="@TimeSpan.FromSeconds(60)"> Current Time Inside Cache Tag Helper: @DateTime.Now </cache>
⑦環境標記幫助程序
<environment include="Development">Development</environment> <environment include="Staging">Staging</environment> <environment include="Production">Production</environment>
⑧圖像標記幫助程序
<img src="~/images/1.jpg" asp-append-version="true"/>
asp-append-version:追加版本號
@await Html.PartialAsync("ViewName") @await Html.PartialAsync("ViewName.cshtml") @await Html.PartialAsync("~/Views/Folder/ViewName.cshtml") @await Html.PartialAsync("/Views/Folder/ViewName.cshtml") @await Html.PartialAsync("../Account/LoginPartial.cshtml")
@model string 姓名:@Model
@await Html.PartialAsync("Person","Hunter")
①添加 ViewComponent 類
在根目錄新建一個ViewComponents文件夾,建ViewComponent類放在此文件夾中
using MvcDemo2.Models; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; using System.Collections.Generic; using System.Linq; namespace MvcDemo2.ViewComponents { public class ProductListViewComponent:ViewComponent { public async Task<IViewComponentResult> InvokeAsync(bool ischecked,string name) { var list=new List<Product>(){ new Product(){IsChecked=true,Name="iphone x",Price=10000}, new Product(){IsChecked=false,Name="iphone 8p",Price=6600}, }; var data= list.Where(m=>m.IsChecked==ischecked&&m.Name.Contains(name)); return View(data); } } }
②建立視圖組件 Razor 視圖
建立 Views/Shared/Components 文件夾。 此文件夾 必須 命名爲 Components
@model IEnumerable<Product> @foreach(var item in Model) { <p>@item.Name</p> }
@await Component.InvokeAsync("ProductList",new {ischecked=true,name="iphone"})
①使用模型綁定上傳小文件
using System.Collections.Generic; using Microsoft.AspNetCore.Http; namespace MvcDemo2.Models { public class FileUpViewModel { public IEnumerable<IFormFile> files {get;set;} public string name{get;set;} } }
public IActionResult FileUp(FileUpViewModel model) { return View(); }
<form asp-action="FileUp" enctype="multipart/form-data" method="POST" role="form"> <legend>提交</legend> <input type="file" name="files" class="form-control" multiple/> <input type="text" name="name" class="form-control"/> <button type="submit" class="btn btn-primary">Submit</button> </form>
每種篩選器類型都在篩選器管道中的不一樣階段執行。
受權篩選器最早運行,用於肯定是否已針對當前請求爲當前用戶受權。 若是請求未獲受權,它們可讓管道短路。
資源篩選器是受權後最早處理請求的篩選器。 它們能夠在篩選器管道的其他階段運行以前以及管道的其他階段完成以後運行代碼。 出於性能方面的考慮,可使用它們來實現緩存或以其餘方式讓篩選器管道短路。它們在模型綁定以前運行,因此能夠影響模型綁定。
操做篩選器能夠在調用單個操做方法以前和以後當即運行代碼。 它們可用於處理傳入某個操做的參數以及從該操做返回的結果。
異常篩選器用於在向響應正文寫入任何內容以前,對未經處理的異常應用全局策略。
結果篩選器能夠在執行單個操做結果以前和以後當即運行代碼。 僅當操做方法成功執行時,它們纔會運行。對於必須圍繞視圖或格式化程序的執行的邏輯,它們頗有用。
下圖展現了這些篩選器類型在篩選器管道中的交互方式:
①篩選器經過不一樣的接口定義支持同步和異步實現
using FiltersSample.Helper; using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersSample.Filters { public class SampleActionFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { // do something before the action executes } public void OnActionExecuted(ActionExecutedContext context) { // do something after the action executes } } }
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersSample.Filters { public class SampleAsyncActionFilter : IAsyncActionFilter { public async Task OnActionExecutionAsync( ActionExecutingContext context, ActionExecutionDelegate next) { // 在行動執行以前作一些事情 var resultContext = await next(); // 在執行操做後執行某些操做; resultContext.Result將被設置 } } }
②添加爲全局篩選器
public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader", "Result filter added to MvcOptions.Filters")); // an instance options.Filters.Add(typeof(SampleActionFilter)); // by type options.Filters.Add(new SampleGlobalActionFilter()); // an instance }); services.AddScoped<AddHeaderFilterWithDi>(); }
③取消和設置短路
經過設置提供給篩選器方法的 context
參數上的 Result
屬性,能夠在篩選器管道的任意位置設置短路。 例如,如下資源篩選器將阻止執行管道的其他階段
using System; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersSample.Filters { public class ShortCircuitingResourceFilterAttribute : Attribute, IResourceFilter { public void OnResourceExecuting(ResourceExecutingContext context) { context.Result = new ContentResult() { Content = "Resource unavailable - header should not be set" }; } public void OnResourceExecuted(ResourceExecutedContext context) { } } }
[ { "outputFileName": "wwwroot/css/site.min.css", "inputFiles": [ "wwwroot/css/site.css" ] }, { "outputFileName": "wwwroot/js/site.min.js", "inputFiles": [ "wwwroot/js/site.js" ], "minify": { "enabled": true, "renameLocals": true }, "sourceMap": false } ]
①須要引用: <DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.6.362" />
②執行命令: dotnet bundle 會合並並壓縮inputFiles裏的文件到outputFileName
1,數據註解
①DisplayFormat
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
②Column
[Column("FirstName")] public string FirstMidName { get; set; }
實體屬性表字段映射
2,DatabaseGenerated標記主鍵
6、配置