我在C#中有一个代码,它基本上读取传递的WSDL以动态生成程序集,然后我们访问该服务的所有方法和属性。
/// <summary>
/// Builds an assembly from a web service description.
/// The assembly can be used to execute the web service methods.
/// </summary>
/// <param name="webServiceUri">Location of WSDL.</param>
/// <returns>A web service assembly.</returns>
private Assembly BuildAssemblyFromWSDL(Uri webServiceUri)
{
if (String.IsNullOrEmpty(webServiceUri.ToString()))
throw new Exception("Web Service Not Found");
XmlTextReader xmlreader = new XmlTextReader(webServiceUri.ToString() + "?wsdl");
ServiceDescriptionImporter descriptionImporter = BuildServiceDescriptionImporter(xmlreader);
return CompileAssembly(descriptionImporter);
}
/// <summary>
/// Builds the web service description importer, which allows us to generate a proxy class based on the
/// content of the WSDL described by the XmlTextReader.
/// </summary>
/// <param name="xmlreader">The WSDL content, described by XML.</param>
/// <returns>A ServiceDescriptionImporter that can be used to create a proxy class.</returns>
private ServiceDescriptionImporter BuildServiceDescriptionImporter(XmlTextReader xmlreader)
{
// make sure xml describes a valid wsdl
if (!ServiceDescription.CanRead(xmlreader))
throw new Exception("Invalid Web Service Description");
// parse wsdl
ServiceDescription serviceDescription = ServiceDescription.Read(xmlreader);
// build an importer, that assumes the SOAP protocol, client binding, and generates properties
ServiceDescriptionImporter descriptionImporter = new ServiceDescriptionImporter();
descriptionImporter.ProtocolName = "Soap";
descriptionImporter.AddServiceDescription(serviceDescription, null, null);
descriptionImporter.Style = ServiceDescriptionImportStyle.Client;
descriptionImporter.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
return descriptionImporter;
}
这段代码适用于除受保护或受保护的wsdls之外的所有wsdls。代码在if (!ServiceDescription.CanRead(xmlreader))
行失败,因为它无法访问传递的服务wsdl。当我尝试访问浏览器中的URL时,我得到500:服务器错误。当我使用适当的身份验证登录我们的Web应用程序,然后使用相同的会话,如果我复制URL - 我可以访问wsdl。 Fyi,在不同的应用程序中,我们通过传递带有服务用户ID /密码的SM Cookies动态调用此服务。
话虽如此,我怎么能这样做,动态访问受保护的wsdl?传递cookie信息以访问wsdl需要做哪些更改?有什么想法吗?
答案 0 :(得分:3)
private Assembly BuildAssemblyFromWSDL(Uri webServiceUri)
{
if (String.IsNullOrEmpty(webServiceUri.ToString()))
throw new Exception("Web Service Not Found");
HttpWebRequest wr = (HttpWebRequest)HttpWebRequest.Create(webServiceUri.OriginalString + "?wsdl");
wr.Credentials = new NetworkCredential("username", "password"); //replace with your credentials
HttpWebResponse wres = (HttpWebResponse)wr.GetResponse();
XmlTextReader xmlreader = new XmlTextReader(wres.GetResponseStream());
ServiceDescriptionImporter descriptionImporter = BuildServiceDescriptionImporter(xmlreader);
return CompileAssembly(descriptionImporter);
}
这将允许您在获取wsdl之前传递凭据
答案 1 :(得分:1)
这非常好,但在BuildAssemblyFromWSDL之后,当我尝试调用任何方法时,它再次给我一个错误消息,如...
请求失败,HTTP状态为401:未经授权。 at(T)type.InvokeMember(methodName,BindingFlags.InvokeMethod,null,obj,args);
调用方法的代码就像......
public T InvokeMethod<T>(string serviceName, string methodName, params object[] args)
{
// create an instance of the specified service
// and invoke the method
object obj = this.webServiceAssembly.CreateInstance(serviceName);
Type type = obj.GetType();
return (T)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, args);
}
现在,我不知道如何在这里传递凭证..即使我试图通过其他方法传递,但仍然得到未经授权的错误..
真的很感谢你能帮忙......