2011-03-10 46 views
3

在此工作中,我們開發了一個可以從外部訪問的SOAP WCF API。由於API的其中一項要求發生了變化,因此我希望爲此API添加一個新類以爲某些函數調用生成正確的路徑。返回數據時的WCF CommunicationException

我們的API分爲3個獨立的庫:

  • 一爲對象
  • 一個用於接口
  • 一個用於實現。

客戶端的課程獲得前兩個在腳本中使用,服務器有三個。

我想加入到API的類看起來是這樣的:

namespace TenForce.Execution.API.Objects.Helpers 
{ 
/// <summary> 
/// <para>This interface defines the functionality available in the PathHelper for the API.</para> 
/// </summary> 
public interface IPathHelper 
{ 
    string ApplicationFolder { get; } // The HomeDataFolder for the application 
    string CompanyHomeFolder { get; } // The HomeDataFolder for the company. 
    string CustomFolder { get; }  // The custom folder for professional services. 
    string WikiFolder { get; }   // The WIKI folder to store pages. 
    string AddinsFolder { get; }  // The AddinFolder to access the addins. 
} 
} 

實際的類實現看起來是這樣的:

using System.IO; 
using System.Runtime.Serialization; 
using TenForce.Execution.BUL; 
using TenForce.Execution.Framework; 

namespace TenForce.Execution.API.Implementation.Helpers 
{ 
/// <summary> 
/// <para>This class provides a direct implementation of the IPathHelper for the API implementation 
/// and manages all the paths inside the DataHomeFolder structure for the TenForce application.</para> 
/// </summary> 
[DataContract] 
public class PathHelper : Objects.Helpers.IPathHelper 
{ 
    #region Private Fields 

    private readonly ParameterBUL _mParameterBul; 
    private const Parameter.ParameterId DataHomeFolderId = Parameter.ParameterId.DataHomeFolder; 
    private const Parameter.ParameterId CompanyNameId = Parameter.ParameterId.CompanyName; 

    #endregion 

    #region Constructor 

    /// <summary> 
    /// <para>Creates a new instance of the PathHelper class</para> 
    /// </summary> 
    public PathHelper() 
    { 
     _mParameterBul = new ParameterBUL(); 
    } 

    #endregion 

    #region IPathHelper Members 

    /// <summary> 
    /// <para>Returns the absolute path to the DataHomeFolder of the TenForce Application.</para> 
    /// </summary> 
    [DataMember] 
    public string ApplicationFolder 
    { 
     get 
     { 
      return CreatePath(_mParameterBul.GetParameterValue(DataHomeFolderId)); 
     } 
    } 

    /// <summary> 
    /// <para>Returns the absolute path to the Company DataHomeFolder.</para> 
    /// </summary> 
    [DataMember] 
    public string CompanyHomeFolder 
    { 
     get 
     { 
      return CreatePath(Path.Combine(ApplicationFolder, _mParameterBul.GetParameterValue(CompanyNameId))); 
     } 
    } 

    /// <summary> 
    /// <para>Returns the absolute path to the Company custom folder.</para> 
    /// </summary> 
    [DataMember] 
    public string CustomFolder 
    { 
     get 
     { 
      return CreatePath(Path.Combine(CompanyHomeFolder, @"custom")); 
     } 
    } 

    /// <summary> 
    /// <para>Returns the absolute path to the Company wiki folder.</para> 
    /// </summary> 
    [DataMember] 
    public string WikiFolder 
    { 
     get 
     { 
      return CreatePath(Path.Combine(CompanyHomeFolder, @"wiki")); 
     } 
    } 

    /// <summary> 
    /// <para>Returns the absolute path to the Company addins folder.</para> 
    /// </summary> 
    [DataMember] 
    public string AddinsFolder 
    { 
     get 
     { 
      return CreatePath(Path.Combine(CompanyHomeFolder, @"addins")); 
     } 
    } 

    #endregion 

    #region Private Members 

