公司最近需要用WSE3.0也就是Web Service Enhancements 3.0,虽然此技术有被WCF淘汰之势,也不是很清楚WSE,但看在公司给的那点银子上,也不得不认真学了。希望能写一个系列,没耐心一向是我缺点。(PS:我的开发环境是.net FrameWork 3.5 sp1,Visual Studio 2008 Sp1 ,Windows Server 2008 sp1)
由于WSE有被WCF取代之势,WSE3.0的安装包已经不支持Visual Studio 2008,所以首相要解决的问题是如何让WSE3.0被Visual Studio 2008 支持。
问题分析:
在我们利用VS工具引用Web Service的时候会生成一些代理类文件,其机制是VS这个开发工具调用MsDiscoCodeGenerator这个工具,接着MsDiscoCodeGenerator利用ServiceDescriptionImportor来生成我们在开发工具中看到的类。这是普通Web Service Proxy的生成方式,而WSE是利用WseExtensionImpotor这个类来生成。关于MsDiscoCodeGenerator这个工具可以在注册表中找到,路径为:HEKY_LOCAL_MACHINE->Microsoft->Visual studio ->9.0->generator,
,
具体信息可以参看http://www.drewnoakes.com/snippets/WritingACustomCodeGeneratorToolForVisualStudio/。所以要解决这个问题,首先就要让VS知道我们用WseExtensionImportor。
具体解决步骤:
- 配置devenv.exe.config,把下面的代码paste到里面,devenv.exe.config跟Vs是一个目录。目的就是让VS开发工具知道我们要用WseExtensionImportor类来生成代理类文件
<system.web> 第一步做完后并不会生成任何代码,其原因是Wse需要知道你当前的项目是否要启用WSE(就像我们在Visual Studio 2005中点击工程右键,启用WSE)。因为WSE通过查询一个委托来决定当前项目是否启用了WSE,而这个标志是WSE Add-in分配的,只不过这个分配在Visual Studio 2005中生效,而Visual Studio 2008中不生效。通过查看WseExtensionImportor可以知道其中有一个属性就是标示这个启用状态的。
public class WseExtensionImporter : SoapExtensionImporter{ public static WseExtensionImporter.IsWseReferencedInActiveProject IsWseReferencedActiveProjectImplementation; public static WseExtensionImporter.IsWseReferenced IsWseReferencedImplementation; public WseExtensionImporter(); public override void ImportMethod(CodeAttributeDeclarationCollection metadata); public delegate bool IsWseReferenced(string rootNamespace); public delegate bool IsWseReferencedInActiveProject(); }
所以我们必须实现这个属性,并以Visual Studio 插件的形式安装到Visual Studio 中
- 构建插件,利用Visual Studio的插件向导生成一个工程,添加对System.Web.Services,Microsoft.Web.Service3,VSLangProj这3个程序集的引用,并在OnConnect方法中加上如下代码。
public void OnConnection(object application, ext_ConnectMode connectMode,object addInInst, ref Array custom) { _applicationObject = (DTE2)application; _addInInstance = (AddIn)addInInst; WseExtensionImporter.IsWseReferencedActiveProjectImplementation = delegate() { foreach (object activeProjectObj in (Array)_applicationObject.ActiveSolutionProjects) { Project project = activeProjectObj as Project; if (project == null) continue; VSProject vsProject = project.Object as VSProject; if (vsProject == null) continue; if (vsProject.References.Find("Microsoft.Web.Services3") != null) return true; } return false; }; }
插件dll我已经提供,在这里下载/Files/david-cj/Addins.rar
关于插件安装的问题,如果你是利用向导工程开发插件,默认会装上插件,但如果用我提供的dll, 需要在mydocuments\visual studio 2008\AddIns\目中添加如附件提供的2个文件(可能目录不存在,自己建一个),Paste过去就可以了
- 添加Web Service引用的问题,需要在“Add Service Reference”中点击“Advance”。