[转]VC2005从支付MFC ActiveX ocx控件到揭橥到.net网站的百分之百历程

   
大家在上一篇作品中介绍Controller激活系统中所涉及到的一对品种,比如有关Controller类型的连锁定义类型就概括了IController类型,IAsyncController类型,ControllerBase抽象类型和我们最终要采用的架空类型Controller,这是ASP.NET
MVC
框架中和Controller本身定义相关的品种。其他援救项目,包括管制Controller的花色ControllerFactory,这一个工厂负责Controller的生育和销毁。大家还论及到另一个辅助项目,用于把系统默认定义的如故自定义的ControllerFactory注册到ASP.NET
MVC框架中的类型ControllerBuilder。

正文转自:http://www.cnblogs.com/gengaixue/archive/2010/08/13/1799112.html

    
Controller类型、ControllerFactory类型和ControllerBuilder类型,他们中间的涉嫌得以描述为:ControllerBuilder是面向客户的,或者说是程序员和ASP.NET
MVC框架之间的大桥。我们经过ControllerBuilder类型的SetControllerFactory方法把咱们自定义的ControllerFactory类型实例注册到ASP.NET
MVC框架中,ControllerFactory类型用于管理Controller类型实例,其实也就是说ControllerFactory类型就是ASP.NET
MVC框架中的一个扩展点。

 

   
大家先天重中之重讲Controller是怎么解析出来的,之所以把这一有些分离写,因为合在一起太长了,也说的不详细,假使我们对以上说的不太精晓,可以查看《白话ASP.NET
MVC之二:Controller激活系统的概览》,  该文对ASP.NET
MVC框架中所提到的Controlelr激活系统所涉及的门类有详尽的介绍。

开篇语:近年来在弄ocx控件揭橥到asp.net网站上使用,就是用户在利用过程中,自动下载安装ocx控件。(此著作也是总计了网上广大人写的散文,我只是汇总一下,加上有些协调的事物,在这边感谢所有在网上发布相关内容的心上人们。)

一、“路由系统”和“激活系统”是怎么关联起来的

ActiveX控件用于Web的历程是将控件嵌入主页中,用户通过浏览器访问该主页时,将主页中的控件下载,并在用户机器上登记,将来就可在用户的浏览器上运行。控件下载三次后就驻留在用户本地机械上,下次再拜访同一的主页时,可不再下载该控件,而是一贯运行用户本地的控件。这里控件容器就是浏览器,用户不需要通过浏览器调用控件的习性或艺术。由此,开发面向Web的ActiveX控件比付出桌面的控件还要简单些,所复杂的是怎么将该控件很好地嵌入主页,使用户能正常浏览。上边介绍这多少个题材。

     上一篇小说有过讲述,我们在那边大概说一下。ASP.NET
的路由系统是起家在一个叫作UrlRoutingModule的HttpModule组件上的,针对请求的路由解析是因此挂号HttpApplication对象的PostResolveRequestCache事件来实现的,为近期的请求动态映射到一个HttpHandler类型上,最后由该HttpHandler接管请求并拍卖。大家来探视UrlRoutingModule类型的代码吧。

一.        创建MFC ActiveX项目

 1 [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
 2 public class UrlRoutingModule : IHttpModule
 3 {
 4     private static readonly object _contextKey = new object();
 5 
 6     private static readonly object _requestDataKey = new object();
 7 
 8     private RouteCollection _routeCollection;
 9 
10     public RouteCollection RouteCollection
11     {
12         get
13         {
14             if (this._routeCollection == null)
15             {
16                 this._routeCollection = RouteTable.Routes;
17             }
18             return this._routeCollection;
19         }
20         set
21         {
22             this._routeCollection = value;
23         }
24     }
25 
26     protected virtual void Dispose()
27     {
28     }
29 
30     protected virtual void Init(HttpApplication application)
31     {
32         if (application.Context.Items[UrlRoutingModule._contextKey] != null)
33         {
34             return;
35         }
36         application.Context.Items[UrlRoutingModule._contextKey] = UrlRoutingModule._contextKey;
37         application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
38     }
39 
40     private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
41     {
42         HttpContextBase context = new HttpContextWrapper(((HttpApplication)sender).Context);
43         this.PostResolveRequestCache(context);
44     }
45 
46     [Obsolete("This method is obsolete. Override the Init method to use the PostMapRequestHandler event.")]
47     public virtual void PostMapRequestHandler(HttpContextBase context)
48     {
49     }
50 
51     public virtual void PostResolveRequestCache(HttpContextBase context)
52     {
53         RouteData routeData = this.RouteCollection.GetRouteData(context);
54         if (routeData == null)
55         {
56             return;
57         }
58         IRouteHandler routeHandler = routeData.RouteHandler;
59         if (routeHandler == null)
60         {
61             throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0]));
62         }
63         if (routeHandler is StopRoutingHandler)
64         {
65             return;
66         }
67         RequestContext requestContext = new RequestContext(context, routeData);
68         context.Request.RequestContext = requestContext;
69         IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
70         if (httpHandler == null)
71         {
72             throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoHttpHandler"), new object[]
73             {
74                 routeHandler.GetType()
75             }));
76         }
77         if (!(httpHandler is UrlAuthFailureHandler))
78         {
79             context.RemapHandler(httpHandler);
80             return;
81         }
82         if (FormsAuthenticationModule.FormsAuthRequired)
83         {
84             UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);
85             return;
86         }
87         throw new HttpException(401, SR.GetString("Assess_Denied_Description3"));
88     }
89 
90     void IHttpModule.Dispose()
91     {
92         this.Dispose();
93     }
94 
95     void IHttpModule.Init(HttpApplication application)
96     {
97         this.Init(application);
98     }
99 }

1.       打开VS2005新建MFC项目。这里我们取名为“ActiveXDemo”。

 
具体来说,该器件通过以RouteTable的静态属性Routes表示的路由表针对当下呼吁实施路由解析,假设有配合,就会遵照路由对象Route来生成RouteData路由数据对象,然后我们借助RouteData对象的RouteHandler属性获取想要的HttpHandler对象。在默认意况下这一个RouteHandler属性所代表的对象是MvcRouteHandler。翠花,上代码:

图片 1

 1 /// <summary>Creates an object that implements the IHttpHandler interface and passes the request context to it.</summary>
 2 public class MvcRouteHandler : IRouteHandler
 3 {
 4     private IControllerFactory _controllerFactory;
 5 
 6     /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.MvcRouteHandler" /> class.</summary>
 7     public MvcRouteHandler()
 8     {
 9     }
10 
11     /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.MvcRouteHandler" /> class using the specified factory controller object.</summary>
12     /// <param name="controllerFactory">The controller factory.</param>
13     public MvcRouteHandler(IControllerFactory controllerFactory)
14     {
15         this._controllerFactory = controllerFactory;
16     }
17 
18     /// <summary>Returns the HTTP handler by using the specified HTTP context.</summary>
19     /// <returns>The HTTP handler.</returns>
20     /// <param name="requestContext">The request context.</param>
21     protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
22     {
23             requestContext.HttpContext.SetSessionStateBehavior(this.GetSessionStateBehavior(requestContext));
24         return new MvcHandler(requestContext);
25     }
26 
27     /// <summary>Returns the session behavior.</summary>
28     /// <returns>The session behavior.</returns>
29     /// <param name="requestContext">The request context.</param>
30     protected virtual SessionStateBehavior GetSessionStateBehavior(RequestContext requestContext)
31     {
32         string text = (string)requestContext.RouteData.Values["controller"];
33         if (string.IsNullOrWhiteSpace(text))
34         {
35             throw new InvalidOperationException(MvcResources.MvcRouteHandler_RouteValuesHasNoController);
36         }
37         IControllerFactory controllerFactory = this._controllerFactory ?? ControllerBuilder.Current.GetControllerFactory();
38         return controllerFactory.GetControllerSessionBehavior(requestContext, text);
39     }
40 
41     /// <summary>Returns the HTTP handler by using the specified request context.</summary>
42     /// <returns>The HTTP handler.</returns>
43     /// <param name="requestContext">The request context.</param>
44     IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
45     {
46         return this.GetHttpHandler(requestContext);
47     }
48 }

 

 
在该品种里面包含了一个IControllerFactory类型成员字段,这些接口类型是颇具ControllerFactory都要必须兑现的接口,否则就不叫Controller的厂子了。MvcRouteHandler类型有五个构造函数,无参的没的说,另一个需要传递一个IControllerFactory类型的参数,那多少个参数用于开头化MvcRouteHandler类型内部含有的品类为IControllerFactory的_controllerFactory字段。当大家协会MvcRouteHandler实例的时候,如果我们调用了无参的构造函数,它会在其中选取ControllerBuilder.Current.GetControllerFactory()方法来得到咱们通过ControllerBuilder类型注册的IControllerFactory类型的实例,代码很明朗:

2.       输入项目名称为“ActiveXDemo”和体系地方。点击“确定”按钮,打开向导对话框。

IControllerFactory controllerFactory = this._controllerFactory ?? ControllerBuilder.Current.GetControllerFactory();

图片 2

 
MvcRouteHandler实现了IRouteHandler接口,目的唯有一个,提供后续的HttpHandler,IRouteHandler接口定义如下:

WoSign 免费提供的年月戳服务URL:
http://timestamp.wosign.com/timestamp

public interface IRouteHandler
{
    IHttpHandler GetHttpHandler(RequestContext requestContext);
}

    
时间戳服务分外重要,添加时间戳后,即便你的代码签名证书已经过期,但鉴于您的代码是在评释有效期内签署的,则时间戳服务保证了此代码依然可信,最后用户依旧可以放心下载,使得即便代码签名证书已经过期,您也无需重签和另行颁发已经签约的代码。

  
MvcRouteHandler会给我们一直回到MvcHandler对象,那多少个目的用于拍卖请求,包括激活Controler对象,代码最有说服力,这份代码,上篇作品也贴过,现在也贴一下把,上代码:
  

