0
votes
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
using MR.Storage.CommonClasses;

namespace Storage.Contract
{

[DataContract]
public class SaveMyData
{

    [DataMember]
    public MR.Storage.CommonClasses.MyData MyData{ get; set; }
}

Above is my data contract class for my wcf service. MyData is a poco class in an external assembly that is decorated with [DataContract] and [DataMember] attributes. When I add a service reference to it in a solution I get "Metadata contains a reference that cannot be resolved". I also tried adding it in wcf test client and it throws error ...\Test Client Projects\14.0\729f94f0-f564-4439-90f9-1c1553821666\Client.cs(42,26) : error CS0234: The type or namespace name 'MyData' does not exist in the namespace 'MR.Storage.CommonClasses' (are you missing an assembly reference?) I opened this file and the only using statement is using System.Runtime.Serialization; Am what I am doing not possible? I saw some other suggestions about using a surrogate, but MyData has a ton of fields so would really like to find a solution that doesnt involve mapping each property

2
Did you add a reference to the assembly that holds the MyData type? A normal reference that is, not a service reference.rene
Yes, my datacontract has using MR.Storage.CommonClasses; which refereneces the external assembly where MyData is defineduser1152145
The using statement does nothing to link that assembly. In the solution explorer, under your project node, in the subnode references, is there an entry for the assembly with the MyData class?rene
Yes there is an entryuser1152145

2 Answers

1
votes

Did you edit the WCF service reference properties? You are able to allude to external assemblies that way. To be honest, I've found that approach to be a pain in the butt (version hell issues), but YMMV.

Wcf Service Properties

0
votes

If you do not necessarily use DataContractSerializer, you could consider using XmlSerializer to serialize your data , it needn't use DataContract and DataMember attribute.

namespace ServiceInterface.Models
{
public class MyData
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

public  class MyDataFather
{
    public MyData MyData { get; set; }
}
}

My servicecontract and service. Please don't forget to add XmlSerializerFormat attribute to your service contract, it tells wcf to use XmlSerializer

[ServiceContract]
[XmlSerializerFormat]
public interface ICotractWithoutAttribute
{
    [OperationContract]
MyDataFather GetData(MyDataFather myDataFather);
}

public class CotractWithoutAttribute : ICotractWithoutAttribute
{
    public MyDataFather GetData(MyDataFather myDataFather)
    {
        return myDataFather;
    }
}

The result.

enter image description here

My client.

using (ChannelFactory<ICotractWithoutAttribute> factory = new ChannelFactory<ICotractWithoutAttribute>("without"))
        {
            ICotractWithoutAttribute cotractWithoutAttribute = factory.CreateChannel();
            ServiceInterface.Models.MyDataFather myDataFather = cotractWithoutAttribute.GetData(new ServiceInterface.Models.MyDataFather { MyData = new ServiceInterface.Models.MyData { Name = "MICK", Age = 18, Id = 1 } });
        }

For more information about XmlSerializer, you could refer to https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-the-xmlserializer-class

If you must use DataContractSerializer , I think you should define a class with similar structure with the external class , add DataContarct and DataMember to the class and copy the data of your external class to your own class in your service.

https://social.msdn.microsoft.com/Forums/vstudio/en-US/51b9d122-7345-44c7-8cd8-eb0ccdbffabf/can-i-use-external-assembly-class-in-a-wcf-without-using-poco?forum=wcf