简体   繁体   中英

Passing object through a webservice with SOAP in C#

I'm working on a server-client application. The communication is done using webservice webmethods. Both server and client are written in 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.

Each webmethod returns ServiceResult class which looks like this:

    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. The problem came when I had tried to send complex classes through webservice.

For example, I have abstract class Job, which has got private elements.

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. Because I have no explicit JobA return type in any webmethod, when I call my webmethod I get an error:

System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type Job[] may not be used in this context.

That was about first error. Now there is another problem with different class, where error looks like this (again, when calling a webmethod):

System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

When I add [SoapInclude(typeof(MyClass))] it has no difference, but using XmlInclude instead makes my ServiceResult.ResultObject array of 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)? 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.

If this property is not supposed to be serialized, then you can decorate it with the XmlIgnore attribute.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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