c#之我可以将 Class 对象用作 DataMember 吗

yjmyzz 阅读:19 2024-10-25 08:56:14 评论:0

这是需要序列化的类。

[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(String message, HttpStatusCode statusCode, String statusDescription) System.ServiceModel.Channels.HttpInput.ValidateContentType() System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.BeginParse() System.ServiceModel.Channels.HttpInput.BeginParseIncomingMessage(HttpRequestMessage httpRequestMessage, AsyncCallback callback, Object state) System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginParseIncomingMessage(AsyncCallback asynCallback, Object state) System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult..ctor(ReplyChannelAcceptor acceptor, Action dequeuedCallback, HttpPipeline pipeline, AsyncCallback callback, Object state) System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor replyChannelAcceptor, Action dequeuedCallback, AsyncCallback callback, Object state) System.ServiceModel.Channels.HttpChannelListener1.HttpContextReceivedAsyncResult1.ProcessHttpContextAsync() System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext context, Action acceptorCallback, AsyncCallback callback, Object state) System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result) System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest() System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest() System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state) System.ServiceModel.AspNetPartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state) System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state) System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, 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() 
        { 
 
        } 
    } 

Action 类

 [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; } 
    } 

请帮我解决这个问题。

请您参考如下方法:

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

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

所有 .NET Framework 基本类型,例如 Byte、SByte、Int16、Int32、Int64、UInt16、UInt32、UInt64、Single、Double、Boolean、Char、Decimal、Object 和 String 都可以在没有其他准备的情况下被序列化,并被视为具有默认数据契约(Contract)。

有关 DataContractSerializer 支持的类型的更多信息,请阅读 msdn

[DataContract] 
public class Results 
    { 
        [DataMember] 
        public string categoryName { get; set; } 
 
        [DataMember] 
        public List<Object> results { get; set; } 
    } 


标签:C#
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号