svcutil.exe for WCF problem

A

adacai

I'm now trying to use WCF for our SOA archecture, but I found the
svcutil generated proxy a bit confused.
Take the following code
[ServiceContract(Namespace = "http://TCM.Mars.ServiceContracts/
2007/03")]
public interface ICatalog
{
[OperationContract]
[ServiceKnownType(typeof(Widget))]
[ServiceKnownType(typeof(Machine))]
Hashtable GetItems();
}


[DataContract]
public class Widget
{
[DataMember]
public string Id;
[DataMember]
public string Catalog;
}

[DataContract()]
public class Machine : Widget
{
[DataMember]
public string Maker;
}

however when I use svcutil to generate a proxy for this interface, the
following code is generated
namespace WorkWise.Tcm.Service.Common.ServiceContracts
{
using System.Runtime.Serialization;



[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization",
"3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute()]

[System.Runtime.Serialization.KnownTypeAttribute(typeof(WorkWise.Tcm.Service.Common.ServiceContracts.Machine))]
public partial class Widget : object,
System.Runtime.Serialization.IExtensibleDataObject
{

private System.Runtime.Serialization.ExtensionDataObject
extensionDataField;

private string CatalogField;

private string IdField;

public System.Runtime.Serialization.ExtensionDataObject
ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}

[System.Runtime.Serialization.DataMemberAttribute()]
public string Catalog
{
get
{
return this.CatalogField;
}
set
{
this.CatalogField = value;
}
}

[System.Runtime.Serialization.DataMemberAttribute()]
public string Id
{
get
{
return this.IdField;
}
set
{
this.IdField = value;
}
}
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization",
"3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute()]
public partial class Machine :
WorkWise.Tcm.Service.Common.ServiceContracts.Widget
{

private string MakerField;

[System.Runtime.Serialization.DataMemberAttribute()]
public string Maker
{
get
{
return this.MakerField;
}
set
{
this.MakerField = value;
}
}
}
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
"3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://
TCM.Mars.ServiceContracts/2007/03", ConfigurationName="ICatalog")]
public interface ICatalog
{

[System.ServiceModel.OperationContractAttribute(Action="http://
TCM.Mars.ServiceContracts/2007/03/ICatalog/GetItems",
ReplyAction="http://TCM.Mars.ServiceContracts/2007/03/ICatalog/
GetItemsResponse")]
Dictionary<object,object> GetItems();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
"3.0.0.0")]
public interface ICatalogChannel : ICatalog,
System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
"3.0.0.0")]
public partial class CatalogClient :
System.ServiceModel.ClientBase<ICatalog>, ICatalog
{

public CatalogClient()
{
}

public CatalogClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}

public CatalogClient(string endpointConfigurationName, string
remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public CatalogClient(string endpointConfigurationName,
System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public CatalogClient(System.ServiceModel.Channels.Binding binding,
System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}

public Dictionary<object,object> GetItems()
{
return base.Channel.GetItems();
}
}


obviously, the ServiceKnownTypeAttribute I decorated on method
GetItems is missing in the generated proxy, thus the deserialization
at the clientside into Widget or Machine, fails. Anyone could tell me
what's wrong with my code or what's wrong with my usage of svcutil.exe
 
N

Nicholas Paldino [.NET/C# MVP]

adacai,

The ServiceKnownType attribute applies to the parameters passed in, not
the return value, so svcutil is doing the right thing here.

Rather, you should be returning a dictionary of your key type and of
Machine (as the value type). That should get you closer to what you want.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

adacai said:
I'm now trying to use WCF for our SOA archecture, but I found the
svcutil generated proxy a bit confused.
Take the following code
[ServiceContract(Namespace = "http://TCM.Mars.ServiceContracts/
2007/03")]
public interface ICatalog
{
[OperationContract]
[ServiceKnownType(typeof(Widget))]
[ServiceKnownType(typeof(Machine))]
Hashtable GetItems();
}


[DataContract]
public class Widget
{
[DataMember]
public string Id;
[DataMember]
public string Catalog;
}

[DataContract()]
public class Machine : Widget
{
[DataMember]
public string Maker;
}

however when I use svcutil to generate a proxy for this interface, the
following code is generated
namespace WorkWise.Tcm.Service.Common.ServiceContracts
{
using System.Runtime.Serialization;



[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization",
"3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute()]

[System.Runtime.Serialization.KnownTypeAttribute(typeof(WorkWise.Tcm.Service.Common.ServiceContracts.Machine))]
public partial class Widget : object,
System.Runtime.Serialization.IExtensibleDataObject
{

private System.Runtime.Serialization.ExtensionDataObject
extensionDataField;

private string CatalogField;

private string IdField;

public System.Runtime.Serialization.ExtensionDataObject
ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}

[System.Runtime.Serialization.DataMemberAttribute()]
public string Catalog
{
get
{
return this.CatalogField;
}
set
{
this.CatalogField = value;
}
}

[System.Runtime.Serialization.DataMemberAttribute()]
public string Id
{
get
{
return this.IdField;
}
set
{
this.IdField = value;
}
}
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization",
"3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute()]
public partial class Machine :
WorkWise.Tcm.Service.Common.ServiceContracts.Widget
{

private string MakerField;

[System.Runtime.Serialization.DataMemberAttribute()]
public string Maker
{
get
{
return this.MakerField;
}
set
{
this.MakerField = value;
}
}
}
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
"3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://
TCM.Mars.ServiceContracts/2007/03", ConfigurationName="ICatalog")]
public interface ICatalog
{

[System.ServiceModel.OperationContractAttribute(Action="http://
TCM.Mars.ServiceContracts/2007/03/ICatalog/GetItems",
ReplyAction="http://TCM.Mars.ServiceContracts/2007/03/ICatalog/
GetItemsResponse")]
Dictionary<object,object> GetItems();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
"3.0.0.0")]
public interface ICatalogChannel : ICatalog,
System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
"3.0.0.0")]
public partial class CatalogClient :
System.ServiceModel.ClientBase<ICatalog>, ICatalog
{

public CatalogClient()
{
}

public CatalogClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}

public CatalogClient(string endpointConfigurationName, string
remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public CatalogClient(string endpointConfigurationName,
System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public CatalogClient(System.ServiceModel.Channels.Binding binding,
System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}

public Dictionary<object,object> GetItems()
{
return base.Channel.GetItems();
}
}


obviously, the ServiceKnownTypeAttribute I decorated on method
GetItems is missing in the generated proxy, thus the deserialization
at the clientside into Widget or Machine, fails. Anyone could tell me
what's wrong with my code or what's wrong with my usage of svcutil.exe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top