Возврат пользовательского класса в WCF - PullRequest
2 голосов
/ 07 июня 2011

Я создал службу WCF, которая возвращает пользовательский объект с именем XmlElementTreeNode.Вот как выглядит объект:

[DataContract]
public class XmlElementTreeNode
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public List<string> Attributes { get; set; }

    [DataMember]
    public List<XmlElementTreeNode> Children { get; set; }

    public XmlElementTreeNode() { }
}

Я могу успешно создать иерархию этих узлов с помощью этого метода:

[OperationContract]
public XmlElementTreeNode GetTreeView(string initialSchemaUri)
{
    Uri uri = new Uri(initialSchemaUri, UriKind.Absolute);
    XPathSorter sorter = new XPathSorter(uri);
    XmlElementTreeNode theNode = sorter.rootTreeNode;
    return theNode;
}

Но я получаю ошибку:

CommunicationException was unhandled by user code
The remote server returned an error: NotFound.

в этом методе в Reference.cs:

public SilverlightApplication.SchemaServiceReference.XmlElementTreeNode EndGetTreeView(System.IAsyncResult result)
{
    object[] _args = new object[0];
    SilverlightApplication.SchemaServiceReference.XmlElementTreeNode _result = ((SilverlightApplication.SchemaServiceReference.XmlElementTreeNode)(base.EndInvoke("GetTreeView", _args, result)));
    return _result;
}

Я переписал службу, чтобы вместо нее вернуть theNode.Name и theNode.Attributes.Оба из них работали.Я также переписал сервис для возврата theNode.Children и получаю ту же самую точную ошибку.

Поэтому, когда я получаю эту ошибку, я никогда не достигаю этот код в Silverlight, потому что сервис не "завершил".

void service_GetTreeViewCompleted(object sender, GetTreeViewCompletedEventArgs e)
{
    XmlElementTreeNode rootNode = e.Result;
}

Однако я нашел это интересным.Я изменил return theNode на return theNode.Children[0].Итак, я все еще возвращаю объект XmlElementTreeNode в Silverlight.Когда я сделал это, я смог получить доступ к методу service_GetTreeViewCompleted и получить доступ к своему дереву узлов (хотя только начиная с первого потомка корневого узла).Мне кажется странным, что это сработало, но не «корневой» узел (исходная переменная theNode).

У кого-нибудь есть идеи, как вернуть мою переменную theNode?Я совершенно новичок в WCF, поэтому, возможно, есть какой-то другой способ правильного возврата моего сложного пользовательского объекта, о котором я не знаю.

Обновление 1

My XmlElementTreeNode объект представляет элемент xml, определенный в документе xsd.Сгенерированная иерархия XmlElementTreeNodes представляет все возможные элементы, которые могут быть созданы в XML-файле, который проверяется на соответствие XRI-идентификаторам URI, передаваемым в мой сервис.Так уж получилось, что первый элемент theNode.Children представляет собой только небольшое дерево узлов.Тем не менее, я попытался вернуть theNode.Children[1], который имеет тысячи подузлов, и я получаю ту же ошибку.Итак, я думаю, что проблема в том, что размер всего объекта theNode слишком велик.

Я попытался отредактировать привязку следующим образом в Web.config:

    <binding name="SilverlightApplication.Web.SchemaService.customBinding0">
      <textMessageEncoding>
        <readerQuotas maxDepth="2147483647"
          maxStringContentLength="2147483647"
          maxArrayLength="2147483647"
          maxBytesPerRead="2147483647"
          maxNameTableCharCount="2147483647" />
      </textMessageEncoding>
      <httpTransport maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" />
      <binaryMessageEncoding maxReadPoolSize="2147483647" maxSessionSize="2147483647" maxWritePoolSize="2147483647" />
    </binding>

Нодаже с этими огромными значениями я получаю ту же ошибку.

Ответы [ 2 ]

3 голосов
/ 07 июня 2011

Ошибка «NotFound» является большой проблемой в Silverlight, потому что по сути это означает, что «что-то пошло не так» - по умолчанию все не-200 ответов от сервиса переводятся в 404 (не найдено) сетевым уровнем SL, и никакая дополнительная информация не предоставляется программе. Несколько вещей, которые вы можете сделать:

  • Посмотрите на инструмент захвата сети (например, Fiddler ), чтобы увидеть точный ответ, который сервер возвращает клиенту.
  • Если ответ похож на 500 (Внутренняя ошибка сервера), включить трассировку на стороне сервера, и трассировка должна содержать исключение, объясняющее ошибку.

Существует несколько документов об отладке служб WCF в SL. Есть хорошее видео (длительностью 25 минут) на http://blogs.msdn.com/b/silverlightws/archive/2010/09/23/debugging-wcf-services-in-silverlight.aspx,, и есть страница MSDN на http://msdn.microsoft.com/en-us/library/cc197938(v=VS.95).aspx с некоторой хорошей информацией.

1 голос
/ 08 июня 2011

Как и ожидалось, проблема в том, что мой возвращаемый объект слишком большой.Я обнаружил, что мне нужно добавить следующую строку в мой Web.config:

<dataContractSerializer maxItemsInObjectGraph="2147483647"/>

В контексте с остальным Web.config:

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
   ...
...