[.net] Please Help - webservices, soap, serialisation and webapplications

Started by
3 comments, last by paulecoyote 19 years, 1 month ago
Hi, I'm trying to serialise (serialize I guess in "US-English") an arraylist of across a data-store type object from the webservice to the webapplication. However I'm getting this error: Server was unable to process request. --> There was an error generating the XML document. --> The type uk.co.ds.xmldb.beans.IndexedXmlDocumentBean was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically. at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at SearchIndexedXmlDocuments(Int16 readAccessLevel, String searchQuery, Int32 maxHits, Object[]& indexedXmlDocumentBeanCollection, String& normalisedSearchQuery) in c:\inetpub\wwwroot\app\Web References\drmwebserviceref\Reference.cs:line 56 at search.Page_Load(Object sender, EventArgs e) in c:\inetpub\wwwroot\app\search\search.aspx.cs:line 42 If I change the WebMethod on the websercice to have an [SoapRpcMethod] attribute, the parameters all come across as null. I'm sure that transferring bean type things has been done many times, and I'm just stuck on something silly... so here's the source to the webservice method:

/// <summary>
		/// Searches all the indexed documents using query string from user, which is then parsed into SQL
		/// </summary>
		/// <param name="documentStream"></param>
		/// <returns>error message</returns>
		/// <remarks>[SoapRpcMethod]</remarks>
		[WebMethod()]
		//[SoapRpcMethod()]
		[SoapInclude( typeof(IndexedXmlDocumentBean )) ]
		public string SearchIndexedXmlDocuments( 
			short readAccessLevel,
			string searchQuery, 
			int maxHits,
			out ArrayList indexedXmlDocumentBeanCollection,
			out string normalisedSearchQuery
			)
		{
			normalisedSearchQuery=String.Empty;
			indexedXmlDocumentBeanCollection=null;			

			string message=String.Empty;

			DrmDirector theDrmDirector = Application["DrmDirector"] as DrmDirector;			
			
			if ( null==theDrmDirector )
			{
				message="DrmDirector not initalised";
			}
			else
			{
				message=theDrmDirector.TheDocumentManager.SearchIndexedXmlDocuments(
					readAccessLevel,
					searchQuery, 
					maxHits,
					out indexedXmlDocumentBeanCollection,
					out normalisedSearchQuery);
			}
			
			return message;
		}



... and the bean I'm trying to put across

using System;
using System.Collections;
using System.IO;
using System.Xml.Serialization;
using System.Xml;

namespace beans
{
	/// <summary>
	/// Summary description for IndexedXmlDocumentBean.
	/// </summary>
	[Serializable]
	[XmlRoot("NewIndexedXmlDocumentBean")]
	public class IndexedXmlDocumentBean
	{		
		public const string def_inXmlDocLastChanged = "now()";

		public const string COLNAME_inXmlDocId = "inxmldocid";
		public const string COLNAME_inXmlDocExternalId = "inxmldocexternalid";
		public const string COLNAME_inXmlDocRevisionNum  = "inxmldocrevisionnum";
		public const string COLNAME_classId  = "classid";
		public const string COLNAME_docCollectionId  = "doccollectionid";
		public const string COLNAME_inXmlDocFilename = "inxmldocfilename";
		public const string COLNAME_drmUserId  = "drmuserid";
		public const string COLNAME_inXmlDocReadAccessLevel  = "inxmldocreadaccesslevel";
		public const string COLNAME_inXmlDocWriteAccessLevel  = "inxmldocwriteaccesslevel";
		public const string COLNAME_inXmlDocLastChanged  = "inxmldoclastchanged";
		public const string COLNAME_inXmlDocPositionCount  = "inxmldocpositioncount";
		public const string COLNAME_inXmlDocChecksum  = "inxmldocchecksum";
		public const string COLNAME_inXmlDocFilesize  = "inxmldocfilesize";
		public const string COLNAME_inXmlDocViewCharge  = "inxmldocviewcharge";
		public const string COLNAME_inXmlDocLastAccessedTime  = "inxmldoclastaccessedtime";
		public const string COLNAME_inXmlDocLastAccessedDate  = "inxmldoclastaccesseddate";
		public const string COLNAME_inXmlDocAccessCount  = "inxmldocaccesscount";
		public const string COLNAME_inXmlDocAccessCountSinceDate  = "inxmldocaccesscountsincedate";
		public const string COLNAME_inXmlDocStatus = "inxmldocstatus";
		public const string COLNAME_inXmlDocComment  = "inxmldoccomment";
		public const string COLNAME_inXmlDocSummary  = "inxmldocsummary";


