简体   繁体   English

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

[英]Passing object through a webservice with SOAP in C#

I'm working on a server-client application. 我正在研究服务器客户端应用程序。 The communication is done using webservice webmethods. 使用webservice web方法完成通信。 Both server and client are written in C#. 服务器和客户端都是用C#编写的。 I've been fighting with it for few days now but I couldn't solve it. 我已经和它斗争了几天,但我无法解决它。

I have problem to send complex classes through webservice - I tried many things so far but none of them work. 我在通过Web服务发送复杂的类时遇到了问题-到目前为止,我已经尝试了很多方法,但是没有一个起作用。

Each webmethod returns ServiceResult class which looks like this: 每个网络方法都返回如下的ServiceResult类:

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

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

ResultStatus is enum, ResultObject is actual returned value. ResultStatus是枚举,ResultObject是实际的返回值。 The problem came when I had tried to send complex classes through webservice. 当我试图通过webservice发送复杂的类时,问题出现了。

For example, I have abstract class Job, which has got private elements. 例如,我有抽象类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;
    [...]   
}

But when I try send class which inherits Job class (let's call it JobA) over webmethod I have errors. 但是,当我尝试通过网络方法发送继承Job类(称为JobA)的类时,出现了错误。 Because I have no explicit JobA return type in any webmethod, when I call my webmethod I get an error: 因为在任何Web方法中都没有显式的JobA返回类型,所以当我调用Web方法时会收到错误消息:

System.Web.Services.Protocols.SoapException: Server was unable to process request. System.Web.Services.Protocols.SoapException:服务器无法处理请求。 ---> System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException:生成XML文档时出错。 ---> System.InvalidOperationException: The type Job[] may not be used in this context. ---> System.InvalidOperationException:在此上下文中不能使用Job []类型。

That was about first error. 那是关于第一个错误。 Now there is another problem with different class, where error looks like this (again, when calling a webmethod): 现在不同类有另一个问题,其中错误看起来像这样(再次,当调用webmethod时):

System.Web.Services.Protocols.SoapException: Server was unable to process request. System.Web.Services.Protocols.SoapException:服务器无法处理请求。 ---> System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException:生成XML文档时出错。 ---> System.InvalidOperationException: The type was not expected. ---> System.InvalidOperationException:不期望该类型。 Use the XmlInclude or SoapInclude attribute to specify types that are not known statically. 使用XmlInclude或SoapInclude属性可以指定静态未知的类型。

When I add [SoapInclude(typeof(MyClass))] it has no difference, but using XmlInclude instead makes my ServiceResult.ResultObject array of XmlNodes. 当我添加[SoapInclude(typeof(MyClass))]时它没有区别,但是使用XmlInclude来生成我的ServiceResult.ResultObject XmlNodes数组。

I think both problems are about serialization but I don't know how to solve them. 我认为这两个问题都与序列化有关,但我不知道如何解决它们。 Basically, my question is: how should I pass custom objects from server to client through webmethod in such a way so I can use them as object (I'd like to cast this ServiceResult.ResultObject to class and use it like an casual instance of that class)? 基本上,我的问题是:如何通过webmethod以如此方式将自定义对象从服务器传递到客户端,以便我可以将它们用作对象(我想将此ServiceResult.ResultObject强制转换为类并将其用作偶然的实例那个班)? What is the best way to do that? 最好的方法是什么?

Could anyone suggest any solution for it? 有人可以提出任何解决方案吗?

Based on the initial error message, it sounds like you may have a property that is an array or collection of Job in the class you are trying to serialize, which will cause the exception that you are seeing. 基于初始错误消息,听起来您可能在您尝试序列化的类中有一个属性是Job的数组或集合,这将导致您看到的异常。

If this property is not supposed to be serialized, then you can decorate it with the XmlIgnore attribute. 如果不应该序列化此属性,则可以使用XmlIgnore属性对其进行装饰。

Also, when I am trying to debug issues with web service serialization, what I generally do is use XmlSerializer to serialize instances of my web service classes before trying to hook them up to web methods. 此外,当我尝试调试Web服务序列化的问题时,我通常使用XmlSerializer来序列化我的Web服务类的实例,然后再尝试将它们连接到Web方法。 Sometimes you can get more explicit information on what failed and see the serialized output to determine where elements might not be serialized as you expect them to be. 有时,您可以获得有关失败原因的更明确的信息,并查看序列化的输出,以确定元素可能未按预期序列化的位置。

Here is a little test method that you can use for this: 这是一个可用于此的小测试方法:

    /// <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());
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM