首页 > 代码库 > 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         }

对应的验证码实体类:

技术分享 View Code

这个时候同样来到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组件