		protected int inXmlDocId = 0;
		protected string inXmlDocExternalId = String.Empty;
		protected int inXmlDocRevisionNum  = 0;
		protected int classId  = 0;
		protected int docCollectionId  = 0;
		protected string inXmlDocFilename = String.Empty;
		protected int drmUserId  = 0;
		protected short inXmlDocReadAccessLevel  = 0;
		protected short inXmlDocWriteAccessLevel  = 0;
		protected string inXmlDocLastChanged  = def_inXmlDocLastChanged;
		protected int inXmlDocPositionCount  = 0;
		protected string inXmlDocChecksum  = null;
		protected object inXmlDocFilesize  = null;		// (optional int) 
		protected object inXmlDocViewCharge  = null;		// (optional float) 
		protected string inXmlDocLastAccessedTime  = null; //(optional string) 
		protected string inXmlDocLastAccessedDate  = null; // (optional) 
		protected object inXmlDocAccessCount  = null; //(optional int) 
		protected string inXmlDocAccessCountSinceDate  = null;	// (optional) 
		protected object inXmlDocStatus = null;	//(optional short) 
		protected string inXmlDocComment  = null;	// (optional) 
		protected string inXmlDocSummary  = null;	// (optional) 


		/// <summary>
		/// True if the indexed document id is non-zero (thus identify something in the table)
		/// </summary>
		[XmlElement(DataType = "bool")]
		public bool HasPopulatedPrimaryKey
		{
			get
			{
				return (0!=inXmlDocId) ;
			}
		}



		/// <summary>
		/// Checks all fields required to give this bean full meaning. E.g. Foreign keys, etc.
		/// </summary>
		[XmlElement(DataType = "bool")]
		public bool HasPopulatedRequiredFields
		{
			get
			{
				return (
					(0!=inXmlDocId) &&
					(inXmlDocExternalId.Length>0) &&
					(0!=inXmlDocRevisionNum) &&
					(0!=classId ) &&
					(0!=docCollectionId ) &&					
					(0!=drmUserId) &&
					(0!=inXmlDocReadAccessLevel) &&
					(0!=inXmlDocWriteAccessLevel )					
					);
			}
		}



		[XmlElement(DataType = "int")]
		public int InXmlDocId
		{
			get
			{
				return inXmlDocId;
			}
			set
			{
				//TODO: Validation?
				inXmlDocId=value;
			}
		}


		[XmlElement(DataType = "string")]
		public string InXmlDocExternalId
		{
			get
			{
				return inXmlDocExternalId;
			}
			set
			{
				if (null==value)
				{					
					inXmlDocExternalId=String.Empty;
				}
				else
				{
					inXmlDocExternalId=value;
				}
			}
		}


		[XmlElement(DataType = "int")]
		public int InXmlDocRevisionNum
		{
			get
			{
				return inXmlDocRevisionNum;
			}
			set
			{
				//TODO: Validation?
				inXmlDocRevisionNum=value;
			}
		}


		[XmlElement(DataType = "int")]
		public int ClassId
		{
			get
			{
				return classId;
			}
			set
			{
				//TODO: Validation?
				classId=value;
			}
		}


		[XmlElement(DataType = "int")]
		public int DocCollectionId
		{
			get
			{
				return docCollectionId;
			}
			set
			{
				//TODO: Validation?
				docCollectionId=value;
			}
		}


		[XmlElement(DataType = "string")]
		public string InXmlDocFilename
		{
			get
			{
				return inXmlDocFilename;
			}
			set
			{
				if (null==inXmlDocFilename)
				{
					inXmlDocFilename=String.Empty;
				}
				else
				{
					inXmlDocFilename=value;
				}
			}
		}


