【问题标题】:Can I use a Class object as a DataMember?我可以将 Class 对象用作 DataMember 吗?
【发布时间】:2016-06-07 04:50:25
【问题描述】:

这是需要序列化的类。

[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 类

[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(字符串 message, 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 接受器,Action dequeuedCallback,HttpPipeline 管道, AsyncCallback 回调,对象状态) System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor replyChannelAcceptor,Action dequeuedCallback,AsyncCallback 回调, 对象状态) System.ServiceModel.Channels.HttpChannelListener1.HttpContextReceivedAsyncResult1.ProcessHttpContextAsync() System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext 上下文,Action acceptorCallback,AsyncCallback 回调,对象 状态) 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; }
    }

请帮我解决这个问题。

【问题讨论】:

标签: c# wcf datacontractserializer


【解决方案1】:

您还需要将DataContract 添加到Results 类。

DataContractSerializer 是一个可选的序列化程序,这意味着它只会序列化您告诉序列化程序序列化的内容。由于您没有使用DataContract 属性标记Results 类,它不会被序列化。

所有 .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; }
    }

【讨论】:

  • 我对 Result 类进行了此更改,但错误仍然存​​在。错误是:内容类型application/soap+xml; charset=utf-8 被发送到需要 text/xml 的服务;字符集=utf-8。客户端和服务绑定可能不匹配。
  • 您需要确保ClientService 端使用相同 绑定。如果客户端使用BasicHttpBinding,则确保服务器也有BasicHttpBinding
  • 我已经添加了配置文件。你能检查一下吗?谢谢你。
  • 尝试在服务配置&lt;protocolMapping&gt; &lt;add binding="basicHttpsBinding" scheme="http" /&gt; &lt;/protocolMapping&gt;中将方案从https更改为http
  • 另外,您能否发布方法的代码以及您如何在客户端使用该服务。
【解决方案2】:

我解决这个问题如下。

[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()

感谢大家的支持

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    相关资源
    最近更新 更多