3.       选取“控件设置”选项卡,具体设置可参照上图。此外选项卡为默认设置。最终点击“完成”按钮保存设置。

  1    public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
  2     {
  3         private struct ProcessRequestState
  4         {
  5             internal IAsyncController AsyncController;
  6 
  7             internal IControllerFactory Factory;
  8 
  9             internal RequestContext RequestContext;
 10 
 11             internal void ReleaseController()
 12             {
 13                 this.Factory.ReleaseController(this.AsyncController);
 14             }
 15         }
 16 
 17         private static readonly object _processRequestTag = new object();
 18 
 19         internal static readonly string MvcVersion = MvcHandler.GetMvcVersionString();
 20 
 21         /// <summary>Contains the header name of the ASP.NET MVC version.</summary>
 22         public static readonly string MvcVersionHeaderName = "X-AspNetMvc-Version";
 23 
 24         private ControllerBuilder _controllerBuilder;
 25 
 26         internal ControllerBuilder ControllerBuilder
 27         {
 28             get
 29             {
 30                 if (this._controllerBuilder == null)
 31                 {
 32                     this._controllerBuilder = ControllerBuilder.Current;
 33                 }
 34                 return this._controllerBuilder;
 35             }
 36             set
 37             {
 38                 this._controllerBuilder = value;
 39             }
 40         }
 41 
 42         /// <summary>Gets or sets a value that indicates whether the MVC response header is disabled.</summary>
 43         /// <returns>true if the MVC response header is disabled; otherwise, false.</returns>
 44         public static bool DisableMvcResponseHeader
 45         {
 46             get;
 47             set;
 48         }
 49 
 50         /// <summary>Gets a value that indicates whether another request can use the <see cref="T:System.Web.IHttpHandler" /> instance.</summary>
 51         /// <returns>true if the <see cref="T:System.Web.IHttpHandler" /> instance is reusable; otherwise, false.</returns>
 52         protected virtual bool IsReusable
 53         {
 54             get
 55             {
 56                 return false;
 57             }
 58         }
 59 
 60         /// <summary>Gets the request context.</summary>
 61         /// <returns>The request context.</returns>
 62         public RequestContext RequestContext
 63         {
 64             get;
 65             private set;
 66         }
 67 
 68         /// <summary>Gets a value that indicates whether another request can use the <see cref="T:System.Web.IHttpHandler" /> instance.</summary>
 69         /// <returns>true if the <see cref="T:System.Web.IHttpHandler" /> instance is reusable; otherwise, false.</returns>
 70         bool IHttpHandler.IsReusable
 71         {
 72             get
 73             {
 74                 return this.IsReusable;
 75             }
 76         }
 77 
 78         /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.MvcHandler" /> class.</summary>
 79         /// <param name="requestContext">The request context.</param>
 80         /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestContext" /> parameter is null.</exception>
 81         public MvcHandler(RequestContext requestContext)
 82         {
 83             if (requestContext == null)
 84             {
 85                 throw new ArgumentNullException("requestContext");
 86             }
 87             this.RequestContext = requestContext;
 88         }
 89 
 90         /// <summary>Adds the version header by using the specified HTTP context.</summary>
 91         /// <param name="httpContext">The HTTP context.</param>
 92         protected internal virtual void AddVersionHeader(HttpContextBase httpContext)
 93         {
 94             if (!MvcHandler.DisableMvcResponseHeader)
 95             {
 96                 httpContext.Response.AppendHeader(MvcHandler.MvcVersionHeaderName, MvcHandler.MvcVersion);
 97             }
 98         }
 99 
100         /// <summary>Called by ASP.NET to begin asynchronous request processing.</summary>
101         /// <returns>The status of the asynchronous call.</returns>
102         /// <param name="httpContext">The HTTP context.</param>
103         /// <param name="callback">The asynchronous callback method.</param>
104         /// <param name="state">The state of the asynchronous object.</param>
105         protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state)
106         {
107             HttpContextBase httpContext2 = new HttpContextWrapper(httpContext);
108             return this.BeginProcessRequest(httpContext2, callback, state);
109         }
110 
111         /// <summary>Called by ASP.NET to begin asynchronous request processing using the base HTTP context.</summary>
112         /// <returns>The status of the asynchronous call.</returns>
113         /// <param name="httpContext">The HTTP context.</param>
114         /// <param name="callback">The asynchronous callback method.</param>
115         /// <param name="state">The state of the asynchronous object.</param>
116         protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
117         {
118             IController controller;
119             IControllerFactory factory;
120             this.ProcessRequestInit(httpContext, out controller, out factory);
121             IAsyncController asyncController = controller as IAsyncController;
122             if (asyncController != null)
123             {
124                 BeginInvokeDelegate<MvcHandler.ProcessRequestState> beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState, MvcHandler.ProcessRequestState innerState)
125                 {
126                     IAsyncResult result;
127                     try
128                     {
129                         result = innerState.AsyncController.BeginExecute(innerState.RequestContext, asyncCallback, asyncState);
130                     }
131                     catch
132                     {
133                         innerState.ReleaseController();
134                         throw;
135                     }
136                     return result;
137                 };
138                 EndInvokeVoidDelegate<MvcHandler.ProcessRequestState> endDelegate = delegate(IAsyncResult asyncResult, MvcHandler.ProcessRequestState innerState)
139                 {
140                     try
141                     {
142                         innerState.AsyncController.EndExecute(asyncResult);
143                     }
144                     finally
145                     {
146                         innerState.ReleaseController();
147                     }
148                 };
149                 MvcHandler.ProcessRequestState invokeState = new MvcHandler.ProcessRequestState
150                 {
151                     AsyncController = asyncController,
152                     Factory = factory,
153                     RequestContext = this.RequestContext
154                 };
155                 SynchronizationContext synchronizationContext = SynchronizationContextUtil.GetSynchronizationContext();
156                 return AsyncResultWrapper.Begin<MvcHandler.ProcessRequestState>(callback, state, beginDelegate, endDelegate, invokeState, MvcHandler._processRequestTag, -1, synchronizationContext);
157             }
158             Action action = delegate
159             {
160                 try
161                 {
162                     controller.Execute(this.RequestContext);
163                 }
164                 finally
165                 {
166                     factory.ReleaseController(controller);
167                 }
168             };
169             return AsyncResultWrapper.BeginSynchronous(callback, state, action, MvcHandler._processRequestTag);
170         }
171 
172         /// <summary>Called by ASP.NET when asynchronous request processing has ended.</summary>
173         /// <param name="asyncResult">The asynchronous result.</param>
174         protected internal virtual void EndProcessRequest(IAsyncResult asyncResult)
175         {
176             AsyncResultWrapper.End(asyncResult, MvcHandler._processRequestTag);
177         }
178 
179         private static string GetMvcVersionString()
180         {
181             return new AssemblyName(typeof(MvcHandler).Assembly.FullName).Version.ToString(2);
182         }
183 
184         /// <summary>Processes the request by using the specified HTTP request context.</summary>
185         /// <param name="httpContext">The HTTP context.</param>
186         protected virtual void ProcessRequest(HttpContext httpContext)
187         {
188             HttpContextBase httpContext2 = new HttpContextWrapper(httpContext);
189             this.ProcessRequest(httpContext2);
190         }
191 
192         /// <summary>Processes the request by using the specified base HTTP request context.</summary>
193         /// <param name="httpContext">The HTTP context.</param>
194         protected internal virtual void ProcessRequest(HttpContextBase httpContext)
195         {
196             IController controller;
197             IControllerFactory controllerFactory;
198             this.ProcessRequestInit(httpContext, out controller, out controllerFactory);
199             try
200             {
201                 controller.Execute(this.RequestContext);
202             }
203             finally
204             {
205                 controllerFactory.ReleaseController(controller);
206             }
207         }
208 
209         private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
210         {
211             HttpContext current = HttpContext.Current;
212             if (current != null && ValidationUtility.IsValidationEnabled(current) == true)
213             {
214                 ValidationUtility.EnableDynamicValidation(current);
215             }
216             this.AddVersionHeader(httpContext);
217             this.RemoveOptionalRoutingParameters();
218             string requiredString = this.RequestContext.RouteData.GetRequiredString("controller");
219             factory = this.ControllerBuilder.GetControllerFactory();
220             controller = factory.CreateController(this.RequestContext, requiredString);
221             if (controller == null)
222             {
223                 throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.ControllerBuilder_FactoryReturnedNull, new object[]
224                 {
225                     factory.GetType(),
226                     requiredString
227                 }));
228             }
229         }
230 
231         private void RemoveOptionalRoutingParameters()
232         {
233             RouteValueDictionary values = this.RequestContext.RouteData.Values;
234             values.RemoveFromDictionary((KeyValuePair<string, object> entry) => entry.Value == UrlParameter.Optional);
235         }
236 
237         /// <summary>Enables processing of HTTP Web requests by a custom HTTP handler that implements the <see cref="T:System.Web.IHttpHandler" /> interface.</summary>
238         /// <param name="httpContext">An <see cref="T:System.Web.HttpContext" /> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) that are used to service HTTP requests.</param>
239         void IHttpHandler.ProcessRequest(HttpContext httpContext)
240         {
241             this.ProcessRequest(httpContext);
242         }
243 
244         /// <summary>Called by ASP.NET to begin asynchronous request processing using the base HTTP context.</summary>
245         /// <returns>The status of the asynchronous call.</returns>
246         /// <param name="context">The HTTP context.</param>
247         /// <param name="cb">The asynchronous callback method.</param>
248         /// <param name="extraData">The data.</param>
249         IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
250         {
251             return this.BeginProcessRequest(context, cb, extraData);
252         }
253 
254         /// <summary>Called by ASP.NET when asynchronous request processing has ended.</summary>
255         /// <param name="result">The asynchronous result.</param>
256         void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
257         {
258             this.EndProcessRequest(result);
259         }
260     }

 

 
MvcHandler类型的BeginProcessRequest方法用来拍卖请求,包括激活Controller实例等。由于MvcHandler类型同时落实了IHttpHandler接口和IHttpAsyncHandler接口,所以她一连异步模式去履行(调用BeginProcessRequest/EndProcessRequest方法)。BeginProcessRequest方法在执行的时候经过RequestContext对象的RouteData属性拿到Controller的名字,然后在通过ControllerBuilder拿到ControllerFactory对象,然后用Controller的名字和ControllerFactory对象来激活目的Controller实例。要是Controller类型实现了IAsyncController接口,那就以异步情势履行Controller,否则以协同形式执行。Controller对象成功执行后,MvcHandler对象会调用ControllerFactory对象ReleaseController方法来销毁Controller实例对象。

