ASP.NET Core3.1 Ocelot认证的实现_实用技巧

来源:脚本之家  责任编辑:小易  

ASP.net mvc5和asp.net.core有什么区别呢,前景如何:区别:asp.net mvc5只能运行在Windows,一般通过IIS发布。asp.net core开源,可跨平台,能够发布到Linux等系统上。asp.net core做了很多的整合工作,目前来说完成了最基本的一部分类库的迁移。前景:asp.net core肯定是以后的一种潮流,随着docker等技术的普及,跨平台的重要性凸显,必须要使用asp.net core编写的接口才能发布到linux中,也就是asp.net core编写的接口可以做成docker的镜像发布,而asp.net mvc5不能。所以最终肯定是会慢慢都转移到asp.net core上来。但是这需要一个比较久的过程。因为从asp.net mvc5转移到asp.net core需要一定时间的学习,即使在国外也需要一定过程。而国内由于语言环境、开发工具(需要VS2015才能进行asp.net core的开发)等的原因,肯定需要更久。国内的技术一直以来也比较保守。如果单纯的以在国内找个开发的工作的话,建议先熟悉下asp.net mvc5。如果确实有跨平台的需求,或者团队成员都对新技术有很高的热情,从事的也是全新的项目的话,就使用asp.net core。.net core:.NET Core 是.NET Framework的新一代版本,是微软开发的第一个官方版本,具有跨平台 (Windows、Mac OSX、Linux) 能力的应用程序开发框架 (Application Framework),未来也将会支持 FreeBSD 与 Alpine 平台,也是微软在一开始发展时就开源的软件平台[1]  ,它经常也会拿来和现有的开源 .NET 平台 Mono 比较。由于 .NET Core 的开发目标是跨平台的 .NET 平台,因此 .NET Core 会包含 .NET Framework 的类库,但与 .NET Framework 不同的是 .NET Core 采用包化 (Packages) 的管理方式,应用程序只需要获取需要的组件即可,与 .NET Framework 大包式安装的作法截然不同,同时各包亦有独立的版本线 (Version line),不再硬性要求应用程序跟随主线版本。参考资料百度百科.百度百科[引用时间2018-1-4]www.zgxue.com防采集请勿采集本网。

1.认证

新框架没用过,.Net Core 2.0感觉应该是支持的。这里有一篇帖子,你可以参考一下。www.bamn.cn/course/volume/3991 实在不行你就转url吧,就像检测用户一样,凡是没有访问权

当客户端通过Ocelot访问下游服务的时候,为了保护下游资源服务器会进行认证鉴权,这时候需要在Ocelot添加认证服务。添加认证服务后,随后Ocelot会基于授权密钥授权每个请求可以访问的资源。用户必须像往常一样在其Startup.cs中注册身份验证服务,但是他们为每次注册提供一个方案(身份验证提供者密钥),例如:

不支持,core 最低是 net 4.6 以上的版本 如果使用 core 请考虑使用WIN10开发

public void ConfigureServices(IServiceCollection services){ var authenticationProviderKey = "TestKey"; services.AddAuthentication() .AddJwtBearer(authenticationProviderKey, x => { });}

在默认 ASP.NET Core 模板中为 Visual Studio 2015 及更新版本提供的 ASP.NET Web 工具扩展中涵盖的漏洞 同时还包括微软最新网页 Kestrel .NET Core 和 ASP.NET Core 支

在此Ocelot认证项目示例中,TestKey是已注册此提供程序的方案,然后将其映射到网关项目Routes路由中:

1、CORS的原理:CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由

{ "Routes": [ { "DownstreamPathTemplate": "/api/customers", "DownstreamScheme": "http", "DownstreamHost": "localhost", "DownstreamPort": 9001, "UpstreamPathTemplate": "/customers", "UpstreamHttpMethod": [ "Get" ], "AuthenticationOptions": { "AuthenticationProviderKey": "TestKey", "AllowedScopes": [] } } ]}

