C#调用具有用户定义数据类型作为参数的WCF服务函数

时间:2015-05-22 05:02:11

标签: c# web-services wcf soap

我想从我的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;
        }
    }
}

0 个答案:

没有答案