2011-03-10 43 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