【问题标题】:Is it possible to return interfaces from .net webservices or can one only return concrete classes?是否可以从 .net webservices 返回接口,或者只能返回具体类?
【发布时间】:2010-10-04 00:27:30
【问题描述】:

我需要从 web 服务返回一个复杂类型,并构建了实现 IMyComplexType 接口的 MyComplexType 类。现在在我的网络服务中,我有一个方法应该返回一个实现 IMyComplexType 的对象,如下所示:

[WebMethod]
public IMyComplexType GetMyComplexType()
{
   IMyComplexType myCt = new MyComplexType();
   ...
   return myCt; 
}

一切都可以编译,但是当我运行 web 服务时,它会抛出如下异常:

System.NotSupportedException: Cannot serialize interface MyWebService.IMyComplexType.

这是设计使然还是我遗漏了什么。我可以以某种方式装饰我的班级或界面以允许这样做吗?我是否必须消除所有接口,只使用具体的或抽象的基类才能使用 .net webservices 做到这一点?

编辑:

这是我要序列化的接口:

public interface ICustomer
{
     long Id {get; set;}
     string Name {get; set;}
     string EmailAddress {get; set;}
}

【问题讨论】:

    标签: .net web-services interface


    【解决方案1】:

    已经有一段时间了,但我相信你只需要让你的接口扩展 ISerializable 就可以了。

    【讨论】:

    • 这反过来要求我在我的所有类中实现 ISerializable 接口——而我希望能够序列化而不必这样做。我只需要公共财产。消除接口并仅使用具体类可以正常工作,但这是最佳实践吗??
    【解决方案2】:

    您不需要实现ISerializable - 只需使用Serializable 属性标记接口即可。如果你想实现接口,一定要继续——它会让你对接口的序列化方式进行细粒度的控制。但我想默认实现应该没问题。还要检查以确保所有接口成员也是可序列化的。

    [编辑] 我什至没有直截了当地思考 - 你无法实现ISerializable,因为无论如何你都在尝试序列化一个 iterface。适合ISerializable 的地方是需要接口公开的自定义序列化的自定义类型。

    【讨论】:

    • 不能将 Serializable 属性放在接口上 - 只能放在类、枚举等上。我试了一下,但没有运气。你还有什么建议吗?我没有任何自定义序列化需求。我只是想通过接口而不是具体类型正确地公开事物。 .net ws 不可能吗?
    • 听起来您界面中的一种类型不可序列化 - 您可以编辑您的帖子并添加界面代码吗?
    • 好的。增加了界面。有没有办法在不实现 ISerializable 的情况下做到这一点,因为我只想按原样序列化它并且没有自定义需求?
    【解决方案3】:

    简短的回答是否定的,您不能通过 WebService 返回接口。

    长答案是你可以得到你想要的行为,但这有点hacky。解决方案是使用二进制序列化。所以你将你的类型序列化为字节,让 web 方法返回一系列字节,然后在另一方面你将字节反序列化回你的复杂类型。

    例如

    [WebMethod]
    public byte[] GetMyComplexType()
    {
    
       IMyComplexType myCt = new MyComplexType();
       ...
    
       MemoryStream stream = new MemoryStream();
       IFormatter fmt = new BinaryFormatter();
       fmt.Serialize(stream, myCt);
       stream.Flush();
       byte[] bytes = stream.ToArray();
       stream.Close();
    
       return bytes;
    }
    

    您需要将所有内容都转换回另一端。

    byte[] bytes = service.GetMyComplexType();
    MemoryStream stream = new MemoryStream(bytes);
    BinaryFormatter fmt = new BinaryFomatter();
    MyComplexType myCt = fmt.DeSerialize(stream);
    

    您可能可以通过创建通用方法来清理反序列化。我应该补充一点,您需要确保可以在客户端上引用复杂类型。

    或者,如果它们是您的接口,那么您可以将它们转换为抽象类。但是,如果您希望该类实现多个接口(或者您已经从另一个类继承),这将不起作用,因为您只能继承一个类。如果您需要客户端上的一些多态行为,则需要使用 XmlInclude 属性。

    【讨论】:

      猜你喜欢
      • 2011-02-10
      • 1970-01-01
      • 2012-09-24
      • 1970-01-01
      • 2018-06-07
      • 2016-03-15
      • 1970-01-01
      • 2012-10-03
      • 1970-01-01
      相关资源
      最近更新 更多