c# - WCF 反序列化丢失子集合

标签 c# .net wcf

几天来我一直在寻找以下问题的答案,到目前为止没有任何运气,非常感谢任何帮助。

免责声明:WCF 和 EntityFramework 对我来说是新概念,但 .NET、c#、Web 服务、对象关系映射概念肯定不是。

我继承了一个带有客户端应用程序的应用程序,该应用程序使用 WCF 服务来检索和保存“问题”对象,该对象包含与“CaseNotesLog”对象的一对多关系。

Client 可以成功检索具有 0 个、1 个或多个子 CaseNotesLog 对象的某些 Matters,也可以成功保存具有添加、更新或删除的 CaseNotesLog 对象的 Matters。

到目前为止还不错,但是似乎有一组 Matters,其中包含可以成功读取但无法保存的子 CaseNotesLog 对象,即使它们根本没有被更改也是如此。

从本质上讲,它看起来像是在保存 Matter 对象时 WCF 上的反序列化过程丢失了子 CaseNotesLog 条目。

澄清一下:

  1. 阅读
    1. 一个 Matter 记录在数据库中有 1 个 CaseNotesLog 子记录,
    2. 这已成功转换为 EntityFramework Matter 对象,在服务器上有一个子 CaseNotesLog 对象
    3. 这已在 WCF 服务中成功序列化/反序列化,并在客户端使用子 CaseNotesLog 正确地填充了一个 Matter 对象。
  2. 保存
    1. 带有子 CaseNotesLog 对象的客户端 Matter 对象“离开”客户端应用程序。
    2. 这被序列化以通过 WCF 服务传回服务器。
    3. 查看跟踪记录此序列化包含子 CaseNotesLog。
    4. 此对象在服务器端被反序列化
    5. 通过将跟踪语句添加到 entityframework Matter 对象的 Setter 代码中,我可以观察到 CaseNotesLog 子项被正确放置到父 Matter 中。
    6. 但是一旦调用 Getter 功能,集合就为空

就好像 RelationshipManager 集合正在其他地方被重置。

最终结果是,带有子 CaseNotesLog 对象的 Matter 对象将我的代码留在了客户端,但是当我检查服务器上对象的状态时,它看起来正在正确地序列化/反序列化-side 子记录已经消失。

为了检查,我向 entityframework 类添加了一些代码,以独立计算子集合的大小。当设置 CaseNotesLog 集合时,在 Set 操作期间它被设置为 1,并且在 Get 期间检索 CaseNotesLog 集合时它保持为 1,即使该集合已被清空。

增加困惑 *这并不适用于所有事项,有些似乎有效,有些则无效 *这似乎并不适用于其他集合似乎有效的所有类型的子对象。

除其他方法外,WCF 服务还实现了以下内容:

[ServiceContract]
public interface IMattersService
{
    ...
    [OperationContract]
    Matter ReadMatter(int matterID);
    ...
    [OperationContract]
    void SaveMatter(Matter matter);
    ...
    }
}

具体实现如下:

public class MattersService : IMattersService
{

   ...
   public Matter ReadMatter(int matterID)
   {
       using (var repo = new MatterRepository())
       {
           try
           {
               return repo.ReadMatter(matterID);
           }
           catch (Exception ex)
           {
               Logger.Write(ex, "Error", 0);
               throw;
           }
       }
   }
   ...
   public void SaveMatter(Matter matter)
   {
       Trace.WriteLine(matter.CaseNotesLogs.Count);
       using (var repo = new MatterRepository())
       {
           try
           {
               repo.SaveMatter(matter);
           }
           catch (Exception ex)
           {
               Logger.Write(ex, "Error", 0);
               throw;
           }
       }
   }
   ...
}

Matter 是 EntityFramework 生成的类:

/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmEntityTypeAttribute(NamespaceName="EDDSolutionsLtd.Services.Data", Name="Matter")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Matter : EntityObject
{
    ...
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [XmlIgnoreAttribute()]
    [SoapIgnoreAttribute()]
    [DataMemberAttribute()]
    [EdmRelationshipNavigationPropertyAttribute("EDDSolutionsLtd.Services.Data", "MatterCaseNotesLog", "CaseNotesLog")]
    public EntityCollection<CaseNotesLog> CaseNotesLogs
    {
        get
        {
            return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog");
        }
        set
        {
            if ((value != null))
            {
                ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog", value);
            }
        }
    }
    ...
}

