-->

在 C# 中使用缓存

缓存的概念和优缺点这里就不介绍了。我主要介绍一下使用方法。

1。在 www.sxzhongrui.com 中使用页面缓存的方法很简单。只需要在aspx页面顶部添加一句语句:

  <%@ OutputCache Duration="100" VaryByParam="none" %>

   持续时间:缓存时间(以秒为单位),必填属性

2。使用微软自己的类库System.Web.Caching

对于新手来说,不建议直接使用微软提供的类库,因为这样并不能提供深入的理解。那么这里我就带领大家自己写一套缓存的操作方法,以便大家能够更清楚的理解。

话不多说,让我们开始输入代码。

1。首先,模拟数据源。新建一个类,写一个数据操作方法(这个方法费时间,费资源)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
使用系统;
使用 System.Collections.Generic;
使用 System.Linq;
使用 System.Text;
使用 System.Threading;
使用 System.Threading.Tasks;
命名空间缓存
{
公共 数据源
{
///
///模拟从数据库读取数据
/// 耗时耗CPU
///
///
公共 静态 int GetDataByDB(int计数)
{
       Console.WriteLine("-----GetDataByDB-----");
int 结果 = 0; 我9999999; i++)
      {
结果 += i;
}
Thread.Sleep(2000);
        返回结果;
}
}
}

2.编写缓存操作类

  2.1 构造字典容器存储缓存数据,并设置权限为private,防止任意访问造成数据不安全

//缓存容器 private static Dictionary CacheDictionary = new Dictionary();

2.2 构造三个方法(向缓存容器添加数据、从缓存容器获取数据、判断缓存是否存在)

/// /// 添加缓存 /// 公共静态无效添加(字符串键,对象值) { CacheDictionary.Add(键,值); } /// /// 获取缓存 /// public static T Get(字符串键) { 返回 (T)CacheDictionary[key]; } /// /// 判断缓存是否存在 /// /// /// 公共静态布尔存在(字符串键) { 返回 CacheDictionary.ContainsKey(key); }

3。程序入口编写测试方法

3.1 我们先来看看正常情况下不适用缓存时它的执行效率有多慢

使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用系统文本;使用 System.Threading.Tasks; 命名空间缓存 { 班级计划 { 静态无效主(字符串[]参数) { for (int i = 1; i < 6; i++) { Console.WriteLine($"------第 {i} 个请求 ------"); int 结果 = DataSource.GetDataByDB(666); Console.WriteLine($"第{i}次请求获取的数据为:{result}"); } } } }

3.2 接下来我们编写缓存试用方法。概念简单来说就是根据key去字典容器中查找是否有对应的缓存数据。如果有则直接调用。如果没有,则会生成并存储在字典容器中。

