Reputation:
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
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
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
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
Reputation: 300749
Create your type in a shared DLL (mark it as Serializable), reference both sides of the wire.
Upvotes: 0