如何在C#动态调用的Web Service中添加SOAP Header?
如何为动态调用的Web Service添加SOAP Header?
你的代码通过ServiceDescriptionImporter动态生成了Web Service客户端代理,而这个代理本质是SoapHttpClientProtocol的子类,我们可以利用这个基类的特性来添加SOAP Header,分两种场景处理:
场景1:添加简单文本型SOAP Header
这种情况适合不需要复杂XML结构的Header,直接通过基类的RequestHeaders属性添加即可。在调用mi.Invoke之前插入以下代码:
// 将动态生成的代理转换为SoapHttpClientProtocol基类 var client = (System.Web.Services.Protocols.SoapHttpClientProtocol)wsvcClass; // 添加普通文本Header client.RequestHeaders.Add("AuthToken", "your-token-value"); // 如果Header需要指定命名空间,用XmlQualifiedName client.RequestHeaders.Add( new System.Xml.XmlQualifiedName("AuthToken", "http://your-service-namespace.com/"), "your-token-value" );
场景2:添加复杂结构的SOAP Header
如果Header是带XML节点的复杂结构,需要先定义对应的实体类,再通过反射赋值给代理:
步骤1:定义Header对应的C#类
假设你的SOAP Header结构如下:
<AuthHeader xmlns="http://your-service-namespace.com/"> <Username>admin</Username> <Password>123456</Password> </AuthHeader>
对应的C#类代码:
using System.Xml.Serialization; [XmlType(Namespace = "http://your-service-namespace.com/")] public class AuthHeader { public string Username { get; set; } public string Password { get; set; } }
步骤2:将Header类编译到动态程序集
在现有代码的编译步骤后,加入这段代码把Header类编译进去:
// 定义Header类的代码字符串 string headerClassCode = @" using System.Xml.Serialization; [XmlType(Namespace = ""http://your-service-namespace.com/"")] public class AuthHeader { public string Username { get; set; } public string Password { get; set; } }"; // 把Header类编译到同一个动态程序集 CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1); results = provider1.CompileAssemblyFromSource(parms, headerClassCode);
步骤3:创建Header实例并赋值给代理
var client = (System.Web.Services.Protocols.SoapHttpClientProtocol)wsvcClass; // 获取Header类的类型 Type headerType = results.CompiledAssembly.GetType("AuthHeader"); // 创建Header实例 object headerInstance = Activator.CreateInstance(headerType); // 设置Header的属性值 headerType.GetProperty("Username").SetValue(headerInstance, "admin"); headerType.GetProperty("Password").SetValue(headerInstance, "123456"); // 找到代理类中对应的Header属性并赋值(如果服务端WSDL定义了Header,代理会自动生成该属性) client.GetType().GetProperty("AuthHeaderValue").SetValue(client, headerInstance);
补充:服务端WSDL已定义SOAP Header的情况
如果你的Web Service的WSDL里已经包含了SOAP Header的定义,ServiceDescriptionImporter在生成代理时会自动创建对应的Header类和属性,你只需要直接实例化并赋值即可:
var client = (System.Web.Services.Protocols.SoapHttpClientProtocol)wsvcClass; // 获取自动生成的Header类型(注意替换成实际的命名空间和类名) Type headerType = results.CompiledAssembly.GetType("YourGeneratedNamespace.AuthHeader"); object header = Activator.CreateInstance(headerType); // 设置Header属性 headerType.GetProperty("Token").SetValue(header, "your-token"); // 赋值给代理的对应属性 client.GetType().GetProperty("AuthHeaderValue").SetValue(client, header);
内容的提问来源于stack exchange,提问作者Manoj
相关产品推荐
相关产品推荐

