我可以将Class对象用作DataMember吗?

时间:2016-02-24 18:16:35

标签: c# wcf datacontractserializer

这是需要序列化的类。

[DataContract]
    public class Fullresponse
    {
        [DataMember(Order=0)]
        public string success { get; set; }
        [DataMember]
        public string participants { get; set; }
        [DataMember]
        public string term { get; set; }
        [DataMember]
        public categoryCollection categories { get; set; }

        [DataMember]
        public string total { get; set; }



    }

这是categoryCollection Class

[DataContract]
    public class categoryCollection
    {
        [DataMember]
        public Results online { get; set; }
        [DataMember]
        public Results offline { get; set; }
    }

这是结果类

public class Results
    {
        public string categoryName { get; set; }


        public List<Node> results { get; set; }
    }

我想从WCF服务到我的客户端应用程序获取Fullresponse类对象。 我怎样才能做到这一点。从这段代码中可以看出错误。当我从Fullresponse类中删除categoryCollection对象时,它可以正常工作。

这是我的服务web.config

<?xml version="1.0"?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
      switchValue="Information, ActivityTracing"
      propagateActivity="true">
        <listeners>
          <add name="traceListener"
          type="System.Diagnostics.XmlWriterTraceListener"
          initializeData= "c:\log\TracesTest1.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

这是我的客户端app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IService1" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:23894/Service1.svc" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
                name="BasicHttpBinding_IService1" />
        </client>
    </system.serviceModel>
</configuration>

堆栈错误跟踪..

  

System.ServiceModel.Channels.HttpInput.ThrowHttpProtocolException(字符串   消息,HttpStatusCode statusCode,String statusDescription)   System.ServiceModel.Channels.HttpInput.ValidateContentType()   System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.BeginParse()   System.ServiceModel.Channels.HttpInput.BeginParseIncomingMessage(HttpRequestMessage   httpRequestMessage,AsyncCallback回调,对象状态)   System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginParseIncomingMessage(AsyncCallback的   asynCallback,对象状态)   System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult..ctor(ReplyChannelAcceptor   accept,Action dequeuedCallback,HttpPipeline管道,   AsyncCallback回调,对象状态)   System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor   replyChannelAcceptor,Action dequeuedCallback,AsyncCallback回调,   对象状态)   System.ServiceModel.Channels.HttpChannelListener 1.HttpContextReceivedAsyncResult 1.ProcessHttpContextAsync()   System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext   context,Action acceptorCallback,AsyncCallback回调,Object   州)   System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult   结果)   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(对象   州)   System.ServiceModel.AspNetPartialTrustHelpers.PartialTrustInvoke(ContextCallback   回调,对象状态)   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(对象   州)   System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32的   errorCode,UInt32 numBytes,NativeOverlapped * nativeOverlapped)   System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32的   错误,UInt32 bytesRead,NativeOverlapped * nativeOverlapped)   System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32的   errorCode,UInt32 numBytes,NativeOverlapped * pOVERLAP)

客户端代码

private void button1_Click(object sender, EventArgs e)
        {
            Service1Client clirnt = new Service1Client();
            Fullresponse C = new Fullresponse();
            C = clirnt.GetDataUsingDataContractnew("","");


        }

IService.cs

[ServiceContract]
    public interface IService1
    {

        [OperationContract]
        string GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(int id);

        [OperationContract]
        Fullresponse GetDataUsingDataContractnew(string id, string skey);
        // TODO: Add your service operations here
    }

Service1.svc.cs

  public class Service1 : IService1
     {
         public string GetData(int value)
         {
             return string.Format("You entered: {0}", value);
         }

         public CompositeType GetDataUsingDataContract(int id)
         {
             CompositeType ct = new CompositeType();
             return ct;
         }

         public Fullresponse GetDataUsingDataContractnew(string id,string skey)
         {
             Fullresponse fr = new Fullresponse();
             SearchContacts sr = new SearchContacts();
             fr = sr.GetJson(id, skey);
             return fr;
         }
     }

getJson method

     public Fullresponse GetJson(string id, string skey)
            {
                List<Node> on = new List<Node>();
                List<Node> off = new List<Node>();
                Results Online = new Results();
                Results Offline = new Results();

                on.Add(new Contact("on1", "url1", "des1", "aaa"));
                off.Add(new Contact("off2", "url2", "des2", "bbb"));
                Online.categoryName = "Online";
                Online.results = on;
                Offline.categoryName = "Offline";
                Offline.results = off;
                categoryCollection categoryCollection = new categoryCollection();
                categoryCollection.online = Online;
                categoryCollection.offline = Offline;

                Fullresponse searchCon = new Fullresponse();
                searchCon.success = "true";
                searchCon.term = "a";
                searchCon.categories = categoryCollection;
                searchCon.total = "1";

                return searchCon;

            }

节点类

 [DataContract]
    public abstract class Node
    {
        [DataMember]
        public string title { get; set; }
        [DataMember]
        public string name { get; set; }
        [DataMember]
        public string url { get; set; }

        [DataMember]
        public string description { get; set; }

       [DataMember]
        public List<Action> actions { get; set; }
        public virtual void AddComment()
        {

        }
        public virtual void AddContact()
        {

        }
    }

行动类

 [DataContract]
    public class Action
    {
        public Action() { }
        public Action(string icon, string url)
        {
            this.icon = icon;
            this.url = url;
        }
        [DataMember]
        public string icon { get; set; }
        [DataMember]
        public string url { get; set; }
    }

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:5)

您还需要将DataContract添加到Results课程。

DataContractSerializer是一个选择性序列化程序,意思是它只序列化你告诉序列化程序序列化的内容。由于您没有使用Results属性标记DataContract类,因此不会将其序列化。

所有.NET Framework原始类型(例如Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64, Single, Double, Boolean, Char, Decimal, Object, and String)都可以序列化而无需其他准备工作,并被视为具有默认数据协定。

有关DataContractSerializer支持的类型的详细信息,请阅读msdn

[DataContract]
public class Results
    {
        [DataMember]
        public string categoryName { get; set; }

        [DataMember]
        public List<Object> results { get; set; }
    }

答案 1 :(得分:0)

我解决了这个问题如下。

[KnownType(typeof(Contact)), KnownType(typeof(Apps)), KnownType(typeof(Person))]
    [DataContract]
    public abstract class Node
    {
        [DataMember]
        public string title { get; set; }
        [DataMember]
        public string name { get; set; }
        [DataMember]
        public string url { get; set; }

        [DataMember]
        public string description { get; set; }

        [DataMember]
        public List<Action> actions { get; set; }
        public virtual void AddComment()
        {

        }
        public virtual void AddContact()
        {

        }
    }

添加KnownType()

thnaks All for the support