二.        添加控件方法

     大家统计一下,ASP.NET
MVC的路由系统和Controller的激活系统是由此那一个目的关系起来的:请求Url
——->Route——->RouteData——->RouteHandler(MvcRouteHandler)——–>MvcRouteHandler——>MvcHandler,通过这个目的就能串起来了。

VC2005会为我们自行创设好MFC
ActiveX程序框架,我们即使给该ActiveX控件添加方法即可。现在大家给控件添加一个“AddFun”方法,这些方法是将五个数相加并重返结果。

二、Controller的事无巨细剖析过程

1.       点击“视图”,打开“类视图”窗口。

    
我先来简述一下Controller解析的法则吧。Controller实例对象的分析是通过落实了IControllerFactory接口的ControllerFactory对象实现的,ControllerFactory是怎么来的呢?是透过调用ControllerBuilder的SetControllerFactory方法实现对ControllerFactory类型或者实例对象的挂号。虽然大家尚无调用ControllerBuilder的SetControllerFactory方法对象ControllerFactory类型或者实例突显注册,系统会利用默认的ControllerFactory来成功对Controller对象的剖析,这么些目的就是DefaultControllerFactory类型,该品种的落实正好反映了ASP.NET
MVC框架对Controller实例的激活采用的默认策略。明日我们就看看DefaultControllerFactory类型是怎么样把Controller对象激活的,这也是Controller激活系统的默认实现,我们可以扩大ControllerFactory类型,实现自定义的Controller激活策略。

图片 3

    
我把代码流程写一下,在MvcHandler类型里面有四个办法,一个主意是:BeginProcessRequest(HttpContextBase
httpContext,AsyncCallback callback,object
state),该格局用于对请求举办拍卖;第二个主意是:ProcessRequestInit(HttpContextbase
httpContext,out IController controller,out IControllerFactory
controllerFactory),该办法就是概念了激活Controller算法的骨架,上代码吧,代码最无二意,大家先看BeginProcessRequest的代码:

2.       展开“ActiveXDemoLib”项,选中“_DActiveXDemo”项。点击鼠标右键,采用“添加”下的“添加方法”。

 1         /// <summary>Called by ASP.NET to begin asynchronous request processing using the base HTTP context.</summary>
 2         /// <returns>The status of the asynchronous call.</returns>
 3         /// <param name="httpContext">The HTTP context.</param>
 4         /// <param name="callback">The asynchronous callback method.</param>
 5         /// <param name="state">The state of the asynchronous object.</param>
 6         protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
 7         {
 8             IController controller;
 9             IControllerFactory factory;
10             this.ProcessRequestInit(httpContext, out controller, out factory);
11             IAsyncController asyncController = controller as IAsyncController;
12             if (asyncController != null)
13             {
14                 BeginInvokeDelegate<MvcHandler.ProcessRequestState> beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState, MvcHandler.ProcessRequestState innerState)
15                 {
16                     IAsyncResult result;
17                     try
18                     {
19                         result = innerState.AsyncController.BeginExecute(innerState.RequestContext, asyncCallback, asyncState);
20                     }
21                     catch
22                     {
23                         innerState.ReleaseController();
24                         throw;
25                     }
26                     return result;
27                 };
28                 EndInvokeVoidDelegate<MvcHandler.ProcessRequestState> endDelegate = delegate(IAsyncResult asyncResult, MvcHandler.ProcessRequestState innerState)
29                 {
30                     try
31                     {
32                         innerState.AsyncController.EndExecute(asyncResult);
33                     }
34                     finally
35                     {
36                         innerState.ReleaseController();
37                     }
38                 };
39                 MvcHandler.ProcessRequestState invokeState = new MvcHandler.ProcessRequestState
40                 {
41                     AsyncController = asyncController,
42                     Factory = factory,
43                     RequestContext = this.RequestContext
44                 };
45                 SynchronizationContext synchronizationContext = SynchronizationContextUtil.GetSynchronizationContext();
46                 return AsyncResultWrapper.Begin<MvcHandler.ProcessRequestState>(callback, state, beginDelegate, endDelegate, invokeState, MvcHandler._processRequestTag, -1, synchronizationContext);
47             }
48             Action action = delegate
49             {
50                 try
51                 {
52                     controller.Execute(this.RequestContext);
53                 }
54                 finally
55                 {
56                     factory.ReleaseController(controller);
57                 }
58             };
59             return AsyncResultWrapper.BeginSynchronous(callback, state, action, MvcHandler._processRequestTag);
60         }

图片 4

  
在这一个点子里面依据分析出来的Controller的花色来施行,假要是异步的Controller这就异步执行,否则就联手实施。在该办法里面,第三行,标黑色的方法就是概念解析和推行Controller的算法骨架,就是我们要贴代码的第二个办法ProcessRequestInit,源码如下:
 

 

 1         private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
 2         {
 3             HttpContext current = HttpContext.Current;
 4             if (current != null && ValidationUtility.IsValidationEnabled(current) == true)
 5             {
 6                 ValidationUtility.EnableDynamicValidation(current);
 7             }
 8             this.AddVersionHeader(httpContext);
 9             this.RemoveOptionalRoutingParameters();
10             string requiredString = this.RequestContext.RouteData.GetRequiredString("controller");
11             factory = this.ControllerBuilder.GetControllerFactory();
12             controller = factory.CreateController(this.RequestContext, requiredString);
13             if (controller == null)
14             {
15                 throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.ControllerBuilder_FactoryReturnedNull, new object[]
16                 {
17                     factory.GetType(),
18                     requiredString
19                 }));
20             }
21         }

3.       打开添加办法向导窗口。因为我们是丰富一个加法方法,所以大家设置的回到类型为LONG型,方法名设为AddFun,添加六个LONG类型参数Add1,Add2。

    
那些点子首倘使得到ControllerFactory实例,按照取得的ControllerFactory对象激活Controller对象,粉色标注的代码就是骨干关键点。表达一些,这一个艺术只是概念了激活Controller算法的龙骨,具体的落实在DefaultControllerFactory类型中。代码很简单,我信任大家看的通晓。