		[XmlElement(DataType = "int")]
		public int DrmUserId
		{
			get
			{
				return drmUserId;
			}
			set
			{
				//TODO: Validation?
				drmUserId=value;
			}
		}


		[XmlElement(DataType = "short")]
		public short InXmlDocReadAccessLevel
		{
			get
			{
				return inXmlDocReadAccessLevel;
			}
			set
			{
				//TODO: Validation?
				inXmlDocReadAccessLevel=value;
			}
		}


		[XmlElement(DataType = "short")]
		public short InXmlDocWriteAccessLevel
		{
			get
			{
				return inXmlDocWriteAccessLevel;
			}
			set
			{
				//TODO: Validation?
				inXmlDocWriteAccessLevel=value;
			}
		}


		[XmlElement(DataType = "string")]
		public string InXmlDocLastChanged
		{
			get
			{
				return inXmlDocLastChanged;
			}
			set
			{
				if ((null==inXmlDocLastChanged) || (inXmlDocLastChanged.Length<1))
				{
					inXmlDocLastChanged=def_inXmlDocLastChanged;
				}
				else
				{
					inXmlDocLastChanged=value;
				}
			}
		}


		[XmlElement(DataType = "int")]
		public int InXmlDocPositionCount
		{
			get
			{
				return inXmlDocPositionCount;
			}
			set
			{
				//TODO: Validation?
				inXmlDocPositionCount=value;
			}
		}


		[XmlElement(DataType = "string")]
		public string InXmlDocChecksum
		{
			get
			{
				return inXmlDocChecksum;
			}
			set
			{
				//TODO: Validation?
				inXmlDocChecksum=value;
			}
		}


		[XmlElement(DataType = "int")]
		public object InXmlDocFilesize
		{
			get
			{
				return inXmlDocFilesize;				
			}
			set
			{
				//TODO: Validation?
				inXmlDocFilesize=value;
			}
		}


		[XmlElement(DataType = "float")]
		public object InXmlDocViewCharge
		{
			get
			{
				return inXmlDocViewCharge;
			}
			set
			{
				//TODO: Validation?
				inXmlDocViewCharge=value;
			}
		}


		[XmlElement(DataType = "string")]
		public string InXmlDocLastAccessedTime
		{
			get
			{
				return inXmlDocLastAccessedTime;
			}
			set
			{
				//TODO: Validation?
				inXmlDocLastAccessedTime=value;
			}
		}


		[XmlElement(DataType = "string")]
		public string InXmlDocLastAccessedDate
		{
			get
			{
				return inXmlDocLastAccessedDate;
			}
			set
			{
				//TODO: Validation?
				inXmlDocLastAccessedDate=value;
			}
		}


		[XmlElement(DataType = "int")]
		public object InXmlDocAccessCount
		{
			get
			{
				return inXmlDocAccessCount;
			}
			set
			{
				//TODO: Validation?
				inXmlDocAccessCount=value;
			}
		}


		[XmlElement(DataType = "string")]
		public string InXmlDocAccessCountSinceDate
		{
			get
			{
				return inXmlDocAccessCountSinceDate;
			}
			set
			{
				//TODO: Validation?
				inXmlDocAccessCountSinceDate=value;
			}
		}


		[XmlElement(DataType = "short")]
		public object InXmlDocStatus
		{
			get
			{
				return inXmlDocStatus;
			}
			set
			{
				//TODO: Validation?
				inXmlDocStatus=value;
			}
		}


		[XmlElement(DataType = "string")]
		public string InXmlDocComment
		{
			get
			{
				return inXmlDocComment;
			}
			set
			{
				//TODO: Validation?
				inXmlDocComment=value;
			}
		}


		[XmlElement(DataType = "string")]
		public string InXmlDocSummary
		{
			get
			{
				return inXmlDocSummary;
			}
			set
			{
				//TODO: Validation?
				inXmlDocSummary=value;
			}
		}





		public IndexedXmlDocumentBean()
		{
			//
			// TODO: Add constructor logic here
			//
		}



