WCF десериализация теряет дочерние коллекции - PullRequest
4 голосов
/ 20 мая 2011

Я искал ответ на следующую проблему в течение нескольких дней, но пока безуспешно, любая помощь очень ценится.

Отказ от ответственности : WCF и EntityFrameworkдля меня это новые концепции, но .NET, c #, веб-сервисы, концепции реляционного сопоставления объектов, безусловно, не являются таковыми.

Я унаследовал приложение с клиентским приложением, используя службу WCF для извлечения и сохранения "Matter"«объект, который содержит отношение« 1-ко-многим »с объектами« CaseNotesLog ».

Клиент может успешно получать определенные объекты Matters с 0, 1 или несколькими дочерними объектами CaseNotesLog, он также может успешно сохранять обратно объекты Matters с добавленными,обновленные или удаленные объекты CaseNotesLog.

Пока все хорошо, однако, как представляется, существует набор Matters с дочерними объектами CaseNotesLog, которые могут быть успешно прочитаны, но не могут быть сохранены, даже если они не были изменены вообще.

По сути, это выглядит как процесс десериализации в WCF при сохранении объекта Matter.t теряет дочерние записи CaseNotesLog.

Чтобы уточнить:

  1. Чтение
    1. запись Matter имеет 1 дочернюю запись CaseNotesLog в базе данных,
    2. это успешно преобразуется в объект EntityFramework Matter с дочерним объектом CaseNotesLog на сервере
    3. , это успешно сериализуется / десериализуется через службу WCF и правильно заполняет объект Matter дочерним CaseNotesLog на стороне клиента.
  2. Сохранить
    1. объект Matter на стороне клиента с дочерним объектом CaseNotesLog "покидает" клиентское приложение.
    2. это сериализуется для передачи обратно службе WCF обратнона сервер.
    3. при просмотре журнала трассировки эта сериализация содержит дочерний CaseNotesLog.
    4. этот объект десериализуется на стороне сервера
    5. путем добавления операторов трассировки в код SetterВ объекте Matter entityframework я могу наблюдать, как дети CaseNotesLog правильно помещаются в паренt Matter.
    6. НО, как только функция Getter вызывается, коллекция становится пустой

Это так, как если бы коллекция RelationshipManager быласбрасывается куда-то еще.

Конечным результатом является то, что объект Matter с дочерним объектом CaseNotesLog оставляет мой код на стороне клиента, но, несмотря на то, что к тому времени, когда я проверяю его, похоже, он корректно сериализуется / десериализуетсясостояние объекта на стороне сервера, к которому ушли дочерние записи.

Чтобы проверить, я добавил некоторый код в класс entityframework для независимого подсчета размера дочерней коллекции.Он устанавливается на 1 во время операции Set, когда установлена ​​коллекция CaseNotesLog, и остается на 1, когда коллекция CaseNotesLog извлекается во время Get, даже если коллекция была очищена.

Чтобы добавить к путанице* это не относится ко всем Вопросам, некоторые, кажется, работают, другие - нет * Это, кажется, не относится ко всем типам дочерних объектов, другие наборы, кажется, работают.

Служба 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;
           }
       }
   }
   ...
}

Материя - это сгенерированный класс 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");
        }
    }
}

Это фрагмент сообщения Soap, полученного службой Wcf, показывающий наличие дочерней записи 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>                  

1 Ответ

0 голосов
/ 29 июня 2011

Можно ли пометить этот атрибут для контракта данных: System.Runtime.Serialization.DataContractAttribute (IsReference = true)]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...