    /// <summary> 
    /// <para>Checks if the specified path exists, and creates the path 
    /// if the system cannot find it.</para> 
    /// </summary> 
    /// <param name="path">The path to verify.</param> 
    private static string CreatePath(string path) 
    { 
     if (!Directory.Exists(path)) 
      Directory.CreateDirectory(path); 
     return path; 
    } 

    #endregion 
} 
} 

所有這一切都是非常基本的東西。 WCF服務是由我們使用通過.NET提供的工廠和類動態創建的。 WCF服務可以完美地處理服務中已有的所有代碼。

所以我決定加入這就是我們服務的類內以下行:

/// <summary> 
    /// <para>Returns the PathHelper to construct the various paths for API Scripts.</para> 
    /// </summary> 
    /// <returns>An instance of the PathHelper.</returns> 
    public Objects.Helpers.IPathHelper GetPathHelper() 
    { 
     return new Helpers.PathHelper(); 
    } 

    #endregion 

當我運行單元測試,所有測試除了那些檢查PathHelper的職能工作,他們都結束了用相同的錯誤消息/異常:

錯誤1個測試用例 'TenForce.Execution.API.ImplementationTest/HelperTests/CheckApplicationFolderPath' 失敗: 執行 System.ServiceModel.CommunicationException:遠程端點沒有LON ger識別這個序列。這很可能是由於遠程終端上的終止。 wsrm:Identifier的值不是已知的序列標識符。可靠的會話有問題。

服務器堆棧跟蹤: 在System.ServiceModel.Channels.ReliableRequestSessionChannel.SyncRequest.WaitForReply(時間跨度超時) 在System.ServiceModel.Channels.RequestChannel.Request(消息消息,時間跨度超時) 在System.ServiceModel.Dispatcher System.ServiceModel.Channels.ServiceChannel.Call(String action,Boolean oneway,ProxyOperationRuntime operation,Object [] ins,Object []輸出,TimeSpan超時) (在System.ServiceModel中).RequestChannelBinder.Request .Channels.ServiceChannel.Call(String action,Boolean oneway,ProxyOperationRuntime operation,Object [] ins,Object [] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeS ervice(IMethodCallMessage包括MethodCall,ProxyOperationRuntime操作) 在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(即時聊天消息)[0]時

異常重新拋出: 在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(即時聊天reqMsg ,IMessage retMsg) at TenForce.Execution.API.Contracts.IAPI System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData & msgData,Int32 type) 。GetPathHelper() at c:\ Users \ arne.de.herdt \ Documents \ Trunk \ Robinson \ TenForce.Execution.API.ServiceClient \ ServiceAPI.cs中的TenForce.Execution.API.ServiceClient.ServiceAPI.GetPathHelper():line 163 at C:\ Users \ arne.de.herdt \ Documents \ Trunk \ Robinson \ TenForce.Execution.API.ImplementationTest \ HelperTests.cs中的TenForce.Execution.API.ImplementationTest.HelperTests.CheckApplicationFolderPath():第56行c:\用戶\ arne.de.herdt \文檔\幹線\羅賓遜\ TenForce.Execution.API.ServiceClient \ ServiceAPI.cs 163

我無言以對什麼錯,或者說我錯過了什麼。代碼正在爲已經存在的內容工作,但是當我添加了我的內容時,它已經失靈,但現有的功能仍在運行。這是我的,導致一個問題。

+0

+1對問題的一個很好和詳細的解釋 – Peter 2011-03-10 08:38:55

+0

服務器上可能會有一些未處理的錯誤中止會話。使用WCF跟蹤獲取更多信息:http://msdn.microsoft.com/en-us/library/ms733025.aspx – 2011-03-10 08:44:02

+0

是GetPathHelper OperationContract?在這種情況下,您必須使用KnownType屬性或ServiceKnownType屬性來定義可以返回哪些路徑幫助器類型。 – 2011-03-10 08:46:55

回答

0

由於從意見和awnser反饋,解決的辦法是對類移動到第二API實現,而不是讓它avaialble通過WCF服務。

該類包含函數和只讀屬性,因此該類不能被WCF服務序列化。最終的結果將是隻有腳本可以使用它,而不是服務。

+0

