I am tryin to consume wdsl with a mex client. To compile it an use it without references. But i am getting compiler errors regarding "CS0246: The type or namespace name 'schema' could not be found".
I use a mexclient to import the contract
MetadataExchangeClient mexClient = new MetadataExchangeClient(binding);
mexClient.ResolveMetadataReferences = true;
mexClient.MaximumResolvedReferences = 1000;
var metaSet = mexClient.GetMetadata(mexAddress, mexMode);
WsdlImporter importer = new WsdlImporter(metaSet);
result.ContractDescriptions = importer.ImportAllContracts();
result.AllEndpoints = importer.ImportAllEndpoints();
then i generate and compile it.
CodeCompileUnit unit = (CodeCompileUnit)importer.State[typeof(CodeCompileUnit)];
ServiceContractGenerator generator = new ServiceContractGenerator(unit);
foreach (ContractDescription contract in result.ContractDescriptions)
{
generator.GenerateServiceContractType(contract);
}
// Generate a code file for the contracts.
CodeGeneratorOptions codeGeneratorOptions = new CodeGeneratorOptions();
codeGeneratorOptions.BracingStyle = "C";
// Create Compiler instance of a specified language.
CompilerResults results;
using (CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("CSharp"))
{
CompilerParameters compilerParameters = new CompilerParameters(new string[] {
"System.dll",
"System.Data.dll",
"System.ServiceModel.dll",
"System.Runtime.Serialization.dll",
"System.Xml.dll",
"System.Xml.Linq.dll",
"System.Xml.Serialization.dll" });
compilerParameters.GenerateInMemory = true;
compilerParameters.GenerateExecutable = false;
compilerParameters.WarningLevel = 1;
compilerParameters.TempFiles = new TempFileCollection("Compile", true);
results = codeDomProvider.CompileAssemblyFromDom(compilerParameters, generator.TargetCompileUnit);
}
This result in error CS0246: The type or namespace name 'schema' could not be found (are you missing a using directive or an assembly reference?)
When i look att the generated code i can se this unkown type
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("BfusTester", "1.0.0.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.logica.com/BusinessForUtilities/2012/LoggerService")]
public partial class TestDS {
private schema schemaField;
private System.Xml.XmlElement anyField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace="http://www.w3.org/2001/XMLSchema", Order=0)]
public schema schema {
get {
return this.schemaField;
}
set {
this.schemaField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAnyElementAttribute(Order=1)]
public System.Xml.XmlElement Any {
get {
return this.anyField;
}
set {
this.anyField = value;
}
}
}
Where the line "private schema schemaField;" contains an unknown type. The method looks like this in the implementation
In interface
[OperationContract]
DataSet Test(DataSet ds);
And in service
public DataSet Test(DataSet ds)
{
return new DataSet();
}
It is just standard System.Data.DataSet. The interface is sadly not mine to edit.
I´m trying to tweak some options or referenced assembly on the ServiceContractGenerator and/or CodeDomProvider but without luck. It seems to me that it´s some kind of xml serialization issue. Hope someone can give me som tips!
So a few days later!
I can see that the method with DataSet that causes the issue in CodeDom generation uses "literal" types.
<wsdl:operation name="Test2">
<soap12:operation soapAction="http://www.logica.com/BusinessForUtilities/2012/LoggerService/ILoggerService/Test2" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
What i have read this tells the "ServiceContractGenerator" to look for types in a literal way. So if it´s wrong, i possibly need to tell the WsdlImporter or ServiceContractGenerator where to look for the DataSet type. But i don´t know how!