Fork me on GitHub
net搭建热插拔式web框架

net搭建热插拔式web框架(重造Controller)

由于.net MVC 的controller 依赖于HttpContext,而我们在上一篇中的沙箱模式已经把一次http请求转换为反射调用,并且http上下文不支持跨域,所以我们要重造一个controller。

  我们在写mvc项目的时候经常会用到ViewBag、ViewData,那我们就先声明这两个变量:

  

1
2
public dynamic ViewBag = new DynamicViewBag();
public ViewDataDictionary ViewData = new ViewDataDictionary();

  当然还可以根据自己的需要构建更多的特性。

   我们在一个网络请求中避免不了会携带一些参数,那这些参数该如何传到沙箱中呢?我们定义了一个RefRequestEntity类,他负责对我们的参数经行打包,把参数打包后对象作为参数传到沙箱内部:

  

  在.net mvc中我们可以返回ActionResult,在ActionResult内部调用时才会做出真正的Response(更多细节请参考mvc实现原理),当然它在执行的整个过程中都是由HttpContext贯穿的,我们没有了HttpContext,我们就只自己构造一些Response方法。

  返回View()结果:

  mvc中由ViewEngine来编译执行我们写好的视图文件(.aspx、.cshtml),而我们则借助于RazorEngine来编译执行razor视图文件,它可以支持我们常用的ViewBag、using、layout等(更多请见RazorEngine)。在本篇中我们还是把精力放回controller的实现中,关于视图的实现我们在下一篇中在讲。我们先看一下一个View的简单实现:

1
2
3
4
5
6
7
8
9
10
/// <summary>返回试图的执行结果
        /// </summary>
        /// <returns></returns>
        protected string View()
        {
            var tKey = Engine.Razor.GetKey(getActionPath(), ResolveType.Global);//getActionPath:获取action对应的视图文件key值。
 
 
       return new CompileView().RunCompile(tKey, nullnull, ViewBag); //返回执行结果
     }

  View()的执行结果是一段html代码。这样我们在请求一个action的时候,就可以正常的呈现一个页面了。下边是一个Controller基类的实现,它完成了View、PartialView的实现Demo:

   我们上边列出了对Razor编译执行的简单过程,还是那句话,RazorEngine的更多实现细节将在下一篇讲解。那么现在问题来了,我们得到了html代码或者说我们执行玩自己的业务逻辑以后如何把这个结果输出呢(即HttpResponse)?

  我们定义了一个RefRespondEntity类,它来承载返回结果,并把结果返回到沙箱外层的调用者,再由这个调用者将这个RefRespondEntity对象Response出去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Serializable]
  public class RefRespondEntity
  {
      public RefRespondEntity(RespondType type)
      {
          ResultType = type;
      }
      /// <summary>返回结果的数据类型
      /// </summary>
      public RespondType ResultType { getset; }
      /// <summary>返回结果的内容
      /// 如果是ResultType=_Redirect那么ResultContext=301
      /// 如果是ResultType=_Stream那么ResultContext="文件名.zip",当然这个文件名可以随意定义
      /// </summary>
      public object ResultContext { getset; }
      /// <summary>返回结果的文件流
      /// </summary>
      public byte[] ResultStream { getset; }
  }

  

1
2
3
4
5
6
7
8
9
10
11
12
13
//一个action的demo      
public RefRespondEntity Index4(RefRequestEntity param)
{
 
     object AA = param.Request["A"];
     object BB = param.Request["B"];
     object CC = param.Request["C"];
 
    RefRespondEntity result = new RefRespondEntity(RespondType._String);
    result.ResultContext = View();
    object tt =   ViewBag.test;
    return result;
}

  

 

1
var result = sandBox.InvokeMothod(urlEntity.controller, urlEntity.action, paras);//sandBox是一个沙箱的实例化对象
1
RequestHandle.ResposeResult(respond, result);//输出结果

  

  

 

  

转载请注明出处:http://www.cnblogs.com/eric-z/p/5028243.html

 

 

 

分类: asp.netasp.net mvc

 

posted on 2015-12-15 23:00  HackerVirus  阅读(841)  评论(0编辑  收藏  举报