图片 5

      
DefaultControllerFactory会先经过“MVC-ControllerTypeCache.xml”文件来加载Controller的体系,如果没有找到有效的数目才会由此调用BuildManager的静态方法GetReferencedAssemblies获取到系统所使用到的拥有程序集,然后针对每个程序集通过反射的不二法门得到所有实现了IController接口的项目,并XML文件的款式缓存起来,缓存的公文名就是“MVC-ControllerTypeCache.xml”。然后我们把Controller的称呼和命名空间作为匹配原则去寻找对应的Controller类型。当大家取得了符合标准的真是的Controller类型后,DefaultControllerFactory对象通过反射的主意创设Controller类型的实例对象。解析逻辑不复杂,可是代码不少。首先我表明某些,把代码全部贴出来不是为着占篇幅,而是为了我们能看的更明亮,我把全体的源码贴出来,我们可以仔细回味一下。

 

  1 /// <summary>Represents the controller factory that is registered by default.</summary>
  2     public class DefaultControllerFactory : IControllerFactory
  3     {
  4         private class DefaultControllerActivator : IControllerActivator
  5         {
  6             private Func<IDependencyResolver> _resolverThunk;
  7 
  8             public DefaultControllerActivator() : this(null)
  9             {
 10             }
 11 
 12             public DefaultControllerActivator(IDependencyResolver resolver)
 13             {
 14                 if (resolver == null)
 15                 {
 16                     this._resolverThunk = (() => DependencyResolver.Current);
 17                     return;
 18                 }
 19                 this._resolverThunk = (() => resolver);
 20             }
 21 
 22             public IController Create(RequestContext requestContext, Type controllerType)
 23             {
 24                 IController result;
 25                 try
 26                 {
 27                     result = (IController)(this._resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
 28                 }
 29                 catch (Exception innerException)
 30                 {
 31                     throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_ErrorCreatingController, new object[]
 32                     {
 33                         controllerType
 34                     }), innerException);
 35                 }
 36                 return result;
 37             }
 38         }
 39 
 40         private static readonly ConcurrentDictionary<Type, SessionStateBehavior> _sessionStateCache = new ConcurrentDictionary<Type, SessionStateBehavior>();
 41 
 42         private static ControllerTypeCache _staticControllerTypeCache = new ControllerTypeCache();
 43 
 44         private IBuildManager _buildManager;
 45 
 46         private IResolver<IControllerActivator> _activatorResolver;
 47 
 48         private IControllerActivator _controllerActivator;
 49 
 50         private ControllerBuilder _controllerBuilder;
 51 
 52         private ControllerTypeCache _instanceControllerTypeCache;
 53 
 54         private IControllerActivator ControllerActivator
 55         {
 56             get
 57             {
 58                 if (this._controllerActivator != null)
 59                 {
 60                     return this._controllerActivator;
 61                 }
 62                 this._controllerActivator = this._activatorResolver.Current;
 63                 return this._controllerActivator;
 64             }
 65         }
 66 
 67         internal IBuildManager BuildManager
 68         {
 69             get
 70             {
 71                 if (this._buildManager == null)
 72                 {
 73                     this._buildManager = new BuildManagerWrapper();
 74                 }
 75                 return this._buildManager;
 76             }
 77             set
 78             {
 79                 this._buildManager = value;
 80             }
 81         }
 82 
 83         internal ControllerBuilder ControllerBuilder
 84         {
 85             get
 86             {
 87                 return this._controllerBuilder ?? ControllerBuilder.Current;
 88             }
 89             set
 90             {
 91                 this._controllerBuilder = value;
 92             }
 93         }
 94 
 95         internal ControllerTypeCache ControllerTypeCache
 96         {
 97             get
 98             {
 99                 return this._instanceControllerTypeCache ?? DefaultControllerFactory._staticControllerTypeCache;
100             }
101             set
102             {
103                 this._instanceControllerTypeCache = value;
104             }
105         }
106 
107         /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.DefaultControllerFactory" /> class.</summary>
108         public DefaultControllerFactory() : this(null, null, null)
109         {
110         }
111 
112         /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.DefaultControllerFactory" /> class using a controller activator.</summary>
113         /// <param name="controllerActivator">An object that implements the controller activator interface.</param>
114         public DefaultControllerFactory(IControllerActivator controllerActivator) : this(controllerActivator, null, null)
115         {
116         }
117 
118         internal DefaultControllerFactory(IControllerActivator controllerActivator, IResolver<IControllerActivator> activatorResolver, IDependencyResolver dependencyResolver)
119         {
120             if (controllerActivator != null)
121             {
122                 this._controllerActivator = controllerActivator;
123                 return;
124             }
125             IResolver<IControllerActivator> arg_44_1 = activatorResolver;
126             if (activatorResolver == null)
127             {
128                 arg_44_1 = new SingleServiceResolver<IControllerActivator>(() => null, new DefaultControllerFactory.DefaultControllerActivator(dependencyResolver), "DefaultControllerFactory constructor");
129             }
130             this._activatorResolver = arg_44_1;
131         }
132 
133         internal static InvalidOperationException CreateAmbiguousControllerException(RouteBase route, string controllerName, ICollection<Type> matchingTypes)
134         {
135             StringBuilder stringBuilder = new StringBuilder();
136             foreach (Type current in matchingTypes)
137             {
138                 stringBuilder.AppendLine();
139                 stringBuilder.Append(current.FullName);
140             }
141             Route route2 = route as Route;
142             string message;
143             if (route2 != null)
144             {
145                 message = string.Format(CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl, new object[]
146                 {
147                     controllerName,
148                     route2.Url,
149                     stringBuilder,
150                     Environment.NewLine
151                 });
152             }
153             else
154             {
155                 message = string.Format(CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl, new object[]
156                 {
157                     controllerName,
158                     stringBuilder,
159                     Environment.NewLine
160                 });
161             }
162             return new InvalidOperationException(message);
163         }
164 
165         private static InvalidOperationException CreateDirectRouteAmbiguousControllerException(ICollection<Type> matchingTypes)
166         {
167             StringBuilder stringBuilder = new StringBuilder();
168             foreach (Type current in matchingTypes)
169             {
170                 stringBuilder.AppendLine();
171                 stringBuilder.Append(current.FullName);
172             }
173             string message = string.Format(CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_DirectRouteAmbiguous, new object[]
174             {
175                 stringBuilder,
176                 Environment.NewLine
177             });
178             return new InvalidOperationException(message);
179         }
180 
181         /// <summary>Creates the specified controller by using the specified request context.</summary>
182         /// <returns>The controller.</returns>
183         /// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
184         /// <param name="controllerName">The name of the controller.</param>
185         /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestContext" /> parameter is null.</exception>
186         /// <exception cref="T:System.ArgumentException">The <paramref name="controllerName" /> parameter is null or empty.</exception>
187         public virtual IController CreateController(RequestContext requestContext, string controllerName)
188         {
189             if (requestContext == null)
190             {
191                 throw new ArgumentNullException("requestContext");
192             }
193             if (string.IsNullOrEmpty(controllerName) && !requestContext.RouteData.HasDirectRouteMatch())
194             {
195                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
196             }
197             Type controllerType = this.GetControllerType(requestContext, controllerName);
198             return this.GetControllerInstance(requestContext, controllerType);
199         }
200 
201         /// <summary>Retrieves the controller instance for the specified request context and controller type.</summary>
202         /// <returns>The controller instance.</returns>
203         /// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
204         /// <param name="controllerType">The type of the controller.</param>
205         /// <exception cref="T:System.Web.HttpException">
206         ///   <paramref name="controllerType" /> is null.</exception>
207         /// <exception cref="T:System.ArgumentException">
208         ///   <paramref name="controllerType" /> cannot be assigned.</exception>
209         /// <exception cref="T:System.InvalidOperationException">An instance of <paramref name="controllerType" /> cannot be created.</exception>
210         protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType)
211         {
212             if (controllerType == null)
213             {
214                 throw new HttpException(404, string.Format(CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_NoControllerFound, new object[]
215                 {
216                     requestContext.HttpContext.Request.Path
217                 }));
218             }
219             if (!typeof(IController).IsAssignableFrom(controllerType))
220             {
221                 throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase, new object[]
222                 {
223                     controllerType
224                 }), "controllerType");
225             }
226             return this.ControllerActivator.Create(requestContext, controllerType);
227         }
228 
229         /// <summary>Returns the controller's session behavior.</summary>
230         /// <returns>The controller's session behavior.</returns>
231         /// <param name="requestContext">The request context.</param>
232         /// <param name="controllerType">The type of the controller.</param>
233         protected internal virtual SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType)
234         {
235             if (controllerType == null)
236             {
237                 return SessionStateBehavior.Default;
238             }
239             return DefaultControllerFactory._sessionStateCache.GetOrAdd(controllerType, delegate(Type type)
240             {
241                 SessionStateAttribute sessionStateAttribute = type.GetCustomAttributes(typeof(SessionStateAttribute), true).OfType<SessionStateAttribute>().FirstOrDefault<SessionStateAttribute>();
242                 if (sessionStateAttribute == null)
243                 {
244                     return SessionStateBehavior.Default;
245                 }
246                 return sessionStateAttribute.Behavior;
247             });
248         }
249 
250         /// <summary>Retrieves the controller type for the specified name and request context.</summary>
251         /// <returns>The controller type.</returns>
252         /// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
253         /// <param name="controllerName">The name of the controller.</param>
254         protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName)
255         {
256             if (requestContext == null)
257             {
258                 throw new ArgumentNullException("requestContext");
259             }
260             if (string.IsNullOrEmpty(controllerName) && (requestContext.RouteData == null || !requestContext.RouteData.HasDirectRouteMatch()))
261             {
262                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
263             }
264             RouteData routeData = requestContext.RouteData;
265             if (routeData != null && routeData.HasDirectRouteMatch())
266             {
267                 return DefaultControllerFactory.GetControllerTypeFromDirectRoute(routeData);
268             }
269             object obj;
270             if (routeData.DataTokens.TryGetValue("Namespaces", out obj))
271             {
272                 IEnumerable<string> enumerable = obj as IEnumerable<string>;
273                 if (enumerable != null && enumerable.Any<string>())
274                 {
275                     HashSet<string> namespaces = new HashSet<string>(enumerable, StringComparer.OrdinalIgnoreCase);
276                     Type controllerTypeWithinNamespaces = this.GetControllerTypeWithinNamespaces(routeData.Route, controllerName, namespaces);
277                     if (controllerTypeWithinNamespaces != null || false.Equals(routeData.DataTokens["UseNamespaceFallback"]))
278                     {
279                         return controllerTypeWithinNamespaces;
280                     }
281                 }
282             }
283             if (this.ControllerBuilder.DefaultNamespaces.Count > 0)
284             {
285                 HashSet<string> namespaces2 = new HashSet<string>(this.ControllerBuilder.DefaultNamespaces, StringComparer.OrdinalIgnoreCase);
286                 Type controllerTypeWithinNamespaces = this.GetControllerTypeWithinNamespaces(routeData.Route, controllerName, namespaces2);
287                 if (controllerTypeWithinNamespaces != null)
288                 {
289                     return controllerTypeWithinNamespaces;
290                 }
291             }
292             return this.GetControllerTypeWithinNamespaces(routeData.Route, controllerName, null);
293         }
294 
295         private static Type GetControllerTypeFromDirectRoute(RouteData routeData)
296         {
297             IEnumerable<RouteData> directRouteMatches = routeData.GetDirectRouteMatches();
298             List<Type> list = new List<Type>();
299             foreach (RouteData current in directRouteMatches)
300             {
301                 if (current != null)
302                 {
303                     Type targetControllerType = current.GetTargetControllerType();
304                     if (targetControllerType == null)
305                     {
306                         throw new InvalidOperationException(MvcResources.DirectRoute_MissingControllerType);
307                     }
308                     if (!list.Contains(targetControllerType))
309                     {
310                         list.Add(targetControllerType);
311                     }
312                 }
313             }
314             if (list.Count == 0)
315             {
316                 return null;
317             }
318             if (list.Count == 1)
319             {
320                 return list[0];
321             }
322             throw DefaultControllerFactory.CreateDirectRouteAmbiguousControllerException(list);
323         }
324 
325         private Type GetControllerTypeWithinNamespaces(RouteBase route, string controllerName, HashSet<string> namespaces)
326         {
327             this.ControllerTypeCache.EnsureInitialized(this.BuildManager);
328             ICollection<Type> controllerTypes = this.ControllerTypeCache.GetControllerTypes(controllerName, namespaces);
329             switch (controllerTypes.Count)
330             {
331             case 0:
332                 return null;
333             case 1:
334                 return controllerTypes.First<Type>();
335             default:
336                 throw DefaultControllerFactory.CreateAmbiguousControllerException(route, controllerName, controllerTypes);
337             }
338         }
339 
340         /// <summary>Releases the specified controller.</summary>
341         /// <param name="controller">The controller to release.</param>
342         public virtual void ReleaseController(IController controller)
343         {
344             IDisposable disposable = controller as IDisposable;
345             if (disposable != null)
346             {
347                 disposable.Dispose();
348             }
349         }
350 
351         internal IReadOnlyList<Type> GetControllerTypes()
352         {
353             this.ControllerTypeCache.EnsureInitialized(this.BuildManager);
354             return this.ControllerTypeCache.GetControllerTypes();
355         }
356 
357         /// <summary>This API supports the ASP.NET MVC infrastructure and is not intended to be used directly from your code. This method calls the <see cref="M:System.Web.Mvc.DefaultControllerFactory.GetControllerSessionBehavior(System.Web.Routing.RequestContext,System.Type)" /> method.</summary>
358         /// <returns>The controller's session behavior.</returns>
359         /// <param name="requestContext">The request context.</param>
360         /// <param name="controllerName">The controller name.</param>
361         SessionStateBehavior IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
362         {
363             if (requestContext == null)
364             {
365                 throw new ArgumentNullException("requestContext");
366             }
367             if (string.IsNullOrEmpty(controllerName))
368             {
369                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
370             }
371             Type controllerType = this.GetControllerType(requestContext, controllerName);
372             return this.GetControllerSessionBehavior(requestContext, controllerType);
373         }
374     }

 

  
既然是ControllerFactory,DefaultControllerFactory肯定也兑现了IControllerFactory接口,其余我们就不看了,大家看看是何等创制Controller对象的,方法代码如下:

4.       其余为默认设置,点击“完成”按钮完成增长方法。接下来我们打开“解决方案资源管理器”打开“ActiveXDemoCtrl.cpp”文件。

 1 /// <summary>Creates the specified controller by using the specified request context.</summary>
 2 /// <returns>The controller.</returns>
 3 /// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
 4 /// <param name="controllerName">The name of the controller.</param>
 5 /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestContext" /> parameter is null.</exception>
 6 /// <exception cref="T:System.ArgumentException">The <paramref name="controllerName" /> parameter is null or empty.</exception>
 7 public virtual IController CreateController(RequestContext requestContext, string controllerName)
 8 {
 9     if (requestContext == null)
10     {
11         throw new ArgumentNullException("requestContext");
12     }
13     if (string.IsNullOrEmpty(controllerName) && !requestContext.RouteData.HasDirectRouteMatch())
14     {
15         throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
16     }
17     Type controllerType = this.GetControllerType(requestContext, controllerName);
18     return this.GetControllerInstance(requestContext, controllerType);
19 }

图片 6

 
代码很粗略,该办法得到Controller的Type类型对象,然后依据Type对象创制实例。这一个办法里面有六个协理方法,一个是GetControllerType方法,另一个是GetControllerInstance方法,遵照名称咱们就能分晓是做什么的。我们先看看GetControllerType方法的源码吧,这里是重中之重,没有Type对象的拿走,未来都是空言:  

5.       打开代码视图,大家会发觉VC2005早就为大家添加了一个“AddFun”方法,我们在章程内添加“return Add1 +
Add2;”语句。

 1 /// <summary>Retrieves the controller type for the specified name and request context.</summary>
 2 /// <returns>The controller type.</returns>
 3 /// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
 4 /// <param name="controllerName">The name of the controller.</param>
 5 protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName)
 6 {
 7     if (requestContext == null)
 8     {
 9         throw new ArgumentNullException("requestContext");
10     }
11     if (string.IsNullOrEmpty(controllerName) && (requestContext.RouteData == null || !requestContext.RouteData.HasDirectRouteMatch()))
12     {
13         throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
14     }
15     RouteData routeData = requestContext.RouteData;
16     if (routeData != null && routeData.HasDirectRouteMatch())
17     {
18         return DefaultControllerFactory.GetControllerTypeFromDirectRoute(routeData);
19     }
20     object obj;
21     if (routeData.DataTokens.TryGetValue("Namespaces", out obj))
22     {
23         IEnumerable<string> enumerable = obj as IEnumerable<string>;
24         if (enumerable != null && enumerable.Any<string>())
25         {
26             HashSet<string> namespaces = new HashSet<string>(enumerable, StringComparer.OrdinalIgnoreCase);
27             Type controllerTypeWithinNamespaces = this.GetControllerTypeWithinNamespaces(routeData.Route, controllerName, namespaces);
28             if (controllerTypeWithinNamespaces != null || false.Equals(routeData.DataTokens["UseNamespaceFallback"]))
29             {
30                 return controllerTypeWithinNamespaces;
31             }
32         }
33     }
34     if (this.ControllerBuilder.DefaultNamespaces.Count > 0)
35     {
36         HashSet<string> namespaces2 = new HashSet<string>(this.ControllerBuilder.DefaultNamespaces, StringComparer.OrdinalIgnoreCase);
37         Type controllerTypeWithinNamespaces = this.GetControllerTypeWithinNamespaces(routeData.Route, controllerName, namespaces2);
38         if (controllerTypeWithinNamespaces != null)
39         {
40             return controllerTypeWithinNamespaces;
41         }
42     }
43     return this.GetControllerTypeWithinNamespaces(routeData.Route, controllerName, null);
44 }

图片 7

   
大家先依照RouteData路由数量来博取Controller的类型对象,假若RouteData不为空,并且在RouteData的Values属性中含有Key为“MS_DirectRouteMatches”的值,这我们就因故获取Controller的体系对象,假若没找到就回来Null值,如果有一个值,就会作为Controller的Type类型值重返,假使多于一个就会抛出非常。就算RouteData不含有Key为“MS_DirectRouteMatches”的值,我们就按照RouteData对象中DataTokens属性Key为“Namespaces”来博取Controller的Type对象,同理,如若没找到就再次来到null,找到一个就直接回到,如若多余一个的话就抛出非常。

 

     
假使我们依旧没找到咋办吧?我们就要看看能不可以利用后备命名空间,假设得以,就遵照此命名空间来寻觅,大家从RouteData路由数量的DataTokens属性中寻觅是否带有有Key为“UseNamespaceFallback”的值,虽然有,并且是False,就从来重临,截止查找,假如不分包Key为“UseNamepsaceFallback”的值或者该值为True,我们就可以遵照ControllerBuilder的DefaultNamespaces属性表示后备命名空间查找Controller的档次,同理,没有找到就赶回null,找到一个就作为结果值直接回到,就算多于一个这就要抛出十分了。

 三、MFC Activex 安全题材:

   
好了,大概的逻辑写完了,假使还有不晓得的,就仔细的探访源码把,要是把源码完整的看五次,然后在重整逻辑,就便于多了。看代码别太注意代码细节,关注紧要的关键点或者叫关键类就足以,把表弟类之间的涉及和权责整理清楚,精晓起来并不复杂。

 1、在默认环境下,编译的MFC
Activex控件,只可以在本地代码中运作,即在http://localhost/xxx/xxx.htm中执行,而在http://127.0.0.1/xxx/xxx.htm中提示无相关属性,需要设置其初始化和脚本运行的安全性

三、扩展点

  ActiveX在远程IE页面上执行,需要贯彻安全接口。

     
到了前几天,Controller激活系统就写的大半了,唯一还差一点的就是扩展点还没提。ASP.NET
MVC号称几乎任哪里方都可以扩展,Controller激活系统中一定也带有着扩张点,下来我们逐条详述。

  在ATL写的ActiveX中,用IObjectSafety。

      恢宏点一:扩充IControllerFactory接口

  http://support.microsoft.com/kb/168371/en-us

             
第一个很容易想到的壮大点就是落实IControllerFactory接口,定义一个全新的ControllerFactory类型。假设是这般,里面所有的职能的就需要总体再一次实现,包括Controller类型的辨析、Controller实例的创导和销毁、也包罗会话状态作为形式的军事管制。那样的功利就是我们就有更好的控制权了,可以按着大家的思维贯彻其效用。可是假使认为再一次实现多少麻烦,而且有时也从未必要,拿我们就足以继承DefaultControllerFactory类型,针对特定的主意去扩展,实现我们温馨的意义要求。比如大家想扩张Ioc,有了IOC可以解耦Controller和Model的涉嫌。一般的话,Controller实例的创导才需要IOC容器的主宰,我们直接从DefaultControllerFactory类型继承,重写Controller实例成立的逻辑即可,这样也避免了方方面面双重实现,做起事来就更经济了。

  在MFC写的ActiveX中,直接改动注册表。

            
DefaultControllerFactory类型在创造Controller实例的时候,有六个办法是足以增添的,一个是受保障的虚方法GetControllerType,我们可以定义自己的Controller类型的辨析方法的兑现,方法签名如下:

  http://support.microsoft.com/kb/161873/en-us

     protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName)

  mfc实现的ocx,要在app实现文件中概括五个公文:

            
其实这也是一个扩充点,但是我们前几天不扩大这里,因为IOC框架和这里的关系不大,我们要壮大的是第二受保障的虚方法,方法签名如下:

 在ActivexDemo.cpp 文件中贯彻以下办法

     protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType)

 

          
那些主意是用来成立Controller实例的,这太守好可以行使IOC容器来保管Controller实例,当然在DefaultControllerFactory类型中还有别的的扩展点,我们可以自己去看,全体代码我在此以前也贴出来过。

 

 1     public class UnityControllerFactory:DefaultControllerFactory
 2     {
 3         /// <summary>
 4         /// IOC的容器对象
 5         /// </summary>
 6         public IUnityContainer UnityContainer { get; private set; }
 7 
 8         /// <summary>
 9         /// 通过构造函数初始化IOC的容器对象
10         /// </summary>
11         /// <param name="unityContainer">传入的IOC容器对象</param>
12         public UnityControllerFactory(IUnityContainer unityContainer)
13         {
14             if (unityContainer != null)
15             {
16                 this.UnityContainer = unityContainer;
17             }
18             else
19             {
20                 throw new ArgumentNullException("容器对象不能为空!");
21             }
22         }
23 
24         /// <summary>
25         /// 
26         /// </summary>
27         /// <param name="requestContext"></param>
28         /// <param name="controllerType"></param>
29         /// <returns></returns>
30         protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
31         {
32             if (controllerType == null)
33             {
34                 return null;
35             }
36             return (IController)this.UnityContainer.Resolve(controllerType);
37         }
38     }

图片 8图片 9代码

         
代码很简单,大家将分析出来的Controller类型作为参数调用UnityContainer对象的Resolve方法,进而获取最终激活的Controller对象。这是样例代码,具体品种中,还要引入Unity的DLL,还索要登记,那一个我就不细说了。

#include “stdafx.h”
#include “ActivexDemo.h”
#include <comcat.h>    
#include <objsafe.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

     壮大点二:扩充ControllerActivator

CActivexDemoApp theApp;

          
DefaultControllerFactory对象并不直接激活目的Controller对象,真正激活Controller对象的是一个称为ControllerActiviator类型的对象,换句话说,DefaultControllerFactory对象委托ControllerActivator对象依照分析出来类型创立对应Controller对象。所有的ControllerActivator对象均落实IControllerActivator接口,该接口定义如下:

const GUID CDECL BASED_CODE _tlid =
        { 0x344B8576, 0xAB2C, 0x4D38, { 0xAE, 0x7, 0x73, 0x74, 0x22, 0x89, 0x72, 0xEA } };
const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;

