我想从我的c#客户端调用一个wcf服务函数,该服务位于远程站点。所以需要通过动态链接服务来调用该函数。
在调用函数并传递所需参数时,它会抛出一个
的异常“类型'TMsgInParam'的对象无法转换 输入'omni.infrasofttech.com.TMsgInParam'“
所以我需要知道如何将复杂类型参数传递给该函数。
现在这里是我必须连接的服务的wsdl文件数据:
<?xml version="1.0" encoding="utf-8" ?>
<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://omni.infrasofttech.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://omni.infrasofttech.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://omni.infrasofttech.com/">
<s:element name="Invoke">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="aToken" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="aSerName" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="aMethod" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="MsgInParam" type="tns:TMsgInParam" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="TMsgInParam">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="Field1" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Field2" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Field3" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Field4" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Field5" nillable="true" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="InvokeResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="InvokeResult" type="tns:TMsgOutParam" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="TMsgOutParam">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="Field1" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Field2" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Field3" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Field4" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Field5" nillable="true" type="s:string" />
</s:sequence>
</s:complexType>
</s:schema>
</wsdl:types>
<wsdl:message name="InvokeSoapIn">
<wsdl:part name="parameters" element="tns:Invoke" />
</wsdl:message>
<wsdl:message name="InvokeSoapOut">
<wsdl:part name="parameters" element="tns:InvokeResponse" />
</wsdl:message>
<wsdl:portType name="TOmniServiceSoap">
<wsdl:operation name="Invoke">
<wsdl:input message="tns:InvokeSoapIn" />
<wsdl:output message="tns:InvokeSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TOmniServiceSoap" type="tns:TOmniServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Invoke">
<soap:operation soapAction="http://omni.infrasofttech.com/Invoke" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="TOmniServiceSoap12" type="tns:TOmniServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Invoke">
<soap12:operation soapAction="http://omni.infrasofttech.com/Invoke" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TOmniService">
<wsdl:port name="TOmniServiceSoap" binding="tns:TOmniServiceSoap">
<soap:address location="http://192.168.100.108/PassOmni30/OmniService.asmx" />
</wsdl:port>
<wsdl:port name="TOmniServiceSoap12" binding="tns:TOmniServiceSoap12">
<soap12:address location="http://192.168.100.108/PassOmni30/OmniService.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
现在我通过以下代码调用此服务调用函数
Uri mexAddress = new Uri("http://192.168.100.108:8080/PassOmni30/OmniService.asmx?wsdl");
// For MEX endpoints use a MEX address and a
// mexMode of .MetadataExchange
MetadataExchangeClientMode mexMode = MetadataExchangeClientMode.HttpGet;
string contractName = "TOmniServiceSoap";
string operationName = "Invoke";
object[] operationParameters = new object[4];
TMsgInParam MsgInParam = new TMsgInParam();
MsgInParam.Field1 = "Name";
MsgInParam.Field2 = "Age";
MsgInParam.Field3 = "Address";
MsgInParam.Field4 = "DOB";
MsgInParam.Field5 = "Contact";
//add parameters
operationParameters[0] = "1";
operationParameters[1] = "1";
operationParameters[2] = 82;
operationParameters[3] = MsgInParam;
// Get the metadata file from the service.
MetadataExchangeClient mexClient = new MetadataExchangeClient(mexAddress, mexMode);
mexClient.ResolveMetadataReferences = true;
MetadataSet metaSet = mexClient.GetMetadata();
// Import all contracts and endpoints
WsdlImporter importer = new WsdlImporter(metaSet);
Collection<ContractDescription> contracts = importer.ImportAllContracts();
ServiceEndpointCollection allEndpoints = importer.ImportAllEndpoints();
// Generate type information for each contract
ServiceContractGenerator generator = new ServiceContractGenerator();
var endpointsForContracts = new Dictionary<string, IEnumerable<ServiceEndpoint>>();
foreach (ContractDescription contract in contracts)
{
generator.GenerateServiceContractType(contract);
// Keep a list of each contract's endpoints
endpointsForContracts[contract.Name] = allEndpoints.Where(
se => se.Contract.Name == contract.Name).ToList();
}
if (generator.Errors.Count != 0)
throw new Exception("There were errors during code compilation.");
// Generate a code file for the contracts
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("C#");
// Compile the code file to an in-memory assembly
// Don't forget to add all WCF-related assemblies as references
CompilerParameters compilerParameters = new CompilerParameters(
new string[] {
"System.dll", "System.ServiceModel.dll",
"System.Runtime.Serialization.dll" });
compilerParameters.GenerateInMemory = true;
CompilerResults results = codeDomProvider.CompileAssemblyFromDom(compilerParameters, generator.TargetCompileUnit);
if (results.Errors.Count > 0)
{
throw new Exception("There were errors during generated code compilation");
}
else
{
// Find the proxy type that was generated for the specified contract
// (identified by a class that implements
// the contract and ICommunicationbject)
Type clientProxyType = results.CompiledAssembly.GetTypes().FirstOrDefault(
t => t.IsClass &&
t.GetInterface(contractName) != null &&
t.GetInterface(typeof(ICommunicationObject).Name) != null);
// Get the first service endpoint for the contract
ServiceEndpoint se = endpointsForContracts[contractName].First();
// Create an instance of the proxy
// Pass the endpoint's binding and address as parameters
// to the ctor
object instance = results.CompiledAssembly.CreateInstance(
clientProxyType.Name,
false,
System.Reflection.BindingFlags.CreateInstance,
null,
new object[] { se.Binding, se.Address },
CultureInfo.CurrentCulture, null);
// Get the operation's method, invoke it, and get the return value
object retVal = instance.GetType().GetMethod(operationName).Invoke(instance, operationParameters);
MessageBox.Show("Login reply received- " + retVal.ToString());
}
我给出的那些复杂数据类型的定义是全局范围
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://omni.infrasofttech.com/")]
public partial class TMsgInParam {
private string field1Field;
private string field2Field;
private string field3Field;
private string field4Field;
private string field5Field;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field1 {
get {
return this.field1Field;
}
set {
this.field1Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field2 {
get {
return this.field2Field;
}
set {
this.field2Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field3 {
get {
return this.field3Field;
}
set {
this.field3Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field4 {
get {
return this.field4Field;
}
set {
this.field4Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field5 {
get {
return this.field5Field;
}
set {
this.field5Field = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://omni.infrasofttech.com/")]
public partial class TMsgOutParam {
private string field1Field;
private string field2Field;
private string field3Field;
private string field4Field;
private string field5Field;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field1 {
get {
return this.field1Field;
}
set {
this.field1Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field2 {
get {
return this.field2Field;
}
set {
this.field2Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field3 {
get {
return this.field3Field;
}
set {
this.field3Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field4 {
get {
return this.field4Field;
}
set {
this.field4Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Field5 {
get {
return this.field5Field;
}
set {
this.field5Field = value;
}
}
}