简体   繁体   English

在 WCF 中返回自定义 class

[英]Returning a custom class in WCF

I created WCF service that returns a custom object called XmlElementTreeNode.我创建了 WCF 服务,该服务返回一个名为 XmlElementTreeNode 的自定义 object。 This is what the object looks like:这是 object 的样子:

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

I am able to successfully create a heirarchy of these nodes with this method:我能够使用此方法成功创建这些节点的层次结构:

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

But the error I get back is:但我回来的错误是:

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

at this method in Reference.cs:在 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;
}

I rewrote the service to return theNode.Name and theNode.Attributes instead.我重写了服务以返回theNode.NametheNode.Attributes Both of those worked.这两个都有效。 I also rewrote the service to return theNode.Children and I get the same exact error.我还重写了服务以返回theNode.Children ,我得到了同样的错误。

So, when I get this error, I never reach this code in Silverlight, because the service did not "finish."因此,当我收到此错误时,我从未在 Silverlight 中找到此代码,因为服务没有“完成”。

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

However, I found this interesting.然而,我发现这很有趣。 I changed return theNode to return theNode.Children[0] .我将return theNode更改为return theNode.Children[0] So, I still am returning an XmlElementTreeNode object to Silverlight.所以,我仍然将 XmlElementTreeNode object 返回给 Silverlight。 When I did this, I was able to reach the service_GetTreeViewCompleted method and access my tree of nodes (although only starting from the first child of the root node).当我这样做时,我能够访问service_GetTreeViewCompleted方法并访问我的节点树(尽管仅从根节点的第一个子节点开始)。 I think it's strange that this worked, but not the "root" node (the original theNode variable).我认为这很奇怪,但不是“根”节点(原始的theNode变量)。

Anyone have any ideas how I can return my theNode variable?任何人都知道如何返回我的theNode变量? I'm completely new to WCF, so maybe there is some other way to go about returning my complex custom object properly that I am not aware of.我对 WCF 完全陌生,所以 go 可能还有其他方法可以正确返回我不知道的复杂自定义 object。

Update 1更新 1

My XmlElementTreeNode object represents an xml element as defined by an xsd document.我的XmlElementTreeNode object 表示由 xsd 文档定义的 xml 元素。 The generated heiarchy of XmlElementTreeNodes represent all the possible elements that could be created in an XML file thati validated against the XSD uri being passed into my service.生成的XmlElementTreeNodes层次结构表示可以在 XML 文件中创建的所有可能元素,该文件已针对传递到我的服务的 XSD uri 进行验证。 It just so happens that the first element of theNode.Children represents only a small tree of nodes.碰巧theNode.Children的第一个元素只代表一棵小节点树。 However, I tried to return theNode.Children[1] , which has thousands of sub-nodes, and I get the same error.但是,我尝试返回具有数千个子节点的theNode.Children[1] ,我得到了同样的错误。 So, I think the problem is that the size of the entire theNode object is simply too big.所以,我认为问题在于整个theNode的大小实在是太大了。

I tried editing my binding as follows in Web.config:我尝试在 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>

But, even with those huge values, I get the same error.但是,即使有这些巨大的价值,我也会得到同样的错误。

The "NotFound" error is a big issue in Silverlight because it essentially means that "something went wrong" - by default all non-200 responses from the service are translated into a 404 (Not Found) by the SL networking layer, and no further information is given to the program. “未找到”错误是 Silverlight 中的一个大问题,因为它本质上意味着“出了点问题”——默认情况下,来自服务的所有非 200 响应都被 SL 网络层转换为 404(未找到),不再赘述信息被提供给程序。 A few things you can do:你可以做几件事:

  • Look at a network capture tool (such as Fiddler ) to see the exact response that the server is returning to the client.查看网络捕获工具(例如Fiddler )以查看服务器返回给客户端的确切响应。
  • If the response is something like 500 (Internal Server Error), enable tracing on the server side and the trace should contain an exception which explains the error.如果响应类似于 500(内部服务器错误),请在服务器端启用跟踪,并且跟踪应包含解释错误的异常。

There are some documentations about debugging WCF services in SL.有一些关于在 SL 中调试 WCF 服务的文档。 There's a good video (25 minutes long) at http://blogs.msdn.com/b/silverlightws/archive/2010/09/23/debugging-wcf-services-in-silverlight.aspx , and there's a MSDN page at http://msdn.microsoft.com/en-us/library/cc197938(v=VS.95).aspx with some good information as well.http://blogs.msdn.com/b/silverlightws/archive/2010/09/23/debugging-wcf-services-in-silverlight.aspx上有一个很好的视频(25 分钟长),还有一个 MSDN 页面在http://msdn.microsoft.com/en-us/library/cc197938(v=VS.95).aspx以及一些很好的信息。

As expected, the problem is that my returned object is too big.不出所料,问题是我返回的 object 太大了。 I found out that I needed to add the following line to my Web.config:我发现我需要将以下行添加到我的 Web.config 中:

<dataContractSerializer maxItemsInObjectGraph="2147483647"/>

In context with the rest of the Web.config:在 Web.config 的 rest 的上下文中:

<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>
   ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM