【问题标题】:What is your preferred method of sending complex data over a web service?通过 Web 服务发送复杂数据的首选方法是什么?
【发布时间】:2008-08-16 03:58:24
【问题描述】:

现在是 2008 年,我仍然对这个感到困惑。因此,我正在开发一种需要将复杂类型传递到其中并从中返回的 Web 方法。我正在玩弄的两个选项是:

  1. 传递和返回具有数据和行为的实际业务对象。运行 wsdl.exe 时,它​​会自动创建仅包含数据部分的代理类,并且这些代理类将自动与服务器端的真实业务对象相互转换。在客户端,他们只能使用哑代理类型,并且他们必须将它们映射到他们认为合适的一些真实的业务对象中。这里的一个大缺点是,如果我同时“拥有”服务器端和客户端,并且我想使用同一组真实业务对象,我可能会遇到名称冲突等问题。(因为真实对象和代理名称相同。)

  2. 忘记尝试传递“真实”业务对象。相反,只需创建简单的 DataTransfer 对象,我将手动将其映射到我的真实业务对象。无论如何,它们仍然会被 wsdl.exe 复制到新的代理对象中,但至少我没有自欺欺人地认为 Web 服务可以原生处理其中包含业务逻辑的对象。

顺便说一句 - 有谁知道如何告诉 wsdl.exe 制作对象的副本?我们不应该直接告诉它,“嘿,在这里使用这个现有的类型。不要复制它!”

无论如何,我现在已经确定了#2,但我很好奇你们的想法。我感觉总体上有方式更好的方法可以做到这一点,而且我的所有观点可能都不完全准确,所以请告诉我你的经历。

更新:我刚刚发现 VS 2008 在添加“服务引用”时可以选择重用现有类型,而不是在代理文件中创建全新的相同类型。甜蜜。

【问题讨论】:

    标签: .net web-services soap wsdl


    【解决方案1】:

    我会做一个混合动力车。我会使用这样的对象

    public class TransferObject
    {
        public string Type { get; set; }
        public byte[] Data { get; set; }
    }
    

    然后我有一个不错的小实用程序,可以序列化一个对象然后压缩它。

    public static class CompressedSerializer
    {
        /// <summary>
        /// Decompresses the specified compressed data.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="compressedData">The compressed data.</param>
        /// <returns></returns>
        public static T Decompress<T>(byte[] compressedData) where T : class
        {
            T result = null;
            using (MemoryStream memory = new MemoryStream())
            {
                memory.Write(compressedData, 0, compressedData.Length);
                memory.Position = 0L;
    
                using (GZipStream zip= new GZipStream(memory, CompressionMode.Decompress, true))
                {
                    zip.Flush();
                    var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    result = formatter.Deserialize(zip) as T;
                }
            }
    
            return result;
        }
    
        /// <summary>
        /// Compresses the specified data.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        public static byte[] Compress<T>(T data)
        {
            byte[] result = null;
            using (MemoryStream memory = new MemoryStream())
            {
                using (GZipStream zip= new GZipStream(memory, CompressionMode.Compress, true))
                {
                    var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    formatter.Serialize(zip, data);
                }
    
                result = memory.ToArray();
            }
    
            return result;
        }
    }
    

    然后您只需传递具有类型名称的传输对象。所以你可以做这样的事情

    [WebMethod]
    public void ReceiveData(TransferObject data)
    {
        Type originType = Type.GetType(data.Type);
        object item = CompressedSerializer.Decompress<object>(data.Data);
    }
    

    现在压缩序列化器使用泛型使其具有强类型,但您可以轻松地创建一个方法来使用上面的 originType 反序列化 Type 对象,这一切都取决于您的实现。

    希望这能给你一些想法。哦,要回答你的另一个问题,wsdl.exe 不支持重用类型,但 WCF 支持。

    【讨论】:

    • 谢谢你!直到我注意到您在 处理 zip 流之后读取了内存流,我才能进行压缩工作。显然刷新 zip 流是不够的......
    【解决方案2】:

    还有一个用于分离层的论据 - 有一组可序列化的对象,这些对象可以传入和传出 Web 服务,还有一个转换器可以在该集合和业务对象之间进行映射和转换(可能具有不适合的属性)穿过电线)

    这是 Web 服务软件工厂 service factory 青睐的方法,这意味着您可以在不破坏 Web 服务接口/合同的情况下更改业务对象

    【讨论】:

      【解决方案3】:

      Darren 写道: 我会做一个混合动力车。我会使用这样的对象...

      有趣的想法...传递对象的序列化版本而不是(wsdl-ed)对象本身。在某种程度上,我喜欢它的优雅,但在另一方面,它似乎违背了将您的 Web 服务公开给潜在的第三方或合作伙伴或其他任何东西的目的。他们怎么知道要通过什么?他们是否必须完全依赖文档?它也失去了一些“异构客户端”方面,因为序列化是非常特定于 .Net 的。我并不是要批评,我只是想知道您提出的建议是否也适用于这些类型的用例。不过,我认为在封闭环境中使用它没有任何问题。

      我应该研究一下 WCF...我一直在避免它,但也许是时候了。

      【讨论】:

        【解决方案4】:

        哦,当然,我只在我是 web 服务的消费者或者你有某种控制器从它们请求对象然后你处理序列化和发送而不是它们直接使用 web 时才这样做服务。但实际上,如果他们直接使用 Web 服务,那么他们就不需要或不一定拥有首先包含该类型的程序集,而应该使用 wsdl 生成的对象。

        是的,我提出的内容非常特定于 .NET,因为我不喜欢使用其他任何东西。我唯一一次在 .net 之外使用 web 服务是在 javascript 中,但现在我只使用 json 响应而不是 xml webservice 响应:)

        【讨论】:

          猜你喜欢
          • 2014-07-14
          • 2015-05-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-20
          • 1970-01-01
          • 2013-11-17
          • 1970-01-01
          相关资源
          最近更新 更多