看似合乎邏輯,只對客戶有效 – 2011-03-10 10:44:21

1

這個錯誤對我來說似乎很奇怪,也許它與您動態生成服務的方式有關。

但是,該類不是可序列化的,該類的屬性是隻讀的(沒有set訪問器)。爲了將屬性標記爲DataMember,屬性需要具有設置的訪問器,即使它被標記爲私有。從MSDN:

注到其DataMemberAttribute屬性已被應用必須同時具有get和set領域 屬性;他們不能只是獲取或僅設置。

DataMember Documentation

您可能希望以一流的序列化的唯一的事情就是m_ParameterBul變量,因此這標誌着作爲數據成員,並刪除所有其他數據成員從只讀屬性屬性將做到這一點。

您應該注意,如果m_ParameterBul不依賴於服務器,則不需要在服務器端創建此類,因爲所有內容都與客戶端相關。在這種情況下,您應該直接在客戶端上創建它。

希望它有幫助!

/// <summary> 
/// <para>This class provides a direct implementation of the IPathHelper for the API implementation 
/// and manages all the paths inside the DataHomeFolder structure for the TenForce application.</para> 
/// </summary> 
[DataContract] 
public class PathHelper : Objects.Helpers.IPathHelper 
{ 
    #region Private Fields 
    [DataMember] 
    private readonly ParameterBUL _mParameterBul; 
    private const Parameter.ParameterId DataHomeFolderId = Parameter.ParameterId.DataHomeFolder; 
    private const Parameter.ParameterId CompanyNameId = Parameter.ParameterId.CompanyName; 

    #endregion 

    #region Constructor 

    /// <summary> 
    /// <para>Creates a new instance of the PathHelper class</para> 
    /// </summary> 
    public PathHelper() 
    { 
     _mParameterBul = new ParameterBUL(); 
    } 

    #endregion 

    #region IPathHelper Members 

    /// <summary> 
    /// <para>Returns the absolute path to the DataHomeFolder of the TenForce Application.</para> 
    /// </summary> 
    public string ApplicationFolder 
    { 
     get 
     { 
      return CreatePath(_mParameterBul.GetParameterValue(DataHomeFolderId)); 
     } 
    } 

    /// <summary> 
    /// <para>Returns the absolute path to the Company DataHomeFolder.</para> 
    /// </summary> 
    public string CompanyHomeFolder 
    { 
     get 
     { 
      return CreatePath(Path.Combine(ApplicationFolder, _mParameterBul.GetParameterValue(CompanyNameId))); 
     } 
    } 

    /// <summary> 
    /// <para>Returns the absolute path to the Company custom folder.</para> 
    /// </summary> 
    public string CustomFolder 
    { 
     get 
     { 
      return CreatePath(Path.Combine(CompanyHomeFolder, @"custom")); 
     } 
    } 

    /// <summary> 
    /// <para>Returns the absolute path to the Company wiki folder.</para> 
    /// </summary> 
    public string WikiFolder 
    { 
     get 
     { 
      return CreatePath(Path.Combine(CompanyHomeFolder, @"wiki")); 
     } 
    } 

    /// <summary> 
    /// <para>Returns the absolute path to the Company addins folder.</para> 
    /// </summary>  
    public string AddinsFolder 
    { 
     get 
     { 
      return CreatePath(Path.Combine(CompanyHomeFolder, @"addins")); 
     } 
    } 

    #endregion 

    #region Private Members 

    /// <summary> 
    /// <para>Checks if the specified path exists, and creates the path 
    /// if the system cannot find it.</para> 
    /// </summary> 
    /// <param name="path">The path to verify.</param> 
    private static string CreatePath(string path) 
    { 
     if (!Directory.Exists(path)) 
      Directory.CreateDirectory(path); 
     return path; 
    } 

    #endregion 
} 
+0

我已經按照您的說法應用了這些更改,現在我又得到了一個不同的錯誤。我不能完全粘貼在這裏,但它現在似乎是一個暫停,這仍然是奇怪的...... 我會盡量使與getter和setter的屬性,填寫服務的數據和然後傳送它。 – 2011-03-10 09:36:58