/// <summary>Provides fine-grained control over how controllers are instantiated using dependency injection.</summary>
public interface IControllerActivator
{
    /// <summary>When implemented in a class, creates a controller.</summary>
    /// <returns>The created controller.</returns>
    /// <param name="requestContext">The request context.</param>
    /// <param name="controllerType">The controller type.</param>
    IController Create(RequestContext requestContext, Type controllerType);
}

// CActivexDemoApp::InitInstance – DLL 初始化

  
该接口中定义了Create方法实现针对对象Controller对象的开创,两个参数分别代表请求上下文和Controller的品类。我们在探望DefaultControllerFactory和ControllerActivator之间的关联呢,DefaultControllerFactory类型有六个构造函数,代码如下:

BOOL CActivexDemoApp::InitInstance()
{
    BOOL bInit = COleControlModule::InitInstance();

 1 /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.DefaultControllerFactory" /> class.</summary>
 2 public DefaultControllerFactory() : this(null, null, null)
 3 {
 4 }
 5 
 6 /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.DefaultControllerFactory" /> class using a controller activator.</summary>
 7 /// <param name="controllerActivator">An object that implements the controller activator interface.</param>
 8 public DefaultControllerFactory(IControllerActivator controllerActivator) : this(controllerActivator, null, null)
 9 {
10 }
11 
12 internal DefaultControllerFactory(IControllerActivator controllerActivator, IResolver<IControllerActivator> activatorResolver, IDependencyResolver dependencyResolver)
13 {
14     if (controllerActivator != null)
15     {
16         this._controllerActivator = controllerActivator;
17         return;
18     }
19     IResolver<IControllerActivator> arg_44_1 = activatorResolver;
20     if (activatorResolver == null)
21     {
22         arg_44_1 = new SingleServiceResolver<IControllerActivator>(() => null, new DefaultControllerFactory.DefaultControllerActivator(dependencyResolver), "DefaultControllerFactory constructor");
23     }
24     this._activatorResolver = arg_44_1;
25 }

    if (bInit)
    {
        // TODO: 在此添加你自己的模块起始化代码。
    }

   
第二个和第两个构造函数都有一个IControllerActivator类型的参数,第五个是程序集内部的,暂时不说,就说第二啊,DefaultControllerFactory正式通过该参数来创建目的Controller对象的,我们按照ControllerActivator对象来创设一个DefaultControllerFactory对象,他会最终被用于创立目标的Controller对象,大家的扩充点也就找到了。

    return bInit;
}

     大家扩充的源码如下:

// CActivexDemoApp::ExitInstance – DLL 终止

 1    public class NinjectControllerActivator : IControllerActivator
 2     {
 3         public IKernel Kernel { get; private set; }
 4 
 5         public NinjectControllerActivator()
 6         {
 7             this.Kernel = new StandardKernel();
 8         }
 9         public IController Create(RequestContext requestContext, Type controllerType)
10         {
11             return (IController)this.Kernel.TryGet(controllerType);
12         }
13 
14         public void Register<TFrom, TTo>() where TTo : TFrom
15         {
16             this.Kernel.Bind<TFrom>().To<TTo>();
17         }
18     }

int CActivexDemoApp::ExitInstance()
{
    // TODO: 在此添加你自己的模块终止代码。

    
扩大写好了,还索要在Global.asax文件之中举行挂号,否则无法运用。IOC相关的内容就不介绍了,我们能够活动钻研。

    return COleControlModule::ExitInstance();
}

     扩充点三:扩充DependencyResolver

// 创制组件连串    
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription) 
{    
    ICatRegister* pcr = NULL ;    
    HRESULT hr = S_OK ;    
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);    
    if (FAILED(hr)) return hr;    
    // Make sure the HKCR\Component Categories\{..catid…}    
    // key is registered.    
    CATEGORYINFO catinfo;    
    catinfo.catid = catid;    
    catinfo.lcid = 0x0409 ; // english    
    // Make sure the provided description is not too long.    
    // Only copy the first 127 characters if it is.    
    int len = wcslen(catDescription);    
    if (len>127) len = 127;    
    wcsncpy(catinfo.szDescription, catDescription, len);    
    // Make sure the description is null terminated.    
    catinfo.szDescription[len] = ‘\0’;    
    hr = pcr->RegisterCategories(1, &catinfo);    
    pcr->Release();    
    return hr;    
}  

          
虽然我们在构建DefaultControllerFactory对象的时候从不显得指定选用的ControllerActiviator参数,则它会选择默认的一个ControllerActivator对象DefaultControllerActivator来完成,该项目是一个民用类型,外界无法访问。源码如下:

// 注册组件连串    
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
 {    
    // Register your component categories information.    
    ICatRegister* pcr = NULL ;    
    HRESULT hr = S_OK ;    
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);    
    if (SUCCEEDED(hr)) {    
      // Register this category as being “implemented” by the class.    
      CATID rgcatid[1];    
      rgcatid[0] = catid;    
      hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);    
    }    
    if (pcr != NULL) pcr->Release();    
    return hr;    
}    
// 卸载组件体系    
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
 {    
    ICatRegister* pcr = NULL ;    
    HRESULT hr = S_OK ;    
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,    
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);    
    if (SUCCEEDED(hr)) {    
      // Unregister this category as being “implemented” by the class.    
      CATID rgcatid[1] ;    
      rgcatid[0] = catid;    
      hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);    
    }    
    if (pcr != NULL) pcr->Release();    
    return hr;    
}    
STDAPI DllRegisterServer(void) 
{    
    HRESULT hr;    
    AFX_MANAGE_STATE(_afxModuleAddrThis);    
    if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))    
        return ResultFromScode(SELFREG_E_TYPELIB);    
    if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))    
        return ResultFromScode(SELFREG_E_CLASS);    
    // 标记控件起始化安全.    
    // 创制先导化安全组件类别    
    hr = CreateComponentCategory(CATID_SafeForInitializing, L”Controls safely initializable from persistent data!”);    
    if (FAILED(hr)) return hr;    
    // 注册开头化安全    
    hr = RegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForInitializing);    
    if (FAILED(hr)) return hr;    
    // 标记控件脚本安全    
    // 创造脚本安全组件连串    
    hr = CreateComponentCategory(CATID_SafeForScripting, L”Controls safely scriptable!”);    
    if (FAILED(hr)) return hr;    
    // 注册脚本安全组件序列    
    hr = RegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);    
    if (FAILED(hr)) return hr;    
    return NOERROR;    
}    
// DllUnregisterServer – Removes entries from the system registry    
STDAPI DllUnregisterServer(void) 
{    
    HRESULT hr;    
    AFX_MANAGE_STATE(_afxModuleAddrThis);    
    if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))    
        return ResultFromScode(SELFREG_E_TYPELIB);    
    if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))    
        return ResultFromScode(SELFREG_E_CLASS);    
    // 删除控件初叶化安全入口.    
    hr=UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForInitializing);    
    if (FAILED(hr)) return hr;    
    // 删除控件脚本安全入口    
    hr=UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);    
    if (FAILED(hr)) return hr;    
    return NOERROR;    
}  

 1 private class DefaultControllerActivator : IControllerActivator
 2 {
 3     private Func<IDependencyResolver> _resolverThunk;
 4 
 5     public DefaultControllerActivator() : this(null)
 6     {
 7     }
 8 
 9     public DefaultControllerActivator(IDependencyResolver resolver)
10     {
11         if (resolver == null)
12         {
13             this._resolverThunk = (() => DependencyResolver.Current);
14             return;
15         }
16         this._resolverThunk = (() => resolver);
17     }
18 
19     public IController Create(RequestContext requestContext, Type controllerType)
20     {
21         IController result;
22         try
23         {
24             result = (IController)(this._resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
25         }
26         catch (Exception innerException)
27         {
28             throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_ErrorCreatingController, new object[]
29             {
30                 controllerType
31             }), innerException);
32         }
33         return result;
34     }
35 }

 

         
其实DefaultControllerActivator对象要像创设目标Controller对象,还凭借此外一个叫DependencyResolver的对象。所有的DenpendencyResolver类型均贯彻了IDenpendencyResolver接口,接口定义如下:

明天控件就可以在自登记时就注册为平安控件了。

 1 /// <summary>Defines the methods that simplify service location and dependency resolution.</summary>
 2 public interface IDependencyResolver
 3 {
 4     /// <summary>Resolves singly registered services that support arbitrary object creation.</summary>
 5     /// <returns>The requested service or object.</returns>
 6     /// <param name="serviceType">The type of the requested service or object.</param>
 7     object GetService(Type serviceType);
 8 
 9     /// <summary>Resolves multiply registered services.</summary>
10     /// <returns>The requested services.</returns>
11     /// <param name="serviceType">The type of the requested services.</param>
12     IEnumerable<object> GetServices(Type serviceType);
13 }

2、设置项目属性 将配置项目设置成静态库(.lib)

        
系统中利用的DependencyResolver是因此DependencyResolver类型注册的。DependencyResolver类型有一个誉为Current的静态属性,该属性表示的是现阶段的、IDependencyResolver类型的靶子。大家得以经过静态方法SetResolver来注册IDependencyResolver对象。需要验证一些,还有静态方法的DependencyResolver类型并不曾兑现IDependencyResolver接口,所以说该项目并不是的确的DependencyResolver类型,我们可以把它精通为一个Facade,它会聚了所要使用的对象和艺术而已,使用更有益。

图片 10

    
即使我们从未对DependencyResolver举办显示的挂号,则系统会接纳一个默认的称呼DefaultDependencyResolver的目的,本对象也是一个民用类型,外界不能利用。

 

    
当我们经过无参的构造函数或者经过将ControllerActivator参数指定为null的构造函数来创立DefaultControllerFactory实例的时候,那么用于激活Controller实例的将是由此DependencyResolver类型的静态属性Current表示的DependencyResolver对象来激活的,大家的恢弘终于也找到了。

