使用C#中的SOAP通过Web服务传递对象

时间:2011-12-07 02:23:09

标签: c# xml web-services serialization soap

我正在研究服务器客户端应用程序。使用webservice webmethods完成通信。服务器和客户端都是用C#编写的。我已经和它斗争了几天,但我无法解决它。

我有通过webservice发送复杂类的问题 - 到目前为止我尝试了很多东西,但没有一个能够工作。

每个webmethod返回ServiceResult类,如下所示:

    public class ServiceResult
    {
        public ResultStatus Status;
        public object ResultObject;

        public ServiceResult(ResultStatus status, object resultObject)
        {
            Status = status;
            ResultObject = resultObject;
        }
    }

ResultStatus是枚举,ResultObject是实际返回值。当我试图通过webservice发送复杂的类时,问题出现了。

例如,我有抽象类Job,它有私有元素。

public abstract class Job : IComparable<Job>
{
    public static readonly int DefaultDelay = 5000;

    private int _jobID;
    private int _referringID;
    private JobType _jobType;
    protected JobState _jobState;
    private JobPriority _jobPriority;
    [...]   
}

但是当我尝试通过webmethod继承Job类(让我们称之为JobA)的发送类时,我有错误。因为我在任何web方法中都没有明确的JobA返回类型,所以当我调用webmethod时会出现错误:

  

System.Web.Services.Protocols.SoapException:服务器无法执行   处理请求。 ---&GT; System.InvalidOperationException:有一个   生成XML文档时出错。 ---&GT;   System.InvalidOperationException:可能不使用Job []类型   这个背景。

这是关于第一次错误。现在不同类有另一个问题,其中错误看起来像这样(再次,当调用webmethod时):

  

System.Web.Services.Protocols.SoapException:服务器无法执行   处理请求。 ---&GT; System.InvalidOperationException:有一个   生成XML文档时出错。 ---&GT;   System.InvalidOperationException:不期望该类型。使用   XmlInclude或SoapInclude属性指定不是的类型   静态地知道。

当我添加[SoapInclude(typeof(MyClass))]时它没有区别,但是使用XmlInclude来生成我的ServiceResult.ResultObject XmlNodes数组。

我认为这两个问题都与序列化有关,但我不知道如何解决它们。基本上,我的问题是:如何通过webmethod以如此方式将自定义对象从服务器传递到客户端,以便我可以将它们用作对象(我想将此ServiceResult.ResultObject强制转换为类并将其用作临时实例那个班)?最好的方法是什么?

有人可以建议任何解决方案吗?

1 个答案:

答案 0 :(得分:3)

根据初始错误消息,听起来您可能在您尝试序列化的类中有一个属性Job的数组或集合,这将导致您看到的异常。

如果不应该序列化此属性,则可以使用XmlIgnore属性对其进行修饰。

此外,当我尝试调试Web服务序列化的问题时,我通常使用XmlSerializer来序列化我的Web服务类的实例,然后再尝试将它们连接到Web方法。有时您可以获得有关失败的更明确的信息,并查看序列化输出以确定元素可能未按预期序列化的位置。

这是一个可用于此的小测试方法:

    /// <summary>
    /// This method serializes objects to an XML string using the XmlSerializer
    /// </summary>
    /// <returns></returns>
    /// <remarks></remarks>
    public string SerializeObjectToXMLString(object theObject)
    {
        // Exceptions are handled by the caller

        using (System.IO.MemoryStream oStream = new System.IO.MemoryStream())
        {
            System.Xml.Serialization.XmlSerializer oSerializer = new System.Xml.Serialization.XmlSerializer(theObject.GetType());

            oSerializer.Serialize(oStream, theObject);

            return Encoding.Default.GetString(oStream.ToArray());
        }
    }