使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用系统文本; 使用 System.Threading.Tasks; 命名空间缓存 { 班级计划 { 静态无效主(字符串[]参数) { for (int i = 1; i < 6; i++) { Console.WriteLine($"------第 {i} 个请求 ------"); //int 结果 = DataSource.GetDataByDB(666); 整数结果 = 0; //key的名称必须保证请求的准确性。 DataSource GetDataByDB 666 是不可或缺的。 字符串键=“DataSource_GetDataByDB_666”; if (CacheHelper.Exsits(key)) { //缓存存在,直接获取原始数据 结果 = CacheHelper.Get(key); } 别的 { //缓存不存在,生成缓存并添加到容器中 结果 = DataSource.GetDataByDB(666);CacheHelper.Add(键,结​​果); } Console.WriteLine($"第{i}次请求获取的数据为:{result}"); } } } }

3.3 看看加了缓存后效率如何

4。您可以看到它并立即完成。至此,缓存的使用就基本完成了。但让我们回顾一下。如果一个系统有成百上千个地方使用了缓存,那岂不是需要写成百上千个if else来判断缓存是否存在然后获取?

答案是显而易见的,而且绝对不合理。所以我们需要优化代码。

4.1 缓存操作类(CacheHelper)编写通用的获取方法

/// /// 缓存获取方法 /// /// /// 缓存字典容器对应的key /// 委托方法传入操作对象 /// public static T GetCache(字符串键,Func func) { T t = 默认值(T); if (CacheHelper.Exsits(key)) { //缓存存在,直接获取原始数据 t = CacheHelper.Get(key); } 别的 { //缓存不存在,生成缓存并添加到容器中 t = func.Invoke(); CacheHelper.Add(key, t); } 返回t; }

4.2 程序入口被调用,传入的委托参数是lamad表达式优化后的代码

使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用系统文本; 使用 System.Threading.Tasks; 命名空间缓存 { 班级计划 { 静态无效主(字符串[]参数) { for (int i = 1; i < 6; i++) {Console.WriteLine($"------第 {i} 个请求 ------"); 整数结果 = 0; //key的名称必须保证请求的准确性。 DataSource GetDataByDB 666 是不可或缺的。 字符串键=“DataSource_GetDataByDB_666”; //将需要执行的数据获取操作写入委托传入方法中(重点) //Func func = new Func(() => { return DataSource.GetDataByDB(666); }); 结果 = CacheHelper.GetCache(key, () => DataSource.GetDataByDB(666)); Console.WriteLine($"第{i}次请求获取的数据为:{result}"); } } } }

至此,缓存的使用就基本结束了。最值得一提的是,当数据量较小、重​​复查询量较大时,应该使用缓存。因为缓存也会消耗内存,所以服务器内存是有限的!

ajax 请求基于restFul 的WebApi(发布、获取、删除、放置)

最近浏览招聘软件,看到有些公司要求能够编写和请求restful webapi。正好这段时间我空闲时间很多,就打开VS准备开始自慰。

1。什么是安息?

restFul是一个符合rest架构风格的网络API接口。

rest 是一种软件架构的编码风格。它是一种基于网络应用而设计开发的编码方法,可以降低开发的复杂度,提高程序的可扩展性(增减问题)。

常见的几种操作类型:get(查询)、post(添加)、put(修改)、delete(删除)

2.restFul标准WebApi构建并部署在iis上

这里为了方便,使用了EF框架,创建读/写控制器时直接引用模型类

使用系统; 使用 System.Collections.Generic; 使用系统数据; 使用 System.Data.Entity; 使用系统.数据.实体.基础设施; 使用 System.Linq; 使用www.sxzhongrui.com; 使用 System.Net.Http; 使用 System.Web.Http; 使用 System.Web.Http.Description; 使用网络API; 命名空间 webapi.Controllers { 公共类ProductsController:ApiController { 私有 DtoolsEntities db = new DtoolsEntities(); // 获取:api/产品 [http获取] 公共 IQueryable GetProduct() { 返回 db.Product.OrderByDescending(p => p.AddDate).Take(10); } // 获取:api/产品/5 [http获取] [响应类型(类型(产品))] 公共 IHttpActionResult GetProduct(int id) { 产品产品 = db.Product.Find(id); 如果(产品==空) { 返回未找到(); } 返回确定(产品); } // PUT: api/Products/5 更新 [HttpPut] [响应类型(typeof(void))] 公共 IHttpActionResult PutProduct(int id, 产品产品) {if (!ModelState.IsValid) { 返回 BadRequest(ModelState); } if (id != 产品.Id) { 返回 BadRequest(); } 产品.AddDate = www.sxzhongrui.com; db.Entry(产品).State = EntityState.Modified; 尝试 { db.SaveChanges(); } 捕获(DbUpdateConcurrencyException) { if (!ProductExists(id)) { 返回未找到(); } 别的 { 扔; } } 返回 StatusCode(HttpStatusCode.NoContent); } // POST: api/产品 [http邮报] [响应类型(类型(产品))] 公共 IHttpActionResult PostProduct(产品产品) { if (!ModelState.IsValid) { 返回 BadRequest(ModelState); } 产品.AddDate = www.sxzhongrui.com; db.Product.Add(产品); db.SaveChanges(); return CreatedAtRoute("DefaultApi", new { id = 产品.Id }, 产品); } // 删除:api/产品/5 [http删除] [响应类型(类型(产品))] 公共 IHttpActionResult 删除产品(int id) { 产品产品 = db.Product.Find(id); 如果(产品==空) { 返回未找到(); } db.Product.Remove(产品); db.SaveChanges();返回确定(产品); } 受保护的覆盖无效处置(布尔处置) { 如果(处置) { db.Dispose(); } 基础.处置(处置); } 私有 bool ProductExists(int id) { return db.Product.Count(e => www.sxzhongrui.com == id) > 0; } } }

最好在每个控制器前根据类型指定[HttpGet][HttpPost][HttpPut][HttpDelete],因为服务器会根据请求类型自动映射匹配控制器名称,加上属性以避免错误。

在weiapi设置中指定json格式,避免数据类型异常

webapi的构建基本没有问题。下一步是在 IIS 上部署。我这里就不描述了。这里不知道怎么部署IIS(会不会被打?)

3。编写前端ajax请求页面

产品名称 产品品牌 ASIN SKU

前后端代码已经写好了。只剩下测试了。想都不用想肯定会出现问题,因为涉及到跨域请求等,接下来我们就为大家解决问题。

问题一:ajax请求涉及cors跨域,请求失败

  问题介绍及原因分析:

         CORS 是一个 W3C 标准,它的全称是“跨域资源共享”。它允许浏览器向跨源服务器发出 XMLHttpRequest 请求。目前基本上所有的浏览器都实现了CORS标准。事实上,几乎所有的浏览器ajax请求都是基于CORS机制的。
         跨域问题一般发生在Javascript发起AJAX调用时,因为浏览器对此类请求的权限较低,通常只允许调用本域内的资源,除非目标服务器明确告知其允许跨域调用。域调用。因此,虽然跨域问题是由浏览器的行为引起的,但解决的方法是          位于 服务器。因为不可能要求所有客户端都降低安全性。

解决方案:

                                                                                                                                                                                                                                                                                        ​

    

问题2:get、post可以正常请求,但是put、delete却出现405(Method Not allowed)。注意:我提交了Put请求,浏览器响应了Request Method:PUT

  问题介绍及原因分析:

         有人会问:我刚刚设置了服务器允许putdelete请求,浏览器上服务器的响应也显示支持putdelete。为什么服务器仍然拒绝?

         一切都是由iis的WebDAV(Web Distribution Authorization Versioning)发布引起的。 WebDAV是HTTP协议的扩展,增加了很多管理服务器上文件的方法。如果安装了 WebDAV,则所有 iis 站点都将默认使用 WebDAV 模块和 WebDAV 处理程序。

        WebDAV处理程序的默认配置将处理以下方法:PropFind,PropPatch,Mkcol,put,复制,DELETE,移动,锁,锁,解锁。因此,浏览器发送的 put delete 请求会被拦截并交给 WebDAV Handler 处理,WebDAV Handler 会默认拒绝该请求

解决方案:

        既然找到了问题,那么解决办法就是删除配置文件中的ebDAVModule和WebDAVHandler或者直接从系统中删除WebDAV

问题3:提出删除请求,再次出现405(方法不允许)

         大家有没有发现,问题2中,如果提交put请求,Request Method就是put,如果提交Delete请求,Request Method就是Delete。然而,这里所有都是选项。那么这个 OPTIONS 到底是什么?

         预检请求(预检请求)
         预检请求是 CORS 中透明的服务器验证机制。预检请求首先需要向另一个域名的资源发送HTTP OPTIONS请求头。目的是判断实际发送的请求是否安全
         以下2种情况需要预检查:
         1.简单请求,例如Content-Type为application/xml或text/xml的POST请求;
         2. 在请求中设置自定义请求。定义 header,如 X-JSON、X-MENGXIANHUI 等

         事实证明,如果put或delete请求的header设置为XMLHttpRequest.setRequestHeader("Content-Type", "application/json"),则之前已经发送过预检请求。

解决方案:

          因为是额外的请求,所以我们可以在服务器端过滤掉它。

         Global.asac 只需添加以下方法

使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用系统.Web; 使用 System.Web.Http; 使用 System.Web.Mvc; 使用 System.Web.Optimization; 使用 System.Web.Routing; 命名空间webapi { 公共类 WebApiApplication :System.Web.HttpApplication {protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } protected void Application_BeginRequest() { if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS") { 响应.End(); } } } }

到这里,ajax跨域实现RestFul请求,已经是能正常运行了。剩下的只是安全校验、身份认证、异常记录等,就能放到生产环境了。这里就不多做描述了,毕竟博主还是上班族...

如有错误,欢迎大家指正~

让 .Net 更方便的导入导出Excel

关闭

赞赏
返回顶部