我添加了一些日志记录的损坏版本:

public int CheckCaseNotesLogsCount { get; set; }
public EntityCollection<CaseNotesLog> CheckCaseNotesLogs { get; set; }
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[XmlIgnoreAttribute()]
[SoapIgnoreAttribute()]
[DataMemberAttribute()]
[EdmRelationshipNavigationPropertyAttribute("EDDSolutionsLtd.Services.Data", "MatterCaseNotesLog", "CaseNotesLog")]
public EntityCollection<CaseNotesLog> CaseNotesLogs
{
    get
    {
        if (CheckCaseNotesLogs != null)
        {
            Trace.WriteLine("GET ACTUAL CheckCaseNotesLogs[" + CheckCaseNotesLogs.Count + "]");
        }
        Trace.WriteLine("GET ACTUAL CheckCaseNotesLogsCount[" + CheckCaseNotesLogsCount + "]");
        StackTrace st = new StackTrace();
        int i = ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog").Count;
        Trace.WriteLine("GET ACTUAL value[" + i + "]");
        Trace.WriteLine(st.ToString());
        return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog");
    }
    set
    {
        if ((value != null))
        {
            CheckCaseNotesLogs = value;
            CheckCaseNotesLogsCount = value.Count;
            Trace.WriteLine("SET ACTUAL value[" + value.Count + "]");
            ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<CaseNotesLog>("EDDSolutionsLtd.Services.Data.MatterCaseNotesLog", "CaseNotesLog", value);
            Trace.WriteLine("SET ACTUAL Property value[" + this.CaseNotesLogs.Count + "]");
        }
        else
        {
           Trace.WriteLine("SET NULL Value");
        }
    }
}

