Asp.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:
public static class MiddlewareExtends
{
/// <summary>
/// 测试用例中间件
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
public static IApplicationBuilder UseTest(this IApplicationBuilder builder)
{
return builder.UseMiddleware<TestMiddleware>();
} }
使用 builder.UseMiddleware<TestMiddleware>() 来添加自定义组件,组件实现代码如下:
public class TestMiddleware
{
private RequestDelegate _requestDelegate;
public TestMiddleware(RequestDelegate requestDelegate)
{
_requestDelegate = requestDelegate;
} public Task Invoke(HttpContext context)
{ context.Items["TestMiddleware"] = "hello world,我是TestMiddleware。"; return _requestDelegate(context);
}
}
以上是最基础的组件格式;注:
1. 组件必须要有 public Task Invoke(HttpContext context) ,HttpContext是咋们http上下文,Invoke()委托方法,每次程序被访问时就会进入Invoke;
2. 要有 public delegate Task RequestDelegate(HttpContext context); 委托方法,来响应http请求;
到这里咋们hello world就完成了,为了测试方法,我们直接在action中写入如下代码:
public IActionResult About()
{ ViewData["Message"] = HttpContext.Items["TestMiddleware"];
return View();
}
运行结果:
组件异步写法
public class TestMiddleware
{
private RequestDelegate _requestDelegate;
public TestMiddleware(RequestDelegate requestDelegate)
{
_requestDelegate = requestDelegate;
} public async Task Invoke(HttpContext context)
{ context.Items["TestMiddleware"] = "hello world,我是asyncTestMiddleware。"; await _requestDelegate(context);
}
}
仅仅需要async 和 await 组合修饰就行了;
.netcore自定义验证码组件
/// <summary>
/// 文字验证码
/// </summary>
public class WenZiCodeMiddleware
{
private RequestDelegate _requestDelegate;
public WenZiCodeMiddleware(RequestDelegate requestDelegate)
{
_requestDelegate = requestDelegate;
} public async Task Invoke(HttpContext context)
{ var url = "http://localhost:1001/shenniuapi/WenZiValidateCode";
using (HttpClient client = new HttpClient())
{
client.Timeout = TimeSpan.FromSeconds(); var str = "{\"UserName\": \"神牛步行3\",\"UserPwd\": \"4297f44b13955235245b2497399d7a93\",\"Token\": \"008我是测试\"}";
var content = new StringContent(str, Encoding.UTF8, "application/x-www-form-urlencoded");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result01 = client.PostAsync(url, content).Result;
var stream = await result01.Content.ReadAsStreamAsync();
using (var reader = new StreamReader(stream))
{
var result02 = await reader.ReadToEndAsync();
context.Items["codedata"] = result02;
}
} await _requestDelegate(context);
}
}
我们同样需要再静态扩展方法里面添加如下代码,来加入组件:
/// <summary>
/// 文字验证码中间件
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
public static IApplicationBuilder UseWenZiValidateCode(this IApplicationBuilder builder)
{
return builder.UseMiddleware<WenZiCodeMiddleware>();
}
在Configure方法中,引用组件: app.UseWenZiValidateCode(); ;Action中,使用组件:
public FileResult GetCode()
{
var data = HttpContext.Items["codedata"].ToString();
var code = JsonConvert.DeserializeObject<MoValidateCodeResponse>(data);
return File(code.CodeStream, "image/jpeg");
}
View试图中代码:
GetCode:<img src="/home/GetCode" data-src="/home/GetCode" />
效果展示:
这里需要考虑场景是,我们上面提及到的Invoke方法是任意请求都会进入,那验证码这种功能做成组件是否不是很合理,因为验证码也只有在登陆界面或验证的界面需要用到而已,如我们上面写的验证码组件,每次都会被程序执行这显然不合理,因此个人认为如果你需要自定义组件,那么需要考量:是否每次请求都需要进入您的组件服务,如果不需要的话,那其实没必要弄一个组件,当然感觉很高大上;因此这里我不得不使用静态扩展方法(当然还有其他方式)来重写获取验证码的方法;
静态扩展方法重写验证码组件
由于上面我们在添加组件时有一个静态类了,那么我们直接在上面补充扩展方法:
/// <summary>
/// 文字验证码
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static async Task<MoValidateCodeResponse> WenZiCode(this HttpContext context)
{
var code = default(MoValidateCodeResponse);
try
{
var url = "http://localhost:1001/shenniuapi/WenZiValidateCode";
using (HttpClient client = new HttpClient())
{
client.Timeout = TimeSpan.FromSeconds(); var str = "{\"UserName\": \"神牛步行3\",\"UserPwd\": \"4297f44b13955235245b2497399d7a93\",\"Token\": \"008我是测试\"}";
var content = new StringContent(str, Encoding.UTF8, "application/x-www-form-urlencoded");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result01 = client.PostAsync(url, content).Result;
var stream = await result01.Content.ReadAsStreamAsync();
using (var reader = new StreamReader(stream))
{
var result02 = await reader.ReadToEndAsync();
code = await JsonConvert.DeserializeObjectAsync<MoValidateCodeResponse>(result02);
}
}
}
catch (Exception ex)
{
}
return code;
}
对应的验证码实体类:
/// <summary>
/// 神牛接口返回基类
/// </summary>
public class MoShenNiuBaseResponse
{
/// <summary>
/// 返回状态: 0:失败 1:成功
/// </summary>
public int Status { get; set; } /// <summary>
/// 错误信息
/// </summary>
public string Msg { get; set; }
} /// <summary>
/// 验证码返回类
/// </summary>
public class MoValidateCodeResponse : MoShenNiuBaseResponse
{ public MoValidateCodeResponse()
{
this.ImgCode = new List<MoImgCode>();
} /// <summary>
/// 验证码类型
/// </summary>
public string Code { get; set; } /// <summary>
/// 验证码图片流
/// </summary>
public byte[] CodeStream { get; set; } /// <summary>
/// 图片验证坐标
/// </summary>
public List<MoImgCode> ImgCode;
} /// <summary>
/// 图片验证码坐标
/// </summary>
public class MoImgCode
{
public string Index { get; set; } public string IndexType { get; set; } public string ImgUrl { get; set; } public Point Point_A { get; set; } public Point Point_B { get; set; } public bool IsChoice { get; set; }
} public class Point
{
public int X { get; set; }
public int Y { get; set; }
}
这个时候同样来到Action中:
public async Task<FileResult> GetCodeAsync()
{
var code = await HttpContext.WenZiCode(); return File(code.CodeStream, "image/jpeg");
}
修改view试图代码,增加点击验证码图片重新获取新的验证码:
<style type="text/css">
img{cursor:pointer}
</style>
<h3>@ViewData["Message"]</h3>
<h3>@ViewData["codedata"]</h3>
GetCode:<img src="/home/GetCode" data-src="/home/GetCode" />
GetCodeAsync:<img src="/home/GetCodeAsync" data-src="/home/GetCodeAsync" /> <script src="~/lib/jquery/dist/jquery.js"></script>
<script>
$(function () {
$("img").on("click", function () {
var img = this;
var nowTime = new Date().getTime();
var src = $(img).attr("data-src") + "?t=" + nowTime;
$(img).attr("src", src);
});
})
</script>
效果图:
以上就是本篇的所有内容,旨在分享怎么写一个组件和什么时候用组件合适,谢谢大家支持和点赞。
Asp.NetCore之组件写法的更多相关文章
- ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇
原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇 第三章 为控件添加事件 后篇 前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是 ...
- ASP.NET自定义控件组件开发 第一章 第二篇 接着待续
原文:ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 很感谢大家给我的第一篇ASP.NET控件开发的支持!在写这些之前,我也看了 ...
- 『Asp.Net 组件』第一个 Asp.Net 服务器组件:自己的文本框控件
代码: using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace DemoWebControl ...
- ASP.NETCore学习记录(一)
ASP.NETCore学习记录(一) asp.net core介绍 Startup.cs ConfigureServices Configure 0. ASP.NETCore 介绍 ASP.N ...
- ASP.NETCORE MVC模块化
ASP.NETCORE MVC模块化编程 前言 记得上一篇博客中跟大家分享的是基于ASP.NETMVC5,实际也就是基于NETFRAMEWORK平台实现的这么一个轻量级插件式框架.那么今天我主要分享的 ...
- 目录---Asp.NETCore轻松学系列【目录】
随笔分类 - Asp.NETCore轻松学系列 Asp.NETCore轻松学系列阅读指引目录 摘要: 耗时两个多月,坚持写这个入门系列文章,就是想给后来者更好更快的上手体验,这个系列可以说是从入门到进 ...
- 【目录】Asp.NETCore轻松学系列
随笔分类 - Asp.NETCore轻松学系列 Asp.NETCore轻松学系列阅读指引目录 摘要: 耗时两个多月,坚持写这个入门系列文章,就是想给后来者更好更快的上手体验,这个系列可以说是从入门到进 ...
- 壹佰文章最全总结| 《关于ASP.NETCore的分享之路》
学习路线图 (关于学习ASP.NET Core需要了解和掌握的知识点图) 一言不合就来图,各位博客园小伙伴大家好,感觉好久没有写文章了,自从春节开始,中间经历种种,慢慢的就开始微信公众号发文了,原因有 ...
- 彻底解决Asp.netCore WebApi 3.1 跨域时的预检查204 options重复请求的问题
Asp.netCore WebApi 3.1 跨域的预检查options问题 1:我们直接使用core跨域的中间件 ,注入跨域服务, services.AddCors(options => { ...
随机推荐
- BZOJ 1898: [Zjoi2004]Swamp 沼泽鳄鱼(矩阵乘法)
可以发现,如果没有鳄鱼,那么就是裸地一道题,但是可以发现鳄鱼最多每12次重复,那么就少于12的那部分dp,其他的就矩阵乘法就行了 PS:第一次吧矩阵乘法AC了好开心QAQ CODE: #include ...
- JavaScript 基本类型值-Number类型
▓▓▓▓▓▓ 大致介绍 在JavaScript的内部采用IEEE754格式来表示数字,所以不区分整数和浮点数,都是用64位浮点数的形式储存.就是说,在JavaScript内部,就根本没有小数.但是有些 ...
- [bzoj1500][NOI2005]维修数列——splay
题目 题解 这道题可以说是数列问题的大BOSS,也算是这一周来学习splay等数据结构的一个总结. 我们一个一个地看这些操作. 对于操作1,我们首先建一棵子树,直接接上原树即可. 对于操作2,我们找到 ...
- Unbutu14.04 启用 root 并禁用guest
系统环境: Ubuntu14.04 x64 问题描述: Ubuntu14.04的64位系统默认禁用 root 账号登录 解决方式: 1. 为root设置密码 sudo passw ...
- java入门知识
Java特性 简单.面向对象.支持网络.解释性.健壮性.安全性.高性能.可移植(跨平台) Java特点 开源.免费.跨平台.面向对象 应用平台 JavaSE(standard edition)(c/s ...
- 腾讯云数据库团队:SQL Server 数据加密功能解析
数据加密是数据库被破解.物理介质被盗.备份被窃取的最后一道防线:数据加密,一方面解决数据被窃取安全问题,另一方面有关法律要求强制加密数据:SQL Server 的数据加密相较于其他数据库,功能相对完善 ...
- css3 的 calc()函数在布局中的使用----头部高度固定,页面正好占满一屏
最近项目遇到一个布局需求,头部高度固定,页面需要刚好占满一屏幕. 如下示意图: 方法:使用calc .wrap{ position: relative; margin-left: 24px; marg ...
- PHP语言开发微信公众平台(订阅号)之curl命令
在开发过程中,经常会遇到要求用curl命令调用接口的情况 那么,什么是curl,简单来说curl是一个利用url语法规定来传输文件和哦数据的工具,支持很多协议,如 http.ftp.telent 等, ...
- iOS网络编程笔记——GCDAsyncSocket使用
CocoaAsyncSocket为Mac和iOS提供了易于使用且强大的异步通信库. 简单的Socket通信包括了建连.断开连接.发送socket业务请求.重连这四个基本功能. 1.建立连接:GCDAs ...
- TCP/IP笔记(二)TCP/IP简介
上回,主要介绍了下协议和OSI参考模型,并简单了解下网络构成要素,这回该说说TCP/IP了 互联网与TCP/IP的关系 互联网进行通信时,需要相应的网络协议,TCP/IP原本就是为使用互联网而开发 ...