我正在研究服务器客户端应用程序。使用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强制转换为类并将其用作临时实例那个班)?最好的方法是什么?
有人可以建议任何解决方案吗?
答案 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());
}
}