You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WCF传输System.IO.FileInfo时CreationTime被重置为1600年的简便解决方法咨询

WCF传输System.IO.FileInfo时CreationTime被重置为1600年的简便解决方法咨询

我太懂你这种觉得写包装类有点冗余甚至“蠢”的感受了!其实你遇到的问题核心很明确:System.IO.FileInfo本身的设计就不是为WCF的数据契约序列化而生的。

它虽然标记了[Serializable]属性,但WCF默认采用的是数据契约序列化(Data Contract Serializer),而FileInfo里的很多属性(比如CreationTime)是延迟加载的——也就是说,在服务器端序列化的时候,这些属性并没有真正去读取文件系统的真实值,只是保存了一个“待加载”的状态;当客户端反序列化时,因为没有服务器端的文件上下文,根本加载不到真实的时间数据,就会默认填充成DateTime类型的最小值附近(也就是你看到的1600年左右的异常时间)。

你提到的[Serializable]其实是给.NET旧式的二进制序列化用的,WCF默认不会优先使用它。如果强行让WCF切换到二进制序列化,虽然能解决部分问题,但会带来更多麻烦:比如客户端和服务器必须严格使用相同版本的.NET框架,跨平台兼容性几乎为零,反而不如包装类靠谱。

给你几个更实用的方案:

  • 方案一:优化你的包装类(其实没那么冗余!)
    你可以把包装类写得更通用、更易用,比如扩展它的属性覆盖常用场景,再配合扩展方法实现一键转换,这样代码复用性拉满,也不会显得繁琐:

    [DataContract]
    public class dcFileInfo
    {
        [DataMember] public string Name { get; set; }
        [DataMember] public DateTime CreationTime { get; set; }
        [DataMember] public DateTime LastWriteTime { get; set; }
        [DataMember] public long Length { get; set; }
        [DataMember] public string FullName { get; set; }
    
        // 空构造函数是WCF序列化的强制要求
        public dcFileInfo() {}
    
        public dcFileInfo(FileInfo fi)
        {
            Name = fi.Name;
            CreationTime = fi.CreationTime;
            LastWriteTime = fi.LastWriteTime;
            Length = fi.Length;
            FullName = fi.FullName;
        }
    }
    
    // 写个扩展方法,转换一行搞定
    public static class FileInfoExtensions
    {
        public static dcFileInfo ToDcFileInfo(this FileInfo fi)
        {
            return new dcFileInfo(fi);
        }
    }
    

    之后你只需要在服务端写fileInfo.ToDcFileInfo()就能完成转换,客户端拿到的就是纯粹的、没有依赖的数据对象,完全不会有时间重置的问题。

  • 方案二:强行启用NetDataContractSerializer(不推荐)
    如果你实在不想写包装类,可以让WCF使用支持[Serializable]的NetDataContractSerializer,但要做好兼容性牺牲:
    在你的服务契约接口上添加特性:

    [ServiceContract]
    public interface IYourFileService
    {
        [OperationContract]
        [SerializerFormat(Serializer = SerializerType.NetDataContractSerializer)]
        FileInfo GetFileInfo(string filePath);
    }
    

    但要注意:这种方式要求客户端必须和服务器使用完全一致的.NET环境,而且客户端反序列化后得到的FileInfo对象在本地是“无效”的——因为它指向的是服务器上的文件路径,客户端本地根本没有这个文件,后续操作大概率会报错。

最后想说一句:其实包装类真的是最稳妥的选择!WCF的设计理念就是传输纯数据契约对象,而不是像FileInfo这种和系统资源强绑定的复杂对象。包装类虽然多写了几行代码,但能让你的数据传输逻辑更清晰、更可控,完全避免序列化的隐藏坑。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 07:33:03