Foundation(WPF)并不包含在.NET Core中。从技术上讲,.NET Core仅支持控制台应用程序。ASP.NET Core和UWP是以.NET Core为基础构建的应用程序模型。NET Standard

Ocelot运行时,它将查看Routes.AuthenticationOptions.AuthenticationProviderKey并检查是否存在使用给定密钥注册的身份验证提供程序。如果不存在,则Ocelot将不会启动,如果存在,则Routes将在执行时使用该提供程序。如果对路由进行身份验证,Ocelot将在执行身份验证中间件时调用与之关联的任何方案。如果请求通过身份验证失败,Ocelot将返回http状态代码401。

dll文件一般被存放在C:\\Windows\\System目录下。电脑系统文件因经常会受到病毒的侵扰,导致系统文件、dll文件等丢失、损坏,一些包括游戏在内的应用程序无法启动。 解决

2.JWT Tokens Bearer认证

用Session传参。。

Json Web Token (JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519)。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

那么你将会认识到 ASP.NET Core 有多完美,这感觉起来就像从古典的 ASP 时代来到全新的 ASP.NET 的世界。 现在,让我们来一探究竟 下面列出 ASP.NET Core 1.0 的核心变

2.1JWT令牌结构

你可以在 OSX 和 Linux上运行 ASP.NET Core 应用,这对于 ASP.NET 来说,这具有跨时代的意义,也给 ASP.NET 开发者和设计师们带来了全新的体验。ASP.NET Core 具有两个

在紧凑的形式中,JSON Web Tokens由dot(.)分隔的三个部分组成,它们是:Header头、Payload有效载荷、Signature签名。因此,JWT通常如下所示:xxxxx.yyyyy.zzzzz(Header.Payload.Signature)。

因为微软没有击败Flash。 有趣的是,Visual Studio安装程序对新家庭成员.Net Core十分重视。当选择构建ASP.Net Web应用程序或想使用容器跨平台应用程序时,.Net Core是将

2.1.1Header头

现在有 WebUtility.UrlDecode() 与 Microsoft.AspNetCore.Http.HttpContext Microsoft.AspNetCore新的对象没有我们常用HttpUtility.UrlDecode这个方法,将URL 中传输而编码的字

标头通常由两部分组成:令牌的类型,即JWT,以及正在使用的签名算法,例如HMAC SHA256或RSA。例如:

{ "alg": "HS256", "typ": "JWT"}

然后,这个JSON被编码为Base64Url,形成JWT的第一部分。

2.1.2Payload有效载荷

Payload部分也是一个JSON对象,用来存放实际需要传递的数据。JWT规定了7个官方字段,供选用。 iss (issuer):签发人 exp (expiration time):过期时间 sub (subject):主题 aud (audience):受众 nbf (Not Before):生效时间 iat (Issued At):签发时间 jti (JWT ID):编号

除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。例如:

{ "sub": "1234567890", "name": "John Doe", "admin": true}

注意,JWT默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。这个JSON对象也要使用Base64URL算法转成字符串。

2.1.3.Signature签名

Signature部分是前两部分的签名,防止数据篡改。首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用Header里面指定的签名算法(默认是HMAC SHA256),按照下面的公式产生签名:

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

签名用于验证消息在此过程中未被更改,并且,在使用私钥签名的令牌的情况下,它还可以验证JWT的发件人是否是它所声称的人。把他们三个全部放在一起,输出是三个由点分隔的Base64-URL字符串,可以在HTML和HTTP环境中轻松传递,而与基于XML的标准(如SAML)相比更加紧凑。下面显示了一个JWT,它具有先前的头和有效负载编码,并使用机密签名:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoid3prNzAzIiwibmJmIjoiMTU5MjE0MzkzNyIsImV4cCI6MTU5MjE0Mzk5OCwiaXNzIjoiYXV0aC5qd3QuY2MiLCJhdWQiOiJkZW5nd3V8MjAyMC82LzE0IDIyOjEyOjE5In0.4RiwhRy0rQkZjclOFWyTpmW7v0AMaL3aeve1L-eWIz0