这是 Wcf 服务收到的 Soap 消息的片段,显示子 CaseNotesLog 记录存在。

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">

  <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">

    <EventID>0</EventID>
    <Type>3</Type>
    <SubType Name="Information">0</SubType>
    <Level>8</Level>
    <TimeCreated SystemTime="2011-05-19T22:49:34.7968750Z" />
    <Source Name="System.ServiceModel.MessageLogging" />
    <Correlation ActivityID="{fa25d214-04e9-4b16-8ae8-3de7b9a12bc6}" />
    <Execution ProcessName="WebDev.WebServer40" ProcessID="2332" ThreadID="13" />
    <Channel />
    <Computer>EDD-MERCURY</Computer>
  </System>
  <ApplicationData>
    <TraceData>
      <DataItem>
        <MessageLogTraceRecord Time="2011-05-19T23:49:34.7812500+01:00"
        Source="ServiceLevelReceiveRequest"
        Type="System.ServiceModel.Channels.BufferedMessage"
            xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">

          <HttpRequest>
            <Method>POST</Method>
            <QueryString></QueryString>
            <WebHeaders>
              <Content-Length>142631</Content-Length>
              <Content-Type>application/soap+xml;
              charset=utf-8</Content-Type>
              <Expect>100-continue</Expect>
              <Host>localhost:58080</Host>
              <VsDebuggerCausalityData>
              uIDPo7kHl/h9zQNAkghvTvB5/u8AAAAAuoDOged1MUm+UmudC0H6u3k/74R6jUpIn/o2sS4KNxYACQAA</VsDebuggerCausalityData>
            </WebHeaders>
          </HttpRequest>
          <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
          xmlns:a="http://www.w3.org/2005/08/addressing">
            <s:Header>
              <a:Action s:mustUnderstand="1">
              http://tempuri.org/IMattersService/SaveMatter</a:Action>
              <a:MessageID>
              urn:uuid:f1d751a7-1012-4268-b7da-87a12cf6d14f</a:MessageID>
              <ActivityId CorrelationId="4f53460f-8880-4b6e-aa66-557fa90d4ae3"
              xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">
              fa25d214-04e9-4b16-8ae8-3de7b9a12bc6</ActivityId>
              <a:ReplyTo>
                <a:Address>
                http://www.w3.org/2005/08/addressing/anonymous</a:Address>
              </a:ReplyTo>
              <a:To s:mustUnderstand="1">
              http://localhost:58080/MattersService.svc</a:To>
            </s:Header>
            <s:Body>
              <SaveMatter xmlns="http://tempuri.org/">
                <matter z:Id="i1"
                xmlns:b="http://schemas.datacontract.org/2004/07/EDDSolutionsLtd.Services.Data"
                xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">

                  <EntityKey z:Id="i2"
                      xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"
                  xmlns:c="http://schemas.datacontract.org/2004/07/System.Data">

                    <c:EntityContainerName>
                    EDDSolutionsLtdEntities</c:EntityContainerName>
                    <c:EntityKeyValues>
                      <c:EntityKeyMember>
                        <c:Key>ID</c:Key>
                        <c:Value i:type="d:int"
                        xmlns:d="http://www.w3.org/2001/XMLSchema">
                        180</c:Value>
                      </c:EntityKeyMember>
                    </c:EntityKeyValues>
                    <c:EntitySetName>Matters</c:EntitySetName>
                  </EntityKey>
                  <b:AllRecordsReceivedDate i:nil="true">
                  </b:AllRecordsReceivedDate>
                  <b:BeginClaimDate i:nil="true">
                  </b:BeginClaimDate>

                  ...

                  <b:CaseEmailLogs></b:CaseEmailLogs>
                  <b:CaseFileLogs></b:CaseFileLogs>
                  <b:CaseNotesLogs>
                    <b:CaseNotesLog z:Id="i3">
                      <EntityKey z:Id="i4"
                          xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses"
                      xmlns:c="http://schemas.datacontract.org/2004/07/System.Data">

                        <c:EntityContainerName>
                        EDDSolutionsLtdEntities</c:EntityContainerName>
                        <c:EntityKeyValues>
                          <c:EntityKeyMember>
                            <c:Key>ID</c:Key>
                            <c:Value i:type="d:int"
                            xmlns:d="http://www.w3.org/2001/XMLSchema">
                            281</c:Value>
                          </c:EntityKeyMember>
                        </c:EntityKeyValues>
                        <c:EntitySetName>
                        CaseNotesLogs</c:EntitySetName>
                      </EntityKey>
                      <b:ActivityDate>
                      2011-05-18T00:00:00</b:ActivityDate>
                      <b:Body i:nil="true"></b:Body>
                      <b:Comment>3</b:Comment>
                      <b:ContactID>608</b:ContactID>
                      <b:CreatedBy>mminns</b:CreatedBy>
                      <b:CreatedOn>
                      2011-05-19T15:25:03.923</b:CreatedOn>
                      <b:ID>281</b:ID>
                      <b:MatterId>180</b:MatterId>
                      <b:ModifiedBy>mminns</b:ModifiedBy>
                      <b:ModifiedOn>
                      2011-05-19T15:25:03.923</b:ModifiedOn>
                      <b:OriginalContactID>0</b:OriginalContactID>
                      <b:Outcome>Unknown</b:Outcome>
                      <b:Subject>1</b:Subject>
                    </b:CaseNotesLog>
                  </b:CaseNotesLogs>

                  ...

                </matter>
              </SaveMatter>
            </s:Body>
          </s:Envelope>
        </MessageLogTraceRecord>
      </DataItem>
    </TraceData>
  </ApplicationData>
</E2ETraceEvent>                  

最佳答案

你能为数据协定标记这个属性吗:System.Runtime.Serialization.DataContractAttribute(IsReference=true)]

关于c# - WCF 反序列化丢失子集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6070252/

相关文章:

c# - 如何使用正则表达式获取特定段?

wcf - 没有兼容的传输管理器错误

.net - 禁止使用 TLS session 票证

c# - Transform.Lookat 问题(C# Unity3D)

c# - C# 中的内联 'try' 语句可能吗?

.net - 禁用数据 GridView 中的行选择

c# - Databind 无法通过 IBindableComponent 进行转换

c# - 为什么.net 对字符串使用 UTF16 编码,而保存文件却默认使用 UTF-8?

c# - 如何在 WCF 中为客户端配置 net.tcp 绑定(bind)

c# - dailymotion 和 blip.tv 的视频 Url 解析器