首页 > 代码库 > NetCore组件
NetCore组件
NetCore之组件写法
本章内容和大家分享的是Asp.NetCore组件写法,在netcore中很多东西都以提供组件的方式来使用,比如MVC架构,Session,Cache,数据库引用等; 这里我也通过调用验证码接口来自定义个组件以此说明如何使用,以及使用时需要注意的场景;
Middleware之hello world
对于netcore来说,通常会在UseStartup<Startup>对应的Startup类中引用组件,这个Startup可以换成自己自定义的其实类,不过需要在UseStartup的时候指向她;这里还是以Startup类为例,通过vs自动生成的文件,在这个类中我们能看到Configure方法体里面包含了:app.UseMvc(),app.UseStaticFiles(),app.xxx()等一些列自带的组件,下面来看下自定义个hello world中组件实例,首先使用静态扩展方法扩展IApplicationBuilder:
1 public static class MiddlewareExtends 2 { 3 /// <summary> 4 /// 测试用例中间件 5 /// </summary> 6 /// <param name="builder"></param> 7 /// <returns></returns> 8 public static IApplicationBuilder UseTest(this IApplicationBuilder builder) 9 { 10 return builder.UseMiddleware<TestMiddleware>(); 11 } 12 13 }
使用 builder.UseMiddleware<TestMiddleware>() 来添加自定义组件,组件实现代码如下:
1 public class TestMiddleware 2 { 3 private RequestDelegate _requestDelegate; 4 public TestMiddleware(RequestDelegate requestDelegate) 5 { 6 _requestDelegate = requestDelegate; 7 } 8 9 public Task Invoke(HttpContext context) 10 { 11 12 context.Items["TestMiddleware"] = "hello world,我是TestMiddleware。"; 13 14 return _requestDelegate(context); 15 } 16 }
以上是最基础的组件格式;注:
1. 组件必须要有 public Task Invoke(HttpContext context) ,HttpContext是咋们http上下文,Invoke()委托方法,每次程序被访问时就会进入Invoke;
2. 要有 public delegate Task RequestDelegate(HttpContext context); 委托方法,来响应http请求;
到这里咋们hello world就完成了,为了测试方法,我们直接在action中写入如下代码:
1 public IActionResult About() 2 { 3 4 ViewData["Message"] = HttpContext.Items["TestMiddleware"]; 5 return View(); 6 }
运行结果:
组件异步写法
1 public class TestMiddleware 2 { 3 private RequestDelegate _requestDelegate; 4 public TestMiddleware(RequestDelegate requestDelegate) 5 { 6 _requestDelegate = requestDelegate; 7 } 8 9 public async Task Invoke(HttpContext context) 10 { 11 12 context.Items["TestMiddleware"] = "hello world,我是asyncTestMiddleware。"; 13 14 await _requestDelegate(context); 15 } 16 }
仅仅需要async 和 await 组合修饰就行了;
.netcore自定义验证码组件
1 /// <summary> 2 /// 文字验证码 3 /// </summary> 4 public class WenZiCodeMiddleware 5 { 6 private RequestDelegate _requestDelegate; 7 public WenZiCodeMiddleware(RequestDelegate requestDelegate) 8 { 9 _requestDelegate = requestDelegate; 10 } 11 12 public async Task Invoke(HttpContext context) 13 { 14 15 var url = "http://localhost:1001/shenniuapi/WenZiValidateCode"; 16 using (HttpClient client = new HttpClient()) 17 { 18 client.Timeout = TimeSpan.FromSeconds(60); 19 20 var str = "{\"UserName\": \"神牛步行3\",\"UserPwd\": \"4297f44b13955235245b2497399d7a93\",\"Token\": \"008我是测试\"}"; 21 var content = new StringContent(str, Encoding.UTF8, "application/x-www-form-urlencoded"); 22 content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 23 var result01 = client.PostAsync(url, content).Result; 24 var stream = await result01.Content.ReadAsStreamAsync(); 25 using (var reader = new StreamReader(stream)) 26 { 27 var result02 = await reader.ReadToEndAsync(); 28 context.Items["codedata"] = result02; 29 } 30 } 31 32 await _requestDelegate(context); 33 } 34 }
我们同样需要再静态扩展方法里面添加如下代码,来加入组件:
1 /// <summary> 2 /// 文字验证码中间件 3 /// </summary> 4 /// <param name="builder"></param> 5 /// <returns></returns> 6 public static IApplicationBuilder UseWenZiValidateCode(this IApplicationBuilder builder) 7 { 8 return builder.UseMiddleware<WenZiCodeMiddleware>(); 9 }
在Configure方法中,引用组件: app.UseWenZiValidateCode(); ;Action中,使用组件:
1 public FileResult GetCode() 2 { 3 var data = http://www.mamicode.com/HttpContext.Items["codedata"].ToString(); 4 var code = JsonConvert.DeserializeObject<MoValidateCodeResponse>(data); 5 return File(code.CodeStream, "image/jpeg"); 6 }
View试图中代码:
1 GetCode:<img src="http://www.mamicode.com/home/GetCode" data-src="http://www.mamicode.com/home/GetCode" />
效果展示:
这里需要考虑场景是,我们上面提及到的Invoke方法是任意请求都会进入,那验证码这种功能做成组件是否不是很合理,因为验证码也只有在登陆界面或验证的界面需要用到而已,如我们上面写的验证码组件,每次都会被程序执行这显然不合理,因此个人认为如果你需要自定义组件,那么需要考量:是否每次请求都需要进入您的组件服务,如果不需要的话,那其实没必要弄一个组件,当然感觉很高大上;因此这里我不得不使用静态扩展方法(当然还有其他方式)来重写获取验证码的方法;
静态扩展方法重写验证码组件
由于上面我们在添加组件时有一个静态类了,那么我们直接在上面补充扩展方法:
1 /// <summary> 2 /// 文字验证码 3 /// </summary> 4 /// <param name="context"></param> 5 /// <returns></returns> 6 public static async Task<MoValidateCodeResponse> WenZiCode(this HttpContext context) 7 { 8 var code = default(MoValidateCodeResponse); 9 try 10 { 11 var url = "http://localhost:1001/shenniuapi/WenZiValidateCode"; 12 using (HttpClient client = new HttpClient()) 13 { 14 client.Timeout = TimeSpan.FromSeconds(60); 15 16 var str = "{\"UserName\": \"神牛步行3\",\"UserPwd\": \"4297f44b13955235245b2497399d7a93\",\"Token\": \"008我是测试\"}"; 17 var content = new StringContent(str, Encoding.UTF8, "application/x-www-form-urlencoded"); 18 content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 19 var result01 = client.PostAsync(url, content).Result; 20 var stream = await result01.Content.ReadAsStreamAsync(); 21 using (var reader = new StreamReader(stream)) 22 { 23 var result02 = await reader.ReadToEndAsync(); 24 code = await JsonConvert.DeserializeObjectAsync<MoValidateCodeResponse>(result02); 25 } 26 } 27 } 28 catch (Exception ex) 29 { 30 } 31 return code; 32 }
对应的验证码实体类:
这个时候同样来到Action中:
1 public async Task<FileResult> GetCodeAsync() 2 { 3 var code = await HttpContext.WenZiCode(); 4 5 return File(code.CodeStream, "image/jpeg"); 6 }
修改view试图代码,增加点击验证码图片重新获取新的验证码:
1 <style type="text/css"> 2 img{cursor:pointer} 3 </style> 4 <h3>@ViewData["Message"]</h3> 5 <h3>@ViewData["codedata"]</h3> 6 GetCode:<img src="http://www.mamicode.com/home/GetCode" data-src="http://www.mamicode.com/home/GetCode" /> 7 GetCodeAsync:<img src="http://www.mamicode.com/home/GetCodeAsync" data-src="http://www.mamicode.com/home/GetCodeAsync" /> 8 9 <script src="http://www.mamicode.com/~/lib/jquery/dist/jquery.js"></script> 10 <script> 11 $(function () { 12 $("img").on("click", function () { 13 var img = this; 14 var nowTime = new Date().getTime(); 15 var src = http://www.mamicode.com/$(img).attr("data-src") + "?t=" + nowTime; 16 $(img).attr("src", src); 17 }); 18 }) 19 </script>
效果图:
NetCore组件