		public IndexedXmlDocumentBean(
			string inXmlDocExternalId, 
			int inXmlDocRevisionNum,
			int classId,
			int docCollectionId,
			string inXmlDocFilename,
			int drmUserId,
			short inXmlDocReadAccessLevel,
			short inXmlDocWriteAccessLevel,			
			string inXmlDocChecksum ,		// (optional) 
			object inXmlDocFilesize ,		// (optional int) 
			object inXmlDocViewCharge ,		// (optional float) 
			string inXmlDocLastAccessedTime	, //(optional string) 
			string inXmlDocLastAccessedDate , // (optional) 
			object inXmlDocAccessCount , //(optional int) 
			string inXmlDocAccessCountSinceDate ,	// (optional) 
			object inXmlDocStatus,	//(optional short) 
			string inXmlDocComment,
			string inXmlDocSummary
			)
		{
			//TODO: If any validation done in properties, should really use those instead.

			InXmlDocExternalId = inXmlDocExternalId;
			InXmlDocRevisionNum = inXmlDocRevisionNum;
			ClassId = classId;
			DocCollectionId = docCollectionId;
			InXmlDocFilename = inXmlDocFilename;
			DrmUserId = drmUserId;
			InXmlDocReadAccessLevel = inXmlDocReadAccessLevel;
			InXmlDocWriteAccessLevel = inXmlDocWriteAccessLevel;
			InXmlDocChecksum= inXmlDocChecksum;
			InXmlDocFilesize = inXmlDocFilesize ;
			InXmlDocViewCharge = inXmlDocViewCharge;
			InXmlDocLastAccessedTime	= inXmlDocLastAccessedTime;
			InXmlDocLastAccessedDate = inXmlDocLastAccessedDate ;
			InXmlDocAccessCount = inXmlDocAccessCount;
			InXmlDocAccessCountSinceDate = inXmlDocAccessCountSinceDate;
			InXmlDocStatus	= inXmlDocStatus;
			InXmlDocComment = inXmlDocComment;
			InXmlDocSummary = inXmlDocSummary;
		}


		public IndexedXmlDocumentBean(
			string inXmlDocExternalId, 
			int inXmlDocRevisionNum,
			int classId,
			int docCollectionId,
			string inXmlDocFilename,
			int drmUserId,
			short inXmlDocReadAccessLevel,
			short inXmlDocWriteAccessLevel
			):
			this(
				inXmlDocExternalId, inXmlDocRevisionNum, classId, docCollectionId,
				inXmlDocFilename, drmUserId, inXmlDocReadAccessLevel, inXmlDocWriteAccessLevel,	
            	null, null, null, null, 
				null, null, null,
				null, null, null
				)
		{
		}
		
	}
}




Any ideas would be helpful, specially from those whom have actually done this. I've [google]'ed for a while but found nothing concrete doing exactly what I'm trying to do. I've seen examples using public data members, but none using read-only properities, private & protected members, etc. Note that some things in the bean have to be "object" rather then short, int, or whatever because they represent a nullable optional field in a database. I expect one of you guys will probably see the solution straight away, I've been mucking about with it all afternoon and so far coming up blank. Thanks, Paul
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.
Advertisement
I don't know if it will help (I don't realy understand your code that well) but standard Serialization ONLY serializes fields that are read/write. When you want to serialize any other kind of data you will have to implement ISerializable (GetData and a special constructor).

Cheers
the read only property is just a IsValid type thing, it does not need to be serialised.
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.
Then you should just add a [NotSerizalized] attribute to the field.

Cheers
My problem was from not fully qualifying the parameter in the typeof() function.

However now I have a new problem... instead of having an array list of my Beans, I have an arraylist with arrays at each element of XmlElements that represent my object... that cannot be cast to my bean type.

When I try and mark my webmethod on the service side
[SoapRpcMethod] it compiles, but parameters are always null regardless of what is passed in. So the exact same code without it marked has, say, parameter "term" coming through with the value "arch". With SoapRpcMethod the parameter is null. Also any return / out values are null regardless of being set in the webmethod in the service.

Are there any decent tutorial sites that show a working example of a web application calling a webservice, with that webservice returning an arraylist of complex user defined types?

I've seen others have problems when using SoapRpcMethod but no solutions...
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.

This topic is closed to new replies.

Advertisement