其实一般发送用户名和密码获取token那是由Identity4来完成的,包括验证用户,生成JwtToken。但是项目这里是由System.IdentityModel.Tokens类库来生成JwtToken。最后返回jwt令牌token给用户。JwtToken解码可以通过https://jwt.io/中进行查看。

3.项目演示

3.1APIGateway项目

在该项目中启用身份认证来保护下游api服务,使用JwtBearer认证,将默认的身份验证方案设置为TestKey。在appsettings.json文件中配置认证中密钥(Secret)跟受众(Aud)信息:

{ "Audience": { "Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==", "Iss": "http://www.c-sharpcorner.com/members/catcher-wong", "Aud": "Catcher Wong" }}

Startup添加身份认证代码如下:

public void ConfigureServices(IServiceCollection services){ //获取appsettings.json文件中配置认证中密钥(Secret)跟受众(Aud)信息 var audienceConfig = Configuration.GetSection("Audience"); //获取安全秘钥 var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"])); //token要验证的参数集合 var tokenValidationParameters = new TokenValidationParameters { //必须验证安全秘钥 ValidateIssuerSigningKey = true, //赋值安全秘钥 IssuerSigningKey = signingKey, //必须验证签发人 ValidateIssuer = true, //赋值签发人 ValidIssuer = audienceConfig["Iss"], //必须验证受众 ValidateAudience = true, //赋值受众 ValidAudience = audienceConfig["Aud"], //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 ValidateLifetime = true, //允许的服务器时间偏移量 ClockSkew = TimeSpan.Zero, //是否要求Token的Claims中必须包含Expires RequireExpirationTime = true, }; //添加服务验证,方案为TestKey services.AddAuthentication(o => { o.DefaultAuthenticateScheme = "TestKey"; }) .AddJwtBearer("TestKey", x => { x.RequireHttpsMetadata = false; //在JwtBearerOptions配置中,IssuerSigningKey(签名秘钥)、ValidIssuer(Token颁发机构)、ValidAudience(颁发给谁)三个参数是必须的。 x.TokenValidationParameters = tokenValidationParameters; }); //添加Ocelot网关服务时,包括Secret秘钥、Iss签发人、Aud受众 services.AddOcelot(Configuration);}public async void Configure(IApplicationBuilder app, IHostingEnvironment env){ //使用认证服务 app.UseAuthentication(); //使用Ocelot中间件 await app.UseOcelot();}

3.1.1Identity Server承载JWT Token

在第二小节介绍JWT Token认证时候,我们都知道一般发送用户名和密码获取Token那是由Identity4来完成的,包括验证用户,生成JWT Token。也就是说Identity Server承载了JWT Token认证功能。为了使用IdentityServer承载Token,请像往常一样在ConfigureServices中使用方案(密钥)注册IdentityServer服务。如果您不知道如何执行此操作,请查阅IdentityServer文档。

public void ConfigureServices(IServiceCollection services){ var authenticationProviderKey = "TestKey"; Action<IdentityServerAuthenticationOptions> options = o => { o.Authority = "https://whereyouridentityserverlives.com"; o.ApiName = "api"; o.SupportedTokens = SupportedTokens.Both; o.ApiSecret = "secret"; }; services.AddAuthentication() .AddIdentityServerAuthentication(authenticationProviderKey, options); services.AddOcelot();}

在Identity4中是由Authority参数指定OIDC服务地址,OIDC可以自动发现Issuer, IssuerSigningKey等配置,而o.Audience与x.TokenValidationParameters = new TokenValidationParameters { ValidAudience = "api" }是等效的。

3.2AuthServer项目

此服务主要用于客户端请求受保护的资源服务器时,认证后产生客户端需要的JWT Token,生成JWT Token关键代码如下:

[Route("api/[controller]")]public class AuthController : Controller{ private IOptions<Audience> _settings; public AuthController(IOptions<Audience> settings) { this._settings = settings; } /// <summary> ///用户使用 用户名密码 来请求服务器 ///服务器进行验证用户的信息 ///服务器通过验证发送给用户一个token ///客户端存储token,并在每次请求时附送上这个token值, headers: {'Authorization': 'Bearer ' + token} ///服务端验证token值,并返回数据 /// </summary> /// <param name="name"></param> /// <param name="pwd"></param> /// <returns></returns> [HttpGet] public IActionResult Get(string name, string pwd) { //验证登录用户名和密码 if (name == "catcher" && pwd == "123") { var now = DateTime.UtcNow; //添加用户的信息,转成一组声明,还可以写入更多用户信息声明 var claims = new Claim[] { //声明主题 new Claim(JwtRegisteredClaimNames.Sub, name), //JWT ID 唯一标识符 new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), //发布时间戳 issued timestamp new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(), ClaimValueTypes.Integer64) }; //下面使用 Microsoft.IdentityModel.Tokens帮助库下的类来创建JwtToken //安全秘钥 var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_settings.Value.Secret)); //声明jwt验证参数 var tokenValidationParameters = new TokenValidationParameters { //必须验证安全秘钥 ValidateIssuerSigningKey = true, //赋值安全秘钥 IssuerSigningKey = signingKey, //必须验证签发人 ValidateIssuer = true, //赋值签发人 ValidIssuer = _settings.Value.Iss, //必须验证受众 ValidateAudience = true, //赋值受众 ValidAudience = _settings.Value.Aud, //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 ValidateLifetime = true, //允许的服务器时间偏移量 ClockSkew = TimeSpan.Zero, //是否要求Token的Claims中必须包含Expires RequireExpirationTime = true, }; var jwt = new JwtSecurityToken( //jwt签发人 issuer: _settings.Value.Iss, //jwt受众 audience: _settings.Value.Aud, //jwt一组声明 claims: claims, notBefore: now, //jwt令牌过期时间 expires: now.Add(TimeSpan.FromMinutes(2)), //签名凭证: 安全密钥、签名算法 signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256) ); //生成jwt令牌(json web token) var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); var responseJson = new { access_token = encodedJwt, expires_in = (int)TimeSpan.FromMinutes(2).TotalSeconds }; return Json(responseJson); } else { return Json(""); } }}public class Audience{ public string Secret { get; set; } public string Iss { get; set; } public string Aud { get; set; }}

appsettings.json文件中配置认证中密钥(Secret)跟受众(Aud)信息:

{ "Audience": { "Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==", "Iss": "http://www.c-sharpcorner.com/members/catcher-wong", "Aud": "Catcher Wong" }}

3.3CustomerAPIServices项目

该项目跟APIGateway项目是一样的,为了保护下游api服务,使用JwtBearer认证,将默认的身份验证方案设置为TestKey。在appsettings.json文件中配置认证中密钥(Secret)跟受众(Aud)信息:

{ "Audience": { "Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==", "Iss": "http://www.c-sharpcorner.com/members/catcher-wong", "Aud": "Catcher Wong" }}

Startup添加身份认证代码如下:

public void ConfigureServices(IServiceCollection services){ //获取appsettings.json文件中配置认证中密钥(Secret)跟受众(Aud)信息 var audienceConfig = Configuration.GetSection("Audience"); //获取安全秘钥 var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"])); //token要验证的参数集合 var tokenValidationParameters = new TokenValidationParameters { //必须验证安全秘钥 ValidateIssuerSigningKey = true, //赋值安全秘钥 IssuerSigningKey = signingKey, //必须验证签发人 ValidateIssuer = true, //赋值签发人 ValidIssuer = audienceConfig["Iss"], //必须验证受众 ValidateAudience = true, //赋值受众 ValidAudience = audienceConfig["Aud"], //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 ValidateLifetime = true, //允许的服务器时间偏移量 ClockSkew = TimeSpan.Zero, //是否要求Token的Claims中必须包含Expires RequireExpirationTime = true, }; //添加服务验证,方案为TestKey services.AddAuthentication(o => { o.DefaultAuthenticateScheme = "TestKey"; }) .AddJwtBearer("TestKey", x => { x.RequireHttpsMetadata = false; //在JwtBearerOptions配置中,IssuerSigningKey(签名秘钥)、ValidIssuer(Token颁发机构)、ValidAudience(颁发给谁)三个参数是必须的。 x.TokenValidationParameters = tokenValidationParameters; }); services.AddMvc();}public void Configure(IApplicationBuilder app){ //使用认证服务 app.UseAuthentication(); app.UseMvc();}

在CustomersController下添加一个需要认证方法,一个不需要认证方法:

[Route("api/[controller]")]public class CustomersController : Controller{ //添加认证属性 [Authorize] [HttpGet] public IEnumerable<string> Get() { return new string[] { "Catcher Wong", "James Li" }; } [HttpGet("{id}")] public string Get(int id) { return $"Catcher Wong - {id}"; }}

3.4ClientApp项目

该项目是用来模拟客户端访问资源服务器整个认证流程测试项目,在Program主程序可以看到如下代码:

class Program{ static void Main(string[] args) { HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Clear(); client.BaseAddress = new Uri("http://localhost:9000"); // 1. without access_token will not access the service // and return 401 . var resWithoutToken = client.GetAsync("/customers").Result; Console.WriteLine($"Sending Request to /customers , without token."); Console.WriteLine($"Result : {resWithoutToken.StatusCode}"); //2. with access_token will access the service // and return result. client.DefaultRequestHeaders.Clear(); Console.WriteLine("\nBegin Auth...."); var jwt = GetJwt(); Console.WriteLine("End Auth...."); Console.WriteLine($"\nToken={jwt}"); client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwt}"); var resWithToken = client.GetAsync("/customers").Result; Console.WriteLine($"\nSend Request to /customers , with token."); Console.WriteLine($"Result : {resWithToken.StatusCode}"); Console.WriteLine(resWithToken.Content.ReadAsStringAsync().Result); //3. visit no auth service Console.WriteLine("\nNo Auth Service Here "); client.DefaultRequestHeaders.Clear(); var res = client.GetAsync("/customers/1").Result; Console.WriteLine($"Send Request to /customers/1"); Console.WriteLine($"Result : {res.StatusCode}"); Console.WriteLine(res.Content.ReadAsStringAsync().Result); Console.Read(); } private static string GetJwt() { HttpClient client = new HttpClient(); client.BaseAddress = new Uri( "http://localhost:9000"); client.DefaultRequestHeaders.Clear(); var res2 = client.GetAsync("/api/auth?name=catcher&pwd=123").Result; dynamic jwt = JsonConvert.DeserializeObject(res2.Content.ReadAsStringAsync().Result); return jwt.access_token; }}

运行项目看看测试结果:

结合代码,我们能看到当客户端通过Ocelot网关访问下游服务http://localhost:9000/api/Customers/Get方法时候,因为该方法是需要通过认证才返回处理结果的,所以会进行JWT Token认证,如果发现没有Token,Ocelot则返回http状态代码401拒绝访问。如果我们通过GetJwt方法在AuthServer服务上登录认证获取到授权Token,然后再访问该资源服务器接口,立即就会返回处理结果,通过跟而未加认证属性的http://localhost:9000/api/Customers/Get/{id}方法对比,我们就知道,Ocelot认证已经成功了!

4.总结

该章节只是结合demo项目简单介绍在Ocelot中如何使用JWT Token认证。其实正式环境中,Ocelot是应该集成IdentityServer认证授权的,同样的通过重写Ocelot中间件我们还可以把configuration.json的配置信息存储到数据库或者缓存到Redis中。

参考文献:

Ocelot官网

到此这篇关于ASP.NET Core3.1 Ocelot认证的实现的文章就介绍到这了,更多相关ASP.NET Core3.1 Ocelot认证内容请搜索真格学网以前的文章或继续浏览下面的相关文章希望大家以后多多支持真格学网! 您可能感兴趣的文章:ASP.NET Core3.1 Ocelot路由的实现ASP.NET Core3.1 Ocelot负载均衡的实现

asp.net mvc5只能运行在Windows,一般通过IIS发布;asp.net core开源,可跨平台,能够发布到Linux等系统上。asp.net core做了很多的整合工作,目前来说完成了最基本的一部分类库的迁移。从前景上来说,asp.net core肯定是以后的一种潮流,随着docker等技术的普及,跨平台的重要性凸显,必须要使用asp.net core编写的接口才能发布到linux中,也就是asp.net core编写的接口可以做成docker的镜像发布,而asp.net mvc5不能。所以最终肯定是会慢慢都转移到asp.net core上来。但是这需要一个比较久的过程。因为从asp.net mvc5转移到asp.net core需要一定时间的学习,即使在国外也需要一定过程。而国内由于语言环境、开发工具(需要VS2015才能进行asp.net core的开发)等的原因,肯定需要更久。国内的技术一直以来也比较保守。如果单纯的以在国内找个开发的工作的话,建议先熟悉下asp.net mvc5。如果确实有跨平台的需求,或者团队成员都对新技术有很高的热情,从事的也是全新的项目的话,就使用asp.net core吧内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • asp.net 身份验证(分目录验证篇)
  • asp.net+web服务实现软件共享
  • aspnetajaxpager,asp.net通用无刷新ajax分页控件,支持多样式多数
  • asp.net读取rss的方法
  • asp.net网站开发包wq.dll打包下载
  • asp.net文件上传解决方案(图片上传、单文件上传、多文件上传、检
  • asp.net中使用sqlite数据库的方法
  • 创建一个asp.net mvc5项目的实现方法(图文)
  • window.showmodaldialog两次加载问题清除缓存方法
  • iis7伪静态web.config配置的方法和规则
  • 请问:ASP.net mvc5和asp.net.core有什么区别呢?在今后的发展...
  • ASP.net mvc5和asp.net.core有什么区别呢?前景如何?
  • 如何评价asp.net core
  • 如何在ASP NET Core中实现CORS跨域
  • Asp.Net Core 设置 .html 页为起始页
  • xp支持asp.net core2.0么
  • 微软BUG Bounty悬赏项目扩展至.NET Core和ASP.NET Core
  • 如何在ASP NET Core中实现CORS跨域
  • netstandard和.netcore的区别
  • microsoft.aspnetcore.http 在哪个dll中
  • asp c# .net 通过onclick="window.rightbar.location.href='../c...
  • net core 是最新的.net版本吗
  • 如何查看 net core版本
  • Net 框架和.Net Core,我该用哪个?怎么选
  • .net core里面用什么代替System.Web.Service
  • 未来.net core 是什么样
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全基础应用实用技巧自学过程首页asp.net实用技巧asp.net core3.1 ocelot路由的实现asp.net core3.1 ocelot负载均衡的实现asp.net 身份验证(分目录验证篇)asp.net+web服务实现软件共享aspnetajaxpager,asp.net通用无刷新ajax分页控件,支持多样式多数asp.net读取rss的方法asp.net网站开发包wq.dll打包下载asp.net文件上传解决方案(图片上传、单文件上传、多文件上传、检asp.net中使用sqlite数据库的方法创建一个asp.net mvc5项目的实现方法(图文)window.showmodaldialog两次加载问题清除缓存方法iis7伪静态web.config配置的方法和规则未将对象引用设置到对象的实例 (java正则表达式 pattern和matcheasp.net(c#)网页跳转七种方法小结未能加载文件或程序集“xxx”或它asp.net“服务器应用程序不可用”asp.net中的几种弹出框提示基本实asp.net gridview 72般绝技asp.net生成excel并导出下载五种asp.net对路径"xxxxx"asp.net汉字转拼音和获取汉字首字asp.net下模态对话框关闭之后继续执行服务使用jquery uploader显示文件上传进度asp.net core 3.0迁移的完美避坑指南repeater全选删除和分页实现思路及代码asp.net获取真实ip的方法.net core如何对mongodb执行多条件查询详解asp.net母版页元素id不一致的体现将选择的图片显示在listview中,并显示filasp.net操作mysql数据库的实例代码讲解asp.net fileupload控件实现文件格式判断
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved