3

I am creating a Web Service using ASP.NET C#. I am sending various data types from the webservice so I use the following structure.

public enum WS_ServiceResponseResult
{
    Success,
    Failure,
}
public class WS_ServiceResponse
{
    public WS_ServiceResponseResult result { get; set; }
    public object data { get; set; }
}

public class WS_User
{
    public long id{ get; set; }
    public string name{ get; set; }
}

Webservice Sample Method

    [WebMethod(EnableSession = true)]
    public WS_ServiceResponse LogIn(string username, string pasword)
    {
        WS_ServiceResponse osr = new WS_ServiceResponse();
        long userID = UserController.checkLogin(username, pasword);

        if (userID != 0)
        {
            osr.result = WS_ServiceResponseResult.Success;
            osr.data = new WS_User() { id = userID, name = username };
        }
        else
        {
            osr.result = WS_ServiceResponseResult.Failure;
            osr.data = "Invalid username/password!";
        }
        return osr;
    }

I am using two client types, javascript and C#.NET Windows Form. When I call from javascript I get no problem and the osr.data is filled with WS_User. So i can use osr.data.id easily. But when I use from C#.NET (proxy is generated using "Add Web Reference") I can successfully call but when the result arrives I get a Soap Exception

{System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.InvalidOperationException: There was an error generating the XML document. ... ...

What am I missing? I Guess object is not well defined and causing the problems. What are the workarounds?

Thanks

Maksud

Addition:

If add the following dummy method, then it works nicely. Hope it helps, to get the solution.

    [WebMethod]
    public WS_User Dummy()
    {
        return new WS_User();
    }
2
  • Do you generate proxy client for C#? Commented Oct 21, 2009 at 6:43
  • Yes. I used Add Web Reference to do that. If I return osr.data = "abcd";// that is object is data then I get no exception. I gets result= success and data="abcd"; But if I use WS_User object then I gets into trouble. Commented Oct 21, 2009 at 6:50

1 Answer 1

5

I had a similar Problem returning an "object" (multiple classes possible) Here is a sample code:

[Serializable()]
[XmlRoot(ElementName="Object")]
public sealed class XMLObject
{

    private Object _Object;

    [XmlElement(Type=typeof(App.Projekte.Projekt), ElementName="Projekt")]
    [XmlElement(Type=typeof(App.Projekte.Task), ElementName="Task")]
    [XmlElement(Type=typeof(App.Projekte.Mitarbeiter), ElementName="Mitarbeiter")]
    public Object Object
    {
        get
        {
            return _Object;
        }
        set
        {
            _Object = value;
        }
    }
}

I think you should change your code this way:

[XmlRoot(ElementName="ServiceResponse")]
public class WS_ServiceResponse
{
    public WS_ServiceResponseResult result { get; set; }

    [XmlElement(Type=typeof(WS_User), ElementName="WS_User")]
    [XmlElement(Type=typeof(string), ElementName="Text")]
    public object data { get; set; }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Your solution works perfectly. And if I needed some array then [XmlElement(Type=typeof(WS_User[]), ElementName="WS_User[]")] is also working. WoW.
Do we need change "public object data { get; set; }"
Although this solution works, my concern is that you would have to manually add XmlElement attributes as more primitive and referenced types use this object. Is there a cleaner approach to this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.