我们在asp.net 开发中已经封装了最强大的HttpContext,我们可以在HttpContext中可以获取到几乎任何想获取的东西,也可以在HttpContext写入需要返回客户端的信息。但是这些还远远不能满足一些要求,比如在任何地方可以获取到登录用户的信息等等。

  之前获取登录用户的信息基本上都是哪里用到就从session里获取,这样做的缺点很多就不一一说明了。

  现在我们通过封装一个WebWorkContext就可以随用随取,不用再次从session、数据库或者缓存中获取了。

1、首先新建类WebWorkContext

  为了演示方便就不建立多个项目了,WebWorkContext就直接建在Mvc的Model中了。

 public class WebWorkContext
{ /// <summary>
/// 判断用户是否登录
/// </summary>
public bool IsLogin { get; set; } /// <summary>
/// 用户ID
/// </summary>
public int UserId { get; set; } /// <summary>
/// 用户名称
/// </summary>
public string UserName { get; set; } /// <summary>
/// 用户邮箱
/// </summary>
public string UserEmail { get; set; } /// <summary>
/// 是否是Get请求
/// </summary>
public bool IsGet { get; set; } /// <summary>
/// 是否是Ajax请求
/// </summary>
public bool IsAjax { get; set; } }

2、在Controller中新建类BaseController,并继承Controller

  刚刚提出刚才的需求就会有很多人想到用继承了,确实是用继承,不过后面也许会有你想不到的好处。

  public class BaseController : Controller
{
/// <summary>
/// 创建上下文Context
/// </summary>
protected WebWorkContext WorkContext = new WebWorkContext(); /// <summary>
/// 重写Controller中的Initialize方法。在此方法中获取用户和其他的信息
/// </summary>
/// <param name="requestContext"></param>
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext); // 判断用户信息
if (!string.IsNullOrEmpty(Convert.ToString(Session["USERID"])))
{
WorkContext.IsLogin = true;
WorkContext.UserId = Convert.ToInt32(Session["USERID"]);
WorkContext.UserName = Convert.ToString(Session["USERNAME"]);
WorkContext.UserEmail = Convert.ToString(Session["USEREMAIL"]);
} // 判断是否是Get请求
WorkContext.IsGet = requestContext.HttpContext.Request.HttpMethod == "GET"; // 判断是否是Ajax请求
WorkContext.IsAjax = requestContext.HttpContext.Request.IsAjaxRequest(); } }

3.1、在Controller中使用WebWorkContext

  我们刚才所做的所有代码都是为了方便使用一些封装的信息,在Controller中使用WebWorkContext是最简单的一种使用方式,只要Controller继承新建的BaseController就可使用WebWorkContext中的任何东西。

  public class HomeController : BaseController
{
public ActionResult Index()
{
var userId = WorkContext.UserId;
var userName = WorkContext.UserName;
return View();
}
}
}

3.2、在View(cshtml)中使用WebWorkContext

  重点来了,之前的几步对于有一点工作经验的都可以很简单的完成,但是在View中使用自定义的类有很多童鞋还是不明白其中的道理。

  第一首先要明白我们可以在View中使用比如Html/Ajax/Model之类的东西,是因为我们的页面都继承了一个类WebViewPage。

  明白这个道理以后就很简单了,我们只要让我们的View继承我们自定义的一个类,然后让我们自定义的类继承WebViewPage即可,然后我们就可以在我们自定义的类中做你想做的任何事了。

  还要明白一个很重要的知识点,就是在哪更改View继承类,当然微软已经为我们扩展做好了,在每个Views文件夹下都有个web.config,找到pageBaseType,更改值为我们自定义类的即可。

3.2.1、新建自定义WebViewPage类(WebWorkContextWebViewPage)

  public abstract class WebWorkContextWebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
{
public WebWorkContext WorkContext;
public sealed override void InitHelpers()
{
base.InitHelpers();
BaseController baseController = ((this.ViewContext.Controller) as BaseController);
if (baseController != null)
{
WorkContext = baseController.WorkContext;
} }
}

3.2.2、更改View的继承,在Views文件夹中的web.config中找到pageBaseType,值更改为我们自定义的类就行了。

  <system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="WebWorkContextDemo.WebWorkContextWebViewPage">
</pages>
</system.web.webPages.razor>

3.2.3、最后一步就是使用了,这个更简单了直接调用即可。

  这里需要注意的是,我们观察代码就知道,View中的WebWorkContext其实是获取BaseController中的,所以使用WebWorkContext的View所对应的Controller必须继承BaseController

 @{
ViewBag.Title = "Home Page";
} 用户的邮箱是: @WorkContext.UserEmail<br />
用户名是: @WorkContext.UserName<br /> @{
var id = WorkContext.UserId;
}

4、【扩展】,在BLL和DAL中使用WebWorkContext

  在Asp.net MVC中使用WebWorkContext已经结束了,但是有很多的时候在需要在其他的层也需要把一些重要的信息沉淀下去,当然最简单的就是每次调用方法把需要的值通过方法参数传递至BLL和DAL。当然这样不是最优的解决方案,如果一个类中的很多方法都需要一个参数,我们肯定不会每次都通过方法传递的,我们会通过设置属性,或者通过一个方法设置值,然后在调用我们需要的方法。

  这样说就简单了,我们可以在Action每次调用BLL方法之前先设置我们的WebWorkContext就可以了。

  public class HomeController : BaseController
{ UserBLL bll = new UserBLL(); /// <summary>
/// 重写Initialize,给BLL设置WebWorkContext
/// </summary>
/// <param name="requestContext"></param>
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
    bll.WorkContext = WorkContext;
}
}

  这样我们就可以在BLL中任意的使用WebWorkContext了。

  同样的道理也可以设置DAL中的WebWorkContext。

BLL:

 public class UserBLL : BaseBLL
{
UserDAL dal = new UserDAL(); public override WebWorkContext WorkContext
{
get
{
return base.WorkContext;
} set
{
base.WorkContext = value;
dal.WorkContext = value;
}
} public string GetBLLUserAge()
{
return WorkContext.UserId.ToString();
}
}

DAL:

 public class UserDAL : BaseDAL
{
public string GetUserAge()
{
return WorkContext.UserId.ToString();
}
}

在BaseBLL和BaseDAL中都只有一段代码,设置可以重写的WebWorkContext。

   public virtual WebWorkContext WorkContext { get; set; }

总结:这样我们就可以几乎在整个解决方案中使用WebWorkContext了,这样每次使用的时候直接用就可以,不需要再次判断获取。

源码Github:https://github.com/Emrys5/Asp.MVC-01-WebWorkContext

系列课程

