2011-06-07 77 views
2

我創建了WCF服務,該服務返回一個名爲XmlElementTreeNode的自定義對象。這是對象的樣子:返回WCF中的自定義類

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

在參考文獻中的此方法:

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.NametheNode.Attributes。這兩個工作。我還重寫了該服務以返回theNode.Children,並得到相同的確切錯誤。

所以,當我得到這個錯誤時,我從來沒有在Silverlight中達到這個代碼,因爲服務沒有「完成」。

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

但是,我發現這很有趣。我將return theNode更改爲return theNode.Children[0]。所以,我仍然在向Silverlight返回一個XmlElementTreeNode對象。當我這樣做時,我能夠到達service_GetTreeViewCompleted方法並訪問我的節點樹(儘管只從根節點的第一個子節點開始)。我認爲這很有效,但不是「根」節點(原始的theNode變量)。

任何人有任何想法如何我可以返回我的theNode變量?我對WCF完全陌生,所以也許還有其他一些方法可以正確地返回我不知道的複雜自定義對象。

更新1

XmlElementTreeNode對象表示由XSD文檔所定義的XML元素。生成的XmlElementTreeNodes的heiarchy表示可以在XML文件中創建的所有可能的元素,這些元素都是針對傳遞到我的服務中的XSD 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> 

,甚至與那些巨大的價值,我得到了同樣的錯誤。

回答

3

「NotFound」錯誤在Silverlight中是一個大問題,因爲它基本上意味着「出錯了」 - 默認情況下,來自服務的所有非200響應都會被SL網絡層轉換爲404(Not Found) ,並沒有進一步的信息給予該方案。你可以做幾件事:

  • 查看網絡捕獲工具(如Fiddler)查看服務器返回到客戶端的確切響應。
  • 如果響應類似服務器端的500(內部服務器錯誤),enable tracing,並且跟蹤應包含解釋錯誤的異常。

有一些關於在SL中調試WCF服務的文檔。有一個很好的視頻(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以及一些很好的信息。

+0

使用招,我得到這個反應我服務:「ReadResponse()失敗:服務器沒有爲此請求返回響應。」我還將着眼於啓用跟蹤。 – 2011-06-07 20:32:30

+0

該視頻非常有幫助。但是,我對該視頻進行了一切嘗試,只有一種情況是我有任何類型的不同調試結果。當我在ServicesReferences.ClientConfig中更新我的服務以使用相對路徑('../ SchemaService.svc'而不是'http:// localhost:12345/SchemaService.svc')時,我得到TimeoutException被用戶代碼未處理遠程服務器在Visual Studio中返回了一個錯誤:NotFound。但沒有任何額外的提琴手,或ViewDetail - > InnerException/StackTrace等.. – 2011-06-07 22:13:49

+0

「ReadResponse()失敗:服務器沒有返回響應」 - 請求實際上到服務器?至於使用http:// localhost ...時沒有顯示任何內容,IIRC fiddler不會捕獲發送到* localhost *的請求,您需要將它發送到機器名稱(並且還可以使用機器打開SL頁面名稱而不是本地主機,以防止跨域問題) – carlosfigueira 2011-06-08 18:20:01

1

正如所料,問題是我返回的對象太大了。我發現我需要將下面的行添加到我的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> 
    ...