RE: Problem returning container class with DataSet as object
- From: "J. Askey" <JAskey@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 27 Dec 2005 07:24:25 -0800
I did come up with a slight solution however, it is a 'hack' on the dataset
object. If anyone has any thoughts on a complete solution that may include
other classes, Im still open to suggestions.
Basically, since the dataset is just being returned as XML and strings to
work, I simply return an XML formatted string instead of a dataset. Such as...
DataSet ds = db.ExecuteDataSet(cmd);
MemoryStream stream = new MemoryStream();
ds.WriteXml(stream, XmlWriteMode.WriteSchema);
StreamReader reader = new StreamReader(stream);
stream.Position = 0;
resp.ReturnValue = reader.ReadToEnd();
The reason I use this more 'complex' code over ds.WriteXmlSchema is that on
the receiving end I still just want to use the simple ds.ReadXml which
expects XML formatted with ds.WriteXml.
"J. Askey" wrote:
> I am implementing a web service and thought it may be a good idea to return a
> more complex class (which I have called 'ServiceResponse') in order to wrap
> the original return value along with two other properties...
>
> bool error;
> string lastError;
>
> My whole class looks like this...
>
> using System;
> using System.Collections.Generic;
> using System.Text;
> using System.Runtime.Serialization;
>
> namespace My.WebServices
> {
> [Serializable]
> public class ServiceResponse
> {
> public bool error = false;
> public string lastError = "";
> public object returnObject = null;
>
> public ServiceResponse()
> {
>
> }
> }
> }
>
> A sample method on my WebService looks like...
>
> [WebMethod]
> public ServiceResponse Ping(string deviceId)
> {
> ServiceResponse resp = new ServiceResponse();
> if (IsValidDevice(deviceId))
> {
> resp.ReturnValue = true;
> }
> else
> {
> resp.Error = true;
> resp.LastError = DEVICE_UNKNOWN_ERROR;
> resp.ReturnValue = false;
> }
> return resp;
> }
>
> and a client side call looks like...
>
> My.WebServices.Service svc = new My.WebServices.Service();
> My.WebServices.ServiceResponse resp;
> resp = (My.WebServices.ServiceResponse)svc.Ping(deviceId);
> if (!resp.Error)
> {
> //do something
> }
>
> So, this works lovely... and solves my needs. However, if I have a web
> service method that returns a DataSet as an object in the ServiceResponse...
> such as...
>
> [WebMethod]
> public ServiceResponse GetUsers(string deviceId)
> {
> ServiceResponse resp = new ServiceResponse();
> if (IsValidDevice(deviceId))
> {
> try
> {
> string sql = "select * from [user] where enabled = 1";
> SqlCommand cmd = new SqlCommand(sql);
> SqlDatabase db = new SqlDatabase(CONNECTION_STRING);
> DataSet ds = db.ExecuteDataSet(cmd);
> resp.ReturnValue = ds;
> }
> catch (Exception ex)
> {
> resp.Error = true;
> resp.LastError = ex.Message;
> }
> }
> else
> {
> resp.Error = true;
> resp.LastError = DEVICE_UNKNOWN_ERROR;
> }
> return resp;
> }
>
> I get an error calling this method...
>
> System.InvalidOperationException: There was an error generating the XML
> document. ---> System.InvalidOperationException: The type System.Data.DataSet
> may not be used in this context. To use System.Data.DataSet as a parameter,
> return type, or member of a class or struct, the parameter, return type, or
> member must be declared as type System.Data.DataSet (it cannot be object).
> Objects of type System.Data.DataSet may not be used in un-typed collections,
> such as ArrayLists.
> at
> System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String
> name, String ns, Object o, Boolean xsiType)
> at
> Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
> at
> Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write2_ServiceResponse(String
> n, String ns, ServiceResponse o, Boolean isNullable, Boolean needType)
> at
> Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write4_ServiceResponse(Object o)
> at
> Microsoft.Xml.Serialization.GeneratedAssembly.ServiceResponseSerializer1.Serialize(Object objectToSerialize, XmlSerializationWriter writer)
> at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter,
> Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
> --- End of inner exception stack trace ---
> at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter,
> Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
> at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter
> textWriter, Object o)
> at System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse
> response, Stream outputStream, Object returnValue)
> at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[]
> returnValues, Stream outputStream)
> at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[]
> returnValues)
> at System.Web.Services.Protocols.WebServiceHandler.Invoke()
>
> I think I understand that the problem is because my
> ServiceResponse.ReturnValue is of type 'object', SOAP does not know how to
> format a complex type such as a DataSet?
>
> So, at this point, Im sort of at a loss on which direction to head. Here are
> the options that I see I have but Im not clear on which are best or even
> feasible.
>
> 1. Somehome make my ServiceResponse class serialize complex types manually
> by implementing the iSerializable interface?
> 2. Drop this return wrapper and use exceptions on the WebService side to
> throw errors and post messages.
> 3. Some other method that I have not though of??
>
> Thank you for any suggestions... Merry Christmas!
>
>
.
- References:
- Problem returning container class with DataSet as object
- From: J. Askey
- Problem returning container class with DataSet as object
- Prev by Date: Re: Many functions in one webservice page or multiple pages with fewer functions?
- Next by Date: Web Exceptions for SSL Sites
- Previous by thread: Problem returning container class with DataSet as object
- Next by thread: request format is unrecognized
- Index(es):
Relevant Pages
|