【问题标题】:Consuming Java Webservice TimeStamp from .net and WCF从 .net 和 WCF 使用 Java Webservice TimeStamp
【发布时间】:2010-11-29 07:20:11
【问题描述】:

我们正在尝试使用 WCF 与 .NET 3.5 中的(可能的)Java WebService 通信。 WebService 定义了一个 Timestamp 对象,它似乎是一个没有十进制毫秒的日期时间。

WCF 决定 .NET 将使用数据时间作为支持代理类的对象。将带有时间戳的对象发送到 Java WebServer 时,日期时间被序列化并包括毫秒。这会导致错误。

我们如何 a) 使 .NET 选择我们实现的自定义类(以便我们可以格式化消息)或 b) 使 WCF 根据 WSDL 中包含的 XSD 文件生成日期时间?

问题定义:时间戳需要如下所示: 2010-01-01T01:01:01-07:00

然而 .NET 会生成一个带小数秒的时间戳,例如: 2010-01-01T01:01:01.1234-07:00

【问题讨论】:

    标签: c# .net wcf web-services timestamp


    【解决方案1】:

    能否修改代码,将其作为字符串传递并在 .ToString() 方法中格式化,如下面的 sn-p 所示?

    SomeTime.ToString("yyyy-MM-ddThh:mm:ss")
    

    【讨论】:

    • 其实要得到最后的时区偏移量,需要做 SomeTime.ToString("yyyy-MM-ddTHH:mm:ssZ"));
    【解决方案2】:

    通过“WCF 决定 .NET 将使用日期时间”,我感觉您使用 Visual Studio 添加对 Web 服务的引用。

    我建议使用SvcUtil 生成代理,然后将其添加到您的项目中。通过这种方式,您可以直接编辑代理并使其按照您的需要运行(例如,序列化字符串而不是日期时间,或者以不同的方式对其进行格式化)。

    每当服务合同发生变化时,您都需要创建一个新代理并合并您的更改,但这通常是为额外控制付出的小代价。

    【讨论】:

    • 是的,你是对的。我们使用 Visual Studio 添加服务引用。我们确实修改了生成的代码以返回一个字符串,但希望避免每次更新 Web 服务时都更改代理。我们对 Web 服务没有任何控制权,也有很多开发人员。每次都强制我们更新代码不是理想的解决方案,但绝对不是我们的首选。是否可以让 SvcUtil 为时间戳选择自定义类而不是基类 datetime?
    • @unknown - 我认为你错过了这一点。生成自己的代理的目的是让您可以修改代理,而不是让 SvcUtil 为您修改它。
    • 感谢您的回答。我们需要更新服务引用不止一点点,所以我希望(真的希望)有一种方法可以强制代理生成器第一次正确创建代理。我们目前正在使用您指定的解决方法。
    • @Coach David - 我不相信你可以。这是不断变化的服务合同很糟糕的原因之一!
    • -1:你不应该修改生成的代码。 svcutil 也会生成与“添加服务引用”相同的代码。
    【解决方案3】:

    我想出了一些方法来解决这个问题。更复杂的方法涉及挂钩自定义 MessageFormatter 端点。

    我们找到了一种简单的方法。

    仅当日期时间对象具有秒数时才会生成分数。

    我们做了什么:

    我们创建了一个静态的 on propertychange 事件处理程序,它使用反射来检测日期时间数据类型。找到后,我们重新创建日期时间而没有秒数。在我们的例子中,我们根本不关心秒数。我们将事件连接到部分类构造函数中。就是这样。

    当然

    public static class DateTimeSecondCatcher
    {
        PropertyInfo dateTimePropertyInfo = sender.GetType().GetProperty(e.PropertyName);
            if ((dateTimePropertyInfo != null) && (dateTimePropertyInfo.PropertyType == typeof(DateTime)))
            {
    
                DateTime dteValue = (DateTime)dateTimePropertyInfo.GetValue(sender, null);
                if (dteValue.Millisecond > 0)
                {
                    dateTimePropertyInfo.SetValue(sender, new DateTime(dteValue.Year,dteValue.Month,dteValue.Day, dteValue.Hour,dteValue.Minute,dteValue.Second,0,dteValue.Kind), null);
                }
            }
    
    }
    
    
    // This code goes in the partial class constructor
    this.PropertyChanged += new PropertyChangedEventHandler(DateTimeSecondCatcher.OnPropertyChanged);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 2014-04-16
      • 1970-01-01
      • 2016-10-11
      相关资源
      最近更新 更多