只在UnitTest和WebHost中的出现的关于LogicalCallContext的严重问题
2010-08-29 00:59
399 查看
最近一直在进行公司内部框架的升级工作,其中一个小的部分就是通过HttpSessionState和CallContext建立一套统一的、可扩展的用于管理上下文信息的框架。在为写好的程序编写Unit Test和QuickStart的时候,遇到了两个基于LogicalCallContext的严重问题。导致这两个问题的根源还没有来得及去追踪,或许是微软VS Unit Test框架本身和WebHost本身的一个Bug。现在将其写出来,一来是希望读者在遇到相同情况的时候知道LogicalCallContext可能是影响因素之一,另一方面也希望借助社区的力量快速找到问题的症结。以下内容假定读者已经对CallContext有一个大概的了解,并且明白LogicalCallContext和IllogicalCallContext之间的区别。对此不了解的读者,可以参考我的文章《如何实现对上下文(Context)数据的统一管理 》。
然后通过如下一个TestMethod测试一个以LogicalCallContext的形式保存的上下文(通过调用CallContext的静态方法LogicalSetData)是否可以通过相同的Key被正常获取。
但是运行上面的UnitTest的时候,在TestResult对话框中会出现一个Error。从下图中我们可以看出这是一个序列化的错误,具体的出错信息为:Unit Test Adapter threw exception: Type is not resolved for member 'UnitTests.LogicalContextItem`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]],UnitTests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null',即我们自定义的类型无法解析。这就有点让人费解了,在这个实例中,LogicalContextItem<TValue>:类型本身是直接定义在UnitTest这个项目之中的,何来无法解析之理。
直接运行上面的程序,SerializationException异常照常被抛出,从下图给出的错误对话框可以看出,该异常具有和上面完全一样的错误信息,即不能解析我们自定义的LogicalContextItem<TValue>类型。
为了找出抛出SerializationException异常的根源,我们可以来该异常的StatckTrace。从下面给出的内容,我们可以看出来该异常最终就是通过WebHost抛出来得。
一、在VS Unit Test下设置LogicalCallContext导致的序列化问题
为了演示在Unit Test下设置LogicalCallContext会导致怎样的问题,为此我写了一个非常简单的例子去重现它。首先我定义了如下一个形如Key-Value 的类型:LogicalContextItem<TValue>:[Serializable] public class LogicalContextItem<TValue> { public string Key { get; private set; } public TValue Value { get; set; } public LogicalContextItem(string key, TValue value) { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } this.Key = key; this.Value = value; } }
然后通过如下一个TestMethod测试一个以LogicalCallContext的形式保存的上下文(通过调用CallContext的静态方法LogicalSetData)是否可以通过相同的Key被正常获取。
[TestClass] public class LogicalSetDataFixture { [TestMethod] public void LogicaSetData() { LogicalContextItem<string> userName = new LogicalContextItem<string>("__userName", "Foo"); CallContext.LogicalSetData(userName.Key, userName); Assert.AreEqual<string>("Foo", ((LogicalContextItem<string>)CallContext.LogicalGetData("__userName")).Value); } }
但是运行上面的UnitTest的时候,在TestResult对话框中会出现一个Error。从下图中我们可以看出这是一个序列化的错误,具体的出错信息为:Unit Test Adapter threw exception: Type is not resolved for member 'UnitTests.LogicalContextItem`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]],UnitTests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null',即我们自定义的类型无法解析。这就有点让人费解了,在这个实例中,LogicalContextItem<TValue>:类型本身是直接定义在UnitTest这个项目之中的,何来无法解析之理。
二、在VS ASP.NET WebHost下设置LogicalCallContext导致的序列化问题
我们知道,为了给基于ASP.NET的Web应用的开发者带来便利,Visual Studio内置了一个简单(和IIS比较而言)的Web应用承载工具,即WebHost。如果采用基于WebHost的承载方式(这是默认的承载方式),上面的错误同样会发生。为了演示,我们同样使用上面定义的LogicalContextItem<TValue>类型,然后在一个单纯的WebPage中的Load事件处理方法中编写了如下一段简单的代码:public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { LogicalContextItem<string> userNameContext = new LogicalContextItem<string>("__userName", "Foo"); CallContext.LogicalSetData(userNameContext.Key, userNameContext); var userName = ((LogicalContextItem<string>)CallContext.LogicalGetData("__userName")).Value; Response.Write(userName); } }
直接运行上面的程序,SerializationException异常照常被抛出,从下图给出的错误对话框可以看出,该异常具有和上面完全一样的错误信息,即不能解析我们自定义的LogicalContextItem<TValue>类型。
为了找出抛出SerializationException异常的根源,我们可以来该异常的StatckTrace。从下面给出的内容,我们可以看出来该异常最终就是通过WebHost抛出来得。
at Microsoft.VisualStudio.WebHost.Host.ProcessRequest(Connection conn) at Microsoft.VisualStudio.WebHost.Server.OnSocketAccept(Object acceptedSocket) at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
三、采用IIS承载我们的Web应用可以解决上述问题
为什么我说这个问题只和内置于VS中的Web应用承载工具WebHost有关呢?一来是因为上面给出的异常StackTrace已经明显反映了异常最后总就是从WebHost跑出来的。另一个主要的原因就是,如果我直接采用IIS来承载的话,运行上述的代码后一切正常。有兴趣的读者可以从这里下载实例程序进行试验。你只需要该Web应用进行了如下配置,放弃使用Vistual Studio Development Server,而选用Local IIS Web Server即可。相关文章推荐
- 关于Win10系统下VC2013安装Unit test出现问题的解决办法
- 解决COCOS2D-X与JNI交互游戏出现崩溃的问题call to OpenGL ES API with no current context (logged once per thread)
- Win10中VC2013安装Unit test组件出现问题解决方案
- 关于httpcontext实际使用时出现的一个问题
- 关于react-native出现SyntaxError /Users/mac/firstTest/index.ios.js: Unexpected token的问题
- 一起谈.NET技术,基于CallContextInitializer的WCF扩展导致的严重问题
- 【selenium】python+selenium+unittest,关于每次执行完一个测试用例都关闭浏览器等时间较长的问题之解决方案
- 关于win7 64位 sp1 旗舰版安装.net FrameWork时出现的“严重错误”问题
- 分享:关于Unit Test中无法生成覆盖率报告问题的解决
- 基于CallContextInitializer的WCF扩展导致的严重问题
- 关于ssh 框架 applicationContext.xml文件中配置hibernate数据库出现的一个小问题
- 关于httpcontext实际使用时出现的一个问题
- 关于使用EJB时出现javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.NamingContextFactory的问题
- 解决Emacs里面的Python mode下跑UnitTest的异常问题
- 关于问题“应用程序未安装或安装时出现「INSTALL_FAILED_CONTAINER_ERROR」”的解决方案方面的事情
- 关于onvif对接海康设备出现soap->error=4的问题
- 关于火车票订购网出现的一些问题
- 关于 LF will be replaced by CRLF 问题出现的原因以及解决方式
- 关于解决 AVD的中文路径出现的问题和更改avd的默认路径
- 关于uiwebview或者网站可能出现的缓存js,css问题