Morgan
Morgan

Reputation:

How to return an Object with an Object Property from a WCF Service?

I have a set of web service methods returning a ActionResult class holding the following properties:

object returnValue
bool success
string message

the returnValue is used to hold different types of return values depending on the web methods used.

The problem I have on the client is that if a web method is returning an internal class in the returnValue I can't cast it due to the client don't recognize the type.

I can fejk methods to be able to expose the class "Issue" I need.

Ex:

Issue ExposeIssueType()
{
    return null;
}

But isn't there any other way?

Upvotes: 1

Views: 1305

Answers (4)

John Saunders
John Saunders

Reputation: 161821

While I'm waiting for your answer to my comment, I'll tell you that this is a very bad web service design. Each web service operation should return the data it is meant to return. There is no point in creating a class that can hold all possible return values.

Additionally, you should not be using a string message to return errors from a web service. The SOAP protocol has a "SOAP Fault" mechanism for that purpose.

Since you're using WCF, you have complete support for SOAP Faults. Example:

In the service contract:

[FaultContract(typeof(GeneralFault))]
[OperationContract]
int Divide(int a, int b);

In the service:

public int Divide(int a, int b)
{
    if (b == 0)
    {
        throw new FaultException<GeneralFault>(
            new GeneralFault {Message = "Attempt to divide by zero"});
    }

    return a / b; // Note - operation can focus on its job
}

Data contract for the data returned in the fault:

[DataContract]
public class GeneralFault
{
    [DataMember]
    public string Message {get;set;}
}

Upvotes: 1

Sklivvz
Sklivvz

Reputation: 31163

You cannot use object in a webmethod signature because it is not simply serializable like you think. What you can do is use a generic type:

public class ActionResult<T>
{
  public T returnValue
  public bool success
  public string message
}

and then your webmethods should return ActionResult<Issue>


To address the concern to the comments and the (unjustified!) -1, run and invoke.

    [WebMethod]
    public object example()
    {
        return new foo
               {
                   bar = "bar",
                   baz = "baz"
               };
    }

    public class foo
    {
        public string bar { get; set; }
        public string baz { get; set; }
    }

result:

System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type Test+foo was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

In other words, you have to specify all the non-primitive types that can be returned -- which pretty much goes against what you are trying to achieve.

I have changed my original assertion about serializability.

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1063884

Having an object value is never a good idea on a web-service; when you have only xml (or similar), how can it stand a chance?

There are some sneaky tricks you might try with multiple subclasses; not sure if this is a good idea, though.

Upvotes: 0

Mitch Wheat
Mitch Wheat

Reputation: 300749

Create your type in a shared DLL (mark it as Serializable), reference both sides of the wire.

Upvotes: 0

Related Questions