Detailed ServiceDescription / Proxy from WSDL
I am using the classes ServiceDescription / ServiceDescriptionImporter to dynamically call web services. I'd like to dig a bit deeper into the WSDL description and get
1) Parameter info for each of the web methods
2) The actual types / composition each parameters of all the web methods (ie if a WebMethod takes some complex type as a parameter, I need to know the primitive / other types it is composed of as well, if possible)
Here is the code I have for the dynamical call:
public static object CallWebService(string webServiceAsmx, string serviceName, string methodName, object[] args = null)
{
WebClient client = new WebClient();
Stream stream = client.OpenRead(webServiceAsmx + "?wsdl");
ServiceDescription description = ServiceDescription.Read(stream);
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap12";
importer.AddServiceDescription(description, null, null);
importer.Style = ServiceDescriptionImportStyle.Client;
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties;
I have been able to get as far as finding some basic info such as the method names, parameter info, but I need deeper analysis. For example I need access to essentially all the information that Wsdl.exe produces in proxy classes but I dont want to have to run Wsdl.exe, just discover the information dynamically. For every method I need to know what its return type is composed of, what its parameters are composed of, etc. I know its in the WSDL just not sure how to programmatically extract it. Here are some of the classes Ive been exploring:
ServiceDescription.Description
ServiceDescription.Messages
ServiceDescription.Types
It seems that alot of them come up empty though?
Thanks in advance.
EDITS
I got a little further, this is the xml schema (WSDL) I am trying to traverse:
- <s:complexType name="Session">
- <s:complexContent mixed="false">
- <s:extension base="tns:EntityObject">
- <s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Host" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="SessionType" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="LoginTime" type="s:dateTime" />
<s:element minOccurs="1" maxOccurs="1" name="LogoutTime" type="s:dateTime" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
And this is the code to traverse:
foreach (System.Xml.Schema.XmlSchemaComplexType item in xmlSchema.SchemaTypes.Values)
{
if (item != null)
{
System.Xml.Schema.XmlSchemaParticle particle = item.Particle;
System.Xml.Schema.XmlSchemaSequence sequence = particle as System.Xml.Schema.XmlSchemaSequence;
if (sequence != null)
{
foreach (System.Xml.Schema.XmlSchemaElement childElement in sequence.Items)
{
string name = childElement.Name;
string type = childElement.SchemaTypeName.Name;
Console.WriteLine(name + " " + type);
}
}
开发者_StackOverflow }
This gets me a little further, but not as far as getting the complexContent of the ComplexType. Produces the following output in the console:
Session Session
If anyone has a similar question, here is how I did it:
foreach (System.Xml.Schema.XmlSchemaComplexType item in xmlSchema.SchemaTypes.Values)
{
ComplexType cType = new ComplexType(item.Name);
System.Xml.Schema.XmlSchemaContentModel model = item.ContentModel;
System.Xml.Schema.XmlSchemaComplexContent complex = model as System.Xml.Schema.XmlSchemaComplexContent;
if (complex != null)
{
System.Xml.Schema.XmlSchemaComplexContentExtension extension = complex.Content as System.Xml.Schema.XmlSchemaComplexContentExtension;
System.Xml.Schema.XmlSchemaParticle particle = extension.Particle;
System.Xml.Schema.XmlSchemaSequence sequence = particle as System.Xml.Schema.XmlSchemaSequence;
if (sequence != null)
{
List<SimpleType> primitives = new List<SimpleType>();
foreach (System.Xml.Schema.XmlSchemaElement childElement in sequence.Items)
{
string name = childElement.Name;
string type = childElement.SchemaTypeName.Name;
cType.Primitives.Add(new SimpleType(name, type));
}
if (cType.Name == parameter.Type || "ArrayOf" + cType.Name == parameter.Type)
{
descriptions.Add(new ComplexParameter(cType, item.Name));
}
}
}
}
This looks pretty similar to what you you did WebServiceInfo It returns custom objects with the info. (if I am understanding your question and the blog well enough)
精彩评论