[Mono-list] Serializable object with Non-Serializable Fields -- > SerializationException

Jacek Rużyczka stacheldraht at interia.pl
Wed Jun 2 09:23:43 EDT 2010


Am Mittwoch 02 Juni 2010 14:46:07 schrieb Robert Jordan:
> Where are you setting this property? How is DBConnectionHandler
> implemented.
> 
This is the DBConnectionHandler:


using System;
using System.Data;
using System.Data.SqlTypes;
using Npgsql;

namespace iwawi.batchjobs
{
	
	/// <summary>
	/// The database connection handler used for batch jobs.
	/// </summary>
	public class DBConnectionHandler : ICloneable
	{
		public        readonly int    status   = 0;
		public static readonly string language = "DE";
		
		private IDbConnection conn;
		private DateTime      loginDate;
		private string        connectionString;
		private short         workstationID;
		private short         departmentID;
		private int           personID;
		private string        userName;
		private string        dbHostName;
		private string        dbInstanceName;
		private string        dbVersion;
		private string []     dbparams;
		
		private static ushort seq   = 1;
		private        ushort myseq = 1;
		
		/// <summary>
		/// Constructor
		/// </summary>
		///<param name="dbparams">Connection parameters</param>
		public DBConnectionHandler(String [] dbparams)
		{
			String hostname = "";
			this.dbparams = dbparams;
			connectionString = "Server=" + dbparams [0]
				+ "; Port=" + dbparams [1] +
				"; Database=" + dbparams [2]
				+ "; User ID=" + dbparams [3] +
				"; Password=" + dbparams [4] +
				"; Encoding=UNICODE; Sslmode=Prefer; SSL=True";

			    this.dbHostName = dbparams [0] + ":" + dbparams [1];
				this.dbInstanceName = dbparams [2];
				this.userName = dbparams [3];
			
			try {
				conn = new NpgsqlConnection (connectionString);
				hostname = Environment.GetEnvironmentVariable("HOSTNAME");
				if (hostname == null) hostname = 
Environment.GetEnvironmentVariable("COMPUTERNAME");
				
				hostname = hostname.ToLower();
				conn.Open();
				
				IDbCommand workstationCommand = conn.CreateCommand();
				workstationCommand.CommandText =
					"select workstation_id from workstations where lower (hostname) = \'"
					+ hostname + "\' and not_in_use = false;";
				IDataReader reader = workstationCommand.ExecuteReader();
				reader.Read();				
				workstationID = (Int16) reader ["workstation_id"];
				reader.Close();
				workstationCommand.Dispose();

				this.status = 2;
				
				IDbCommand userCommand = conn.CreateCommand();
				userCommand.CommandText =
					"select person_id, fk_department_id, now() as login_date, " + 
					"substring(version() for (position (',' in version())) - 1) as 
db_version"
					+ " from employees where username = \'"
					+ dbparams [3] + "\' and is_inactive = false;";
				reader = userCommand.ExecuteReader();
				reader.Read();				
				personID = (Int32) reader ["person_id"];
				departmentID = (Int16) reader ["fk_department_id"];
				loginDate = (DateTime) reader ["login_date"];
				dbVersion = (String) reader ["db_version"];
				reader.Close();
				userCommand.Dispose();
				
				this.status = 1;
				myseq = seq;
				seq++;
			}
			catch (NpgsqlException ex) {
				this.status = -1;
				Console.WriteLine(ex.Message);
				Console.WriteLine(ex.StackTrace);
			}
			
			/* If your client has not been registered in the "workstations" table, THIS 
will happen. */
			catch (InvalidOperationException ex) {
				String messageString;
				if (status == 2) {
					messageString = "Sie als Benutzer »" + dbparams [3] + "« sind nicht für 
den Zugriff auf iWAWI freigeschaltet.\n"
					+ "Bitte wenden Sie sich an Ihren Systemadministrator.";
				}
				else {
					messageString = "Ihr PC »" + hostname + "« ist nicht für den Zugriff auf 
iWAWI freigeschaltet.\n"
					+ "Bitte wenden Sie sich an Ihren Systemadministrator.";
				}

				this.status = -1;
				Console.WriteLine(messageString);
			}
		}
		
		/// <summary>
		/// Returns a ready-to-use database command object.
		/// </summary>
		/// <returns>
		/// A <see cref="IDbCommand"/>
		/// </returns>
		public IDbCommand CreateCommand ()
		{
			return this.conn.CreateCommand();
		}
		
		/// <summary>
		/// Creates a data adapter object containing the SQL statement given.
		/// </summary>
		/// <param name="commandText">
		/// The SQL statement <see cref="System.String"/>.
		/// </param>
		/// <returns>
		/// The ready-to-use <see cref="IDataAdapter"/>.
		/// </returns>
		public IDataAdapter CreateDataAdapter (string commandText)
		{
			return new NpgsqlDataAdapter(commandText, (NpgsqlConnection) this.conn);
		}
	}
}

This class, BTW, is set right after the PrintReceipt constructor has been 
called.

> Marking a class as [Serializable] and inheriting from MarshalByRefObject
> at the same time is usually a sign that you've got remoting wrong.
> 
I must admit that I got the skeleton of my class from some tutorial long time 
ago. But when I remove [Serializable], the PrintReceipt objects isn't created 
at all. And I suppose to know why: Right before the end of the code I define a 
callback event, so that PrintReceipt can call his "master" once it's ready.

> A class is either a MarshalByRefObject and it does not
> leave its AppDomain or [Serializable] which means that
> it will leave the AppDomain in its serialization form.
> 
The intention is that PrintReceipt will "live" on a remote server (it's a 
SingleCall object), and the client just requests its creation.

Kind regards
Jacek Rużyczka

----------------------------------------------------------------------
Wakacyjna przygoda czeka! Zgarnij nagrody za 18 000zl!
Sprawdz >>> http://linkint.pl/f2721



More information about the Mono-list mailing list