[asp.net mvc 奇淫巧技] 01 - 封装上下文 - 在View中获取自定义的上下文的更多相关文章

  1. [asp.net mvc 奇淫巧技] 02 - 巧用Razor引擎在Action内生成Html代码

    在web开发中经常会遇到在内部代码中获取Html,这些Html是需要和数据进行一起渲染.并不是直接把Html代码返回给客户端.这样的做法有很多应用场景,例如分页.Ajax一次性获取几段Html片段.生 ...

  2. [asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper

    一.需求 我们在开发中经常会遇到一些枚举,而且这些枚举类型可能会在表单中的下拉中,或者单选按钮中会用到等. 这样用是没问题的,但是用过的人都知道一个问题,就是枚举的命名问题,当然有很多人枚举直接中文命 ...

  3. [asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗?

    在QQ群或者一些程序的交流平台,经常会有人问:我怎么传一个数组在Action中接收.我传的数组为什么Action的model中接收不到.或者我在ajax的data中设置了一些数组,为什么后台还是接收不 ...

  4. [asp.net mvc 奇淫巧技] 05 - 扩展ScriptBundle,支持混淆加密javascript

    一.需求: 在web开发中,经常会处理javascript的一些问题,其中就包括js的压缩,合并,发布版本以及混淆加密等等问题.在asp.net 开发中我们使用ScriptBundle已经可以解决ja ...

  5. [asp.net mvc 奇淫巧技] 06 - 也许你的项目同一个用户的请求都是同步的

    一.感慨 很久前看到一篇博客中有句话大致的意思是:“asp.net 程序性能低下的主要原因是开发人员技术参差不齐”,当时看到这句话不以为然,然而时间过的越久接触的.net 开发人员越多就越认同这句话: ...

  6. ASP.NET Core 奇淫技巧之伪属性注入

    一.前言 开局先唠嗑一下,许久未曾更新博客,一直在调整自己的状态,去年是我的本命年,或许是应验了本命年的多灾多难,过得十分不顺,不论是生活上还是工作上.还好当我度过了所谓的本命年后,许多事情都在慢慢变 ...

  7. [javascript 实践篇]——那些你不知道的“奇淫巧技”

    1. 空(null, undefined)验证 刚开始,我是比较蠢的验证(我还真是这样子验证的) if (variable1 !== null || variable1 !== undefined | ...

  8. asp.net mvc 如何在View中获取Url参数的值

    如果url是 /home/index?id=3 直接Request就ok. 但是如果路由设定为:{controller}/{action}/{id} url是 /home/index/3   这时想在 ...

  9. C# -- 等待异步操作执行完成的方式 C# -- 使用委托 delegate 执行异步操作 JavaScript -- 原型:prototype的使用 DBHelper类连接数据库 MVC View中获取action、controller、area名称、参数

    C# -- 等待异步操作执行完成的方式 C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] ...

随机推荐

  1. css基础总结一

    最近在弄一个简单管理系统的前端,所以打算将做项目的一些个人感想以及总结简单罗列下,当然,主要针对前端的基础部分以及一些常用的前端个人简单技巧总结.主要分为js部分和css部分,下面是css的基础部分总 ...

  2. 为什么SQL语句Where 1=1 and在SQL Server中不影响性能

        最近一个朋友和我探讨关于Where 1=1 and这种形式的语句会不会影响性能.最后结论是不影响.     虽然结论正确,但对问题的认识却远远没有解决问题的根本.实际上在T-SQL语句的书写过 ...

  3. javascript运算符——位运算符

    × 目录 [1]二进制 [2]非 [3]与[4]或[5]异或[6]左移[7]右移[8]>>>[9]应用 前面的话 位运算符是非常底层的运算,由于其很不直观,所以并不常用.但是,其速度 ...

  4. javase基础复习攻略《一》

    作为一名软件工程专业,JAVA开发方向的大三本科学生,有必要把自己的学到的专业知识进行一下整理,一则方便自己了解自己的学习程度,二则帮助刚刚接触这一门语言的童鞋了解学习,本人来自与河南理工大学,介绍完 ...

  5. ZZUOJ 1199 大小关系(拓扑排序,两种方法_判断入度和dfs回路判断)

    /* 这道题如果按照度为0的节点来判断的时候,将度为0的节点和其相连的节点(度数并减去1) 从图中去掉,如果度为0的节点的个数为0个但是图中的节点没有都去掉的 时候那么说明 出现了回路!用这种方法必须 ...

  6. 开发笔记:基于EntityFramework.Extended用EF实现指定字段的更新

    今天在将一个项目中使用存储过程的遗留代码迁移至新的架构时,遇到了一个问题——如何用EF实现数据库中指定字段的更新(根据UserId更新Users表中的FaceUrl与AvatarUrl字段)? 原先调 ...

  7. javaccript学习2

    [Javascript]javascript学习 十六 JavaScript 事件 事件是可以被 JavaScript 侦测到的行为. 事件 JavaScript 使我们有能力创建动态页面.事件是可以 ...

  8. Android 2.x中使用actionbar - Actionbarsherlock (2)

    先前有一个项目,是基于android4.0来开发,使用到了Fragment及ActionBar,没打算支持android2.1-android2.3系列版本 写完之后,我将此应用发布到百度应用,一天以 ...

  9. eclipse中断点调试debug

    几乎没有用过debug模式,每次想要知道结果都是sysou一下.记得曾经问乱码问题,jfinal说打断点调试看在哪里出错.简单记下普通调试. 1.在需要查看的地方打断点,方法是在行号右侧双击. 2.运 ...

  10. SQL Server安全(6/11):执行上下文与代码签名(Execution Context and Code Signing)

    在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切.但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念.这篇文章提供了基础,因此你可以对SQL Se ...