3、       最终生成项目,ocx控件就暴发了。 

    最终实现的代码如下:

 

 1 public class NinjectDependencyResolver : IDependencyResolver
 2     {
 3         public IKernel Kernel { get; private set; }
 4 
 5         public NinjectDependencyResolver()
 6         {
 7             this.Kernel = new StandardKernel();
 8         }
 9 
10         public void Register<TFrom, TTo>() where TTo : TFrom
11         {
12             this.Kernel.Bind<TFrom>().To<TTo>();
13         }
14 
15         public object GetService(Type serviceType)
16         {
17             return this.Kernel.TryGet(serviceType);
18         }
19 
20         public IEnumerable<object> GetServices(Type serviceType)
21         {
22             return this.Kernel.GetAll(serviceType);
23         }
24     }

 ActiveX打包与发表

    好了,增添点写完
,大家有时间可以看看源码,可以有诸多启迪,拿到的也更多。

在VS2005或VS2008装置后发现路径**VC7\Common7\Tools\Bin\下有许多小工具,我对含蓄Cert的文书相比感兴趣。经过探讨,发现是关于申明和签约的,当然,该证件未被注脚认证部门确认。下边列出这多少个工具和自我的施用体验。
1。Makecert.exe —证书创设工具
2。Cert2Spc.exe —发行者证书测试工具
3。Signcode.exe —文件签字工具(VS2008带的是signtool)

四、小结

一、ActiveX发布步骤

   
我们可以总计了,到此,Controler激活系统这些小节自家就写完了。其实不是很复杂,大家在看的时候,刚起头别太关心代码的底细,先把握总体数据流向,或者叫请求脉络,把内部所波及到的靶子和涉嫌都收拾清楚了,然后再有针对的去看关系到的每个对象,不是画画图,不是画画,是画各样对象期间的关联图,图能画出来,表达您的心尖就有了总体把握了。如若太关爱细节,太关爱某个项目标代码,也会很容易顾此失彼,因为自己先导就是那么,总是看了前面忘记前边,请求的路线也不是很通晓。所以大家上学的时候也要有方法,方法对,学的就快,成就感就能很快发生。好了,说了这么多了,继续开足马力吧,希望自己写的事物对大家所有帮助。

在这里大概表达下,打包activeX需要创建证书,具体用到makecert 、cert2spc
、signtool
这五个VS提供的工具,工具在VS文件夹里面,以下制作过程需要在工具所在的公文夹下完成!
1、单击”起首”–>”运行(R)”–>输入”cmd”–>回车–>进入到操作的控件所在的目录(需要将方面所说的工具,和ocx控件放到一个文书夹下);
2、创制PVK文件(私人密匙文件),在命令行中输入”makecert -sk demo demo.pvk
-n CN=XXXXXXX公司”,然后回车;

sk-表示核心的密钥容器地方,ss-要旨的证件存储名称,
n-证书颁发对象,r-证书存储地点;

3、成立CER文件(企业证书),在命令行中输入”makecert -sk demo.pvk
demo.cer”,然后回车,如图8所示,若出现”Successed”提醒,则会在E:\
demo目录下生成demo.cer文件;

sk-代表要旨的密钥容器地点,is-颁发者的证书存储名称,
n-证书颁发对象,ic-颁发者的讲明存储地方,-$-授权范围(用于代码签名);

4、创造SPC测试软件出版商注明书,在命令行中输入”cert2spc demo.cer
demo.spc”,然后回车;

5、创制INF文件,用台式机编辑以下消息:

 

图片 11图片 12代码

[version]    

signature=”$CHICAGO$”

AdvancedINF=2.0

[Add.Code]

ActivexDemo.ocx=ActivexDemo.ocx

[ActivexDemo.ocx]

file-win32-x86=thiscab    
//告诉ie到什么地方去获取那些dll,file一共包括多少个部分,第一有些是file,这一个永远都是那样的(至少近日以来);第二局部报告注脚匡助的OS,win32意味着windows,mac就是苹果MAC  OX了;第三部分是CPU类型,比如说x86、  ppc  (Power  PC)、  mips或者alpha了   
//其中“thiscab”是一个关键字,表示 CAB 包含此 DLL,也可经过点名一条相对或相对路径,从一个 HTTP 地点下载所需的 DLL,   
例如:  file-win32-x86=http://www.mysite.com/mydir/NEEDED.DLL   
RegisterServer=yes    

clsid={468E4531-F890-47EC-8368-3BDA4448FF08}    
//“clsid”是快要安装的控件的 CLSID  
DestDir=11    
//它的值是dll将要存到本地硬盘的职位,要是它的值是10,则将dll放到\Windows或者\WinNT下;如果是11,则放到\Windows\System或者\WinNT\System32下;假诺未指定任何 DestDir(典型气象),则代码安装在固定的 OCCACHE 目录中。  
FileVersion=1,0,0,1
//表明了atl90.dll的版本号   

  

6、创立CAB文件,在命令行中输入”cabarc -s 6144 n demo.cab atl90.dll
Polygon.dll demo.inf”,-s
选项表示在压缩文件中保存用于代码签名的长空,n命令指定希望创设 CAB
文件,然后回车;

7、使用Code Signing Wizard签署一个CAB文件,在决定台输入signtool
signwizard 进入到signtool窗体中;

图片 13

8、单击”下一步(N)”按钮,拔取要拓展数字签名的且已做成CAB包的公文Dome.cab文件;

图片 14

9、拔取好CAB包后单击”下一步(N)”按钮,在挑选想要的签字类型里甄选”自定议(C)”并单击”下一步(N)”按钮;

图片 15

10、接下去单击”从文件采用(F)”按钮,选取刚刚制作的demo.cer;

图片 16

11、在单击”下一步(N)”,然后选用”CSP中的私钥(K)”;

图片 17

12、在单击“下一步(N)”按钮,然后在散列算法中精选“shal”,并单击“下一步(N)”按钮。

图片 18

13、在”证书路径中的证书”中精选”证书路径中的所有证件,包括根证书(C)”,在”另外证书(可选)”中采纳”包括在偏下PKCS
#7
证书(.p7b)文件中的证书(P):”,并单击”浏览(R)…”按钮接纳demo.spc文件,采用完后单击”下一步(N)”按钮;

图片 19

14、接下去在弹出的”数据描述”窗口中输入集团的称呼和网址并单击”下一步(N)”按钮;

图片 20

15、现大部份工作都已形成,在接下去的一步当中是可选的操作,其效率只是为CAB出席时间戳,此步骤完全能够不做,VeriSign: 
http://timestamp.verisign.com/scripts/timstamp.dll

图片 21

16、完成,单击”下一步(N)”按钮便可赶到数字签名向导的结尾一步,即操作总览,如图26所示,单击”完成”按钮便可大功告成;

 图片 22

 

上边是微软代码签名证书(.pvk/.spc)签名指南的言传身教

 

 

本使用指南演示如何利用WoSign代码签名证书来给微软代码签名,Thawte和VeriSign代码签名证书也是利用相同措施,只是利用不同的岁月戳URL。

    
用户在在线申请代码签名证书时会生成证书私钥文件,如:myCert.pvk,而代码签名证书成功揭橥后的证书文件为公钥文件,如:myCert.spc,又称:软件发行证书(Software
Publishing Certificate) 。
代码签名证书一般都是选取公钥和私钥分离的多少个文件措施,适合于 DOS
命令行形式的代码签名。如果您您愿意把代码签名证书导入到Windows证书存储区中,从而简化签名操作,请参考:不等证书格式转换指南

     WoSign代码签名证书的根证书链为:
UTN-USERFirst-ObjectWoSign Code
Signing Authority

    使用微软的 SignCode.exe
就足以对微软的代码举办签字,假设你没有此文件,点击
这里下载。 Signcode.exe 可以行使 DOS
命令行格局实现签约,我们推荐用户采纳数字签名向导格局,简单方便。请留意:假设你支付的ActiveX为IE加载项,请先数字签名每个CAB文件中的.dll和.ocx等公事,再把这个文件打包成.cab文件后再数字签名.cab文件,以管教所有IE加载项都被IE验证和亲信,否则会展现“未阐明”而可能影响健康运作。

    具体签名向导过程如下:

     (1) 运行 Signcode.exe , 要求你采取需要签字的文本,补助:可执行文件
(*.exe; *.dll; *.ocx) ; Cabinet 打包文件 (*.cab) 和目录文件
(*.cat) ,如下图 1 所示 ( 如: TestSign.cab)
,请留意:如若签名的文本已经有数字签名,则会被新的签名覆盖:

图片 23

(2) 点击“下一步”后,如下图 2
所示,会要求您采取“签名类型”,缺省的“典型”签名类型;请选取“自定义”
签名类型:

图片 24

 (3) 如下图 3
所示,点击“从文件采用”签名证书 ( 公钥文件 ),如: WotoneCS.spc :

图片 25

   (4) 点击“下一步”后,如下图 4
所示,会要求您接纳私钥文件,如: WotoneCS.pvk ,其他参数不用动:

图片 26

  (5) 点击“下一步”后,如下图 5
所示,会指示要求输入私钥密码:

图片 27

   (6) 点击“下一步”后,如下图 6
所示,会指示要求选拔散列算法 ( 摘要算法、缩微图算法 ) ,缺省为 sha1
,也足以选 md5 :

图片 28

(7) 点击“下一步”后,如下图 7
所示,采纳怎么证书包括到数字签名中,直接点击“下一步”即可,即拔取缺省的席卷根证书:

图片 29

(8) 如下图 8
所示,要求填写该签名代码的功能描述,推荐一定要认真填写,因为此音信将会在最后用户下载此代码时呈现,有助于最后用户了解此代码的效率以确定是不是下载安装。第一行“描述”是指此代码的效能文字描述,第二行“
Web
地点”则让最后用户点击文字描述来详细理解此代码的功力和采纳方法等,本演示中的“
Web 地方”为WoTrust代码签名证书简介页面:

图片 30

 (9) 点击“下一步”后,如下图 9
所示,选中“将时刻戳添加到数量中”,请使用:

 

WoSign 免费提供的刻钟戳服务URL:
http://timestamp.wosign.com/timestamp

    
时间戳服务非凡关键,添加时间戳后,虽然你的代码签名证书已经晚点,但出于您的代码是在讲明有效期内签名的,则时间戳服务保证了此代码依旧可信,最终用户仍旧可以放心下载,使得即使代码签名证书已经晚点,您也无需重签和重新发表已经签署的代码。

图片 31

(10) 点击“下一步”后,如下图 10
所示,会提醒已经到位数字签名向导,点击“完成”后还会唤醒您输入私钥密码,就完了代码签名证书的代码签名。

图片 32

(11) 现在,需要选取 chktrust.exe 来查看已经签署的代码, chktrust.exe
文件已经打包在 signtool.rar中。进入
DOS 命令指示符,并跻身曾经签署的文件所在目录 ( 如:
d:\sign\TestCA.cab) ,键入命令: chktrust testcs.cab
,则会彰显实际使用时在 IE 浏览器下载页面的意况,如下图 11 所示,对于Win
XP操作系统,会来得软件名称和发行者名称,其中软件名称就是你在第(8)步输入的描述,点击此称呼就链接到您在第(8)步填写的网址,而点击发行者名称,则会显得你的签字消息和时间戳音信。对于Win2000操作系统,则稍有两样,第
1
行的红线部分就是岁月戳记录的签署时的当地时间,请留心:此时间不是取签名电脑的时刻,而是提供时间戳服务的服务器总结出来的签字电脑安装的四野时区的地头时间。第
1 行红色文字就是在第 8 步中输入的叙述文字,点击此蓝色文字就足以访问在第
8 步中输入的 Web 描述页面。第 2
行紫色文字则为该代码的发行者,也就是代码签名证书的申请者(拥有者)(
如:广州市沃通电子商务服务有限公司) ,点击可以查阅证书的详细信息;第 2
行有棕色下划线部分显得“发行商可靠性由 WoSign Code Signing Authority 验证
”就是此代码签名证书的讲明颁发者。

图片 33

12) 点击“是”或“运行”,则会唤醒“ TestSign.cab: Succeeded ”表示代码
TestSign.cab
签名验证有效,可以放手网站上了。请留心:签名后的CAB文件放到网站上急需运用
object 格局。

请注意:无法仅签约CAB文件,CAB包中享有DLL文件都要先签名后再装进,再签字CAB文件,否则IE浏览器会突显为“未表明的发行者”而影响健康使用,甚至杀毒软件会觉得是毒而被删除!如下图所示的其实案例:

 

图片 34

 

在Web页中投入ActiveX 控件

在改动了IE的白城设置后,如故无法调用控件的法子,需要将做客的站点设置为“受信站点”,则方能正常使用控件
在<html> 和<head>之间插入
<!– saved from url=(0017)http://localhost/ –>
则在IE窗口上方不会弹出肉色指示条 。

  在HTML页面中利用ActiveX控件包含两个基本操作:将控件放入HTML中;将该控件下载给用户;在用户机器上安装该控件。假使只是本着IE用户,在HTML中插入ActiveX控件就比较简单;尽管同时兼任IE和Netscape用户,则要做更多干活。我们清楚,HTML文件由文本和各类标志(tags)组成,ActiveX
控件对于IE在HTML中的标志是<OBJECT>,该标记有多少个第一的参数特性,它们是:

  1.ID:为控件提供一个标识名称,为HTML代码提供一种访问该控件的主意。

  2.CLASSID:是该控件唯一的UUID,告诉IE装入哪个目的。假使采纳已经开发好的控件,它的CLASSID可以通过调用Win95或NT下的运用Regedit来查找。从起首菜单中运作该程序,展开HKEY_CLASSES_ROOT项,可以观察按字母顺序排列的注册表,找到需要使用的控件名,例如WClnt,展开时可看到一个CLSID文件夹,里面就是该控件的CLASSID。

  尽管是投机用VC开发控件,该UUID能够在ActiveX控件项目中的ODL(对象描述库)文件中找到;通过翻看控件的类音信注释来定位一定控件的UUID,例如,要找到CMyControl控件的UUID,则需要找到以下代码:

  // Class information for CMyControl

  [uuid
(051C4748-1262-11D2-87C1-00A024D948FB),

  licensed,

  helpstring(“CmyControl Control”),
control ]

  uuid前面括号中的内容就是该控件的UUID。

  3.CODEBASE:如若在用户机器上从不控件的脚下版本,该参数告诉用户浏览器在什么地方可找到要下载的控件和新型版本号.当控件作了修改后,能够更改版本号强制用户重新下载。

  4.PARAM:该标记用于安装控件的最先属性值,它有多个特性:Name和Value,即属性名称和属性值。

  其它还有局部标记,如:Width代表该控件所占的升幅,Height表示中度等,总体来说,这样一个插入控件的HTML代码和插入Java
Applet的HTML代码十分相像。

  下边是一个嵌有ActiveX控件的HTML代码示例:

 

ID=“CMyControl”

CLASSID=“clsid:051C4748-1262-11D2-87C1-00A024D948FB

CODEBASE=“http://www.mysite.com.cn/ocxdir/mycontrol.ocx#version=1,0,0,1”

WIDTH=400

HEIGHT=200

ALIGN=center

HSPACE=0

VSPACE=0

  假使指望控件仍是可以在Netscape中运作,除了Netscape需加装插件外,HTML也要加一些叠加标记,下边的例证中EMBED段就是为Netscape加上的。假设使用MFC开发OCX控件,则少数用户率先次访问时除了下载OCX文件外,还要下载相应的MFC
DLL,下载量变大,这时可将相关文件在劳动器端打包成可以在客户端自解压安装的CAB文件。经过修改后的HTML代码段如下:

<ALIGN=“CENTER” CLASSID=“clsid:

7BCA18C6-2178-11D2-87C1-00A024D948FB”

WIDTH=“1200” HEIGHT=“900” ID=“marquee”

CODEBASE=“http://218.168.188.188/scadaweb/

WClnt.cab#version=1,0,0,1”>

<EMBED
ALIGN=“CENTER”CLASSID=“clsid:7BCA18C6- 2178-11D2-87C1-00A024D948FB”

WIDTH=“1200” HEIGHT=“900” ID=“marqueequot;”

CODEBASE=“http://218.168.188.188/scadaweb/

WClnt.OCX#version=1,0,0,1”

TYPE=“application/oleobject” >

 

 

 

 

实时动态页面的落实方案

  对实时动态页面的渴求多暴发于一些要求自动更新实时数据的使用中,如电网监控、股市监测等。具体要求是:用户只需选拔希望浏览的图片,但无需到场操作,该图片就能遵照实时数量不断更新,用户总能观望到新型情状。

  要促成上述效率,结构上有两种方案:一种是安装一个中介服务器,该服务器作为控件和后台系统消息交换的中介;另一种是不设中介服务器,但在提供实时数据的后台服务器上留出供控件通信用的数码接口,控件可以直接从后台服务器上定时得到当前实时数据。按数据提供模式分也有二种:一种是由客户端定时向服务器发出请求,指明需要的实时数据,服务器收到请求后将满足请求的动态数据发送至相应客户;另一种是客户端只请求一遍,服务器端便定时将知足请求的实时数据传到客户端,直到客户转换要来得的图样或为止刷新。上述各方案都有其亮点和局限,在接纳中可考虑实际情况采纳相应方案。

  工作流程为:用户先从Web服务器上下载包含ActiveX
控件的网页,控件随即在客户机上注册运行,并由此Winsock同中介服务器或直接同提供实时音讯的网,如股票信息网相连接,定时取得动态实时数据,并刷新显示。在那个系统中,客户有两条路线拿到音讯,一条是和Web
Server的接连,从这条线上用户访问主页;另一条就是控件和后台音信网的连续,从这条线路上用户可以访问实时数据。后一条路线用Winsock建立,传输速度远高于前一条线路,且控制灵活、效用高,不和主页下载争资源。通过那条线路,用户仍能够传递远程控制音讯实现遥控操作。

利用MFC开发ActiveX控件

  利用VC5.0开发的这种控件,功效可扩张性强,理论上单独的VC5.0程序有所的效率,该控件都能促成,例如控件直接绘制浏览器,可以运用OpenGL等图库,图形图像功用强大。实时数码刷新频率理论上可达飞秒级,用户通过鼠标可以兑现各项交互操作,如旋转、缩放,图2就是一幅GL图形,并有一个缩放工具条举办缩放操作。假诺是在微机上见到,可以看到这么些三维图在频频转动。

  应该说,较好的开发工具可一贯用API编程或使用ATL模板库,利用MFC开发ActiveX控件不是一个好的采取,因为控件运行需要MFC
DLL的支撑。假若客户机器上未曾这个类库(这种处境很少,但真的存在),第一次下载就要花费些工夫。但是对此熟识MFC的开发员来说,那一个问题相对MFC提供的惠及来说都是足以忽略的。

  由于VC5.0对ActiveX控件的开销提供了诸多便民,所以开发一个ActiveX控件并不像许多个人设想中的那么难堪复杂,通过VC
5.0的AppWizard,实现控件的主类从科尔Control类派生出来,该类则是CWnd的一个子类,所以您可以像对窗口类编程一样对这么些主类编程。为了兑现地点提及的效率,首先必要重载它的OnDraw函数插手需要绘制的对象,参与Winsock类(CSocket或CAsyncSocket),以实现与后端数据服务器的通信。假若需要用OpenGL绘制丰裕多彩的立体图,则要开首化GL环境。其他的做事就在于用户如何控制程序的调度,使得各职能都能正常办事且与其他一些常规通信。其余,后端服务器程序也要扩展对应于该控件的接口。

  这样的一个主次编译通过后,就改为一个可用于Web的控件,后缀名是OCX。按照后边叙述的格局将该OCX置入主页,基本的办事就是完成。

  综上所述,利用VC5.0开发ActiveX控件用于Web浏览,紧要有以下多少个特征:

  1.行使Winsock的通信机制,速度快、控制灵活、效能高;

  2.控件采取VC5.0编制,功能可增添性很强;

  4.控件第一次下载即使稍费时间,但下载后即在用户机上注册,未来可径直调用,速度效能均好;

  5.ActiveX技术是微软发展的首要性,且已变为当下软件发展的风尚所向,发展空间广阔;

  6.系统接纳VC开发,能够行使已部分使用C语言编制的系统,开发工作量大大减弱。

  Web页面的开发紧要分为三类:静态Web页面、半动态Web页面以及Client端动态页面。本文重点阐释基于ActiveX
Control(控件)动态实时页面的支付。

regsvr32 netshare.ocx        注册netshare.ocx控件

regsvr32 /u netshare.ocx    解除netshare.ocx控件的挂号