How do you XMLSerialize a more complex class in c#? - c#

hello I want to serialize a class in C# with a XMLserializer. The Compiler says that Room (myClass) is not primitive (i am using Unity3d) and therefor can not be serialized. The problem is that the most Tutorial are only for simple classes with a few simple fields. Can you help me changs Room to be serializable?
[Serializable]
public class Room
{
public Room()
{
m_id = "test";
m_section = Areas.PublicSec;
m_connections = null;
m_size = 10;
}
public Room(string _id, Areas _section, List<string> _connections, int _size)
{
// f.e. Bathroom
m_id = _id;
// private, public or hallway filled with the enum Areas
m_section = _section;
// list of rooms that have or will have a Connection
if (_connections != null)
{
m_connections = _connections;
}
else
{
m_connections = new List<string>();
}
//? Desired minium size of the room
m_size = _size;
}
private string m_id;
public string id
{
get { return m_id; }
set { m_id = value;}
}
private Areas m_section;
public Areas Section
{
get { return m_section; }
set { m_section = value; }
}
private List<string> m_connections;
[XmlArray("m_connections")]
public List<string> Connections
{
get { return m_connections; }
set { m_connections = value; }
}
private int m_size;
public int Size
{
get { return m_size; }
set { m_size = value; }
}
}
My XMLSerializer works with simple classes but not with this one.

Related

I dont understand the error.. I think as far as I know there is a dataType, but I dont see how?

In the code below I hope that I specify correctly whats wrong. I need to be able to call item.departments.dept_Type and that should be possible because of the association that I have made. I don't need to create inner joins on a query to get the data if I understand correctly.
This is my PersonClass
namespace DATALAYER.DataHandler
{
[Table(Name = "People")]
public class Person
{
private int _DepartmentID;
public EntityRef<Department> _Department;
public Person() { this._Department = new EntityRef<Department>(); }
private int _ID;
[Column(IsPrimaryKey =true, Storage ="_ID")]
public int ID
{
get { return this._ID; }
set { this._ID = value; }
}
private string _p_FirstName;
[Column(Storage = "_p_FirstName")]
public string p_FirstName
{
get { return this._p_FirstName; }
set { this._p_FirstName = value; }
}
private string _LastName;
[Column(Storage = "_LastName")]
public string p_LastName
{
get { return this._LastName; }
set { this._LastName = value; }
}
private string _EmailAddress;
[Column(Storage = "_EmailAddress")]
public string p_EmailAddress
{
get { return this._EmailAddress; }
set { this._EmailAddress = value; }
}
private string _Password;
[Column(Storage = "_Password")]
public string p_Password
{
get { return this._Password; }
set { this._Password = value; }
}
private string _SSID;
[Column(Storage = "_SSID")]
public string p_SSID
{
get { return this._SSID; }
set { this._SSID = value; }
}
private string _DOB;
[Column(Storage = "_DOB")]
public string p_DOB
{
get { return this._DOB; }
set { this._DOB = value; }
}
private string _CellNumber;
[Column(Storage = "_CellNumber")]
public string p_CellNumber
{
get { return this._CellNumber; }
set { this._CellNumber = value; }
}
[Column(Storage = "_DepartmentID", DbType = "Int")]
public int p_Department_dept_ID
{
get { return this._DepartmentID; }
set { this._DepartmentID = value; }
}
[Association(Storage = "_DepartmentID", ThisKey = "p_Department_dept_ID")]
public Department Department
{
get { return this._Department.Entity; }
set { this._Department.Entity = value; }
}
}
}
This is my Department code
namespace DATALAYER.DataHandler
{
[Table(Name = "Departments")]
public class Department
{
//private EntitySet<Person> _Person;
//public Department()
//{
// this._Person = new EntitySet<Person>();
//}
private int _DepartmentID;
[Column(IsPrimaryKey = true, Storage = "_DepartmentID")]
public int dept_ID
{
get { return this._DepartmentID; }
set { this._DepartmentID = value; }
}
private string _deptType;
[Column(Storage = "_deptType")]
public string dept_Type
{
get { return this._deptType; }
set { this._deptType = value; }
}
//[Association(Storage = "_Person", OtherKey = "ID")]
//public EntitySet<Person> Persons
//{
// get { return this._Person; }
// set { this._Person.Assign(value); }
//}
}
}
Now the problem I'm thinking is that there is a problem with datatypes between the primary key of the person and a foreign key the departments. But Since they are both int I don't see how that can be a problem.
If someone can just explain my problem to cleary if Im wrong or something or help me with a solution pls.
Added this class
namespace DATALAYER.DataHandler
{
public class SHSdb2 : DataContext
{
public Table<Person> People;
public Table<Department> Department;
//public Table<Address> Address;
public SHSdb2(string connection) : base(connection) { }
}
}
Person table
Department table
Without this code it works but then I can only call stuff inside the table
[Column(Storage = "_DepartmentID", DbType = "Int")]
public int p_Department_dept_ID
{
get { return this._DepartmentID; }
set { this._DepartmentID = value; }
}
[Association(Storage = "_DepartmentID", ThisKey = "p_Department_dept_ID")]
public Department Department
{
get { return this._Department.Entity; }
set { this._Department.Entity = value; }
}
Seems like I fixed it with this not sure if its a fix or I just lucky if someone can still maybe explain this to me it would be much appreciated.
var personQuery =
from per in db.People
where per.p_FirstName == "Christian"
select per.Department;
I'm thinking by specifying that it needs to get the data from department it would allow it in the foreach.

Custom Collection/List To Store Custom Objects

I have a customer object class:
public class customerObject
{
private string _address1;
private string _address2;
private string _address3;
private string _category;
private string _country;
private string _county;
private string _custcode;
private string _fullname;
private string _int_rep_hou;
private string _int_rep_key;
private double _lat;
private double _lng;
private string _postcode;
private string _rep_code;
private string _telephone;
public customerObject()
{
}
public string Address1
{
get { return _address1; }
set { _address1 = value; }
}
public string Address2
{
get
{
return _address2;
}
set { _address2 = value; }
}
public string Address3 { get { return _address3; } set { _address3 = value; } }
public string Category
{
get { return _category; }
set { _category = value; }
}
public string Country { get { return _country; } set { _country = value; } }
public string County { get { return _county; } set { _county = value; } }
public string Custcode
{
get { return _custcode; }
set { _custcode = value; }
}
public string Fullname
{
get { return _fullname; }
set { _fullname = value; }
}
public string Int_rep_hou
{
get { return _int_rep_hou; }
set { _int_rep_hou = value; }
}
public string Int_rep_key
{
get { return _int_rep_key; }
set { _int_rep_key = value; }
}
public double Lat { get { return _lat; } set { _lat = value; } }
public double Lng { get { return _lng; } set { _lng = value; } }
public string Postcode { get { return _postcode; } set { _postcode = value; } }
public string Rep_code
{
get { return _rep_code; }
set { Rep_code = value; }
}
public string Telephone { get { return _telephone; } set { _telephone = value; }
}
}
I have a CustomCollections class
public class CustomerCollection
{
public List<customerObject> Customers { get; set; }
}
My method that loops through dt rows and converts to a customer object
public List<Valueobjects.CustomerCollection> dolist(DataTable temptablename)
{
//Create Collection Object
Valueobjects.CustomerCollection Collection = new Valueobjects.CustomerCollection();
foreach (DataRow row in temptablename.Rows)
{
//Create Customer Object
Valueobjects.customerObject Customer = new Valueobjects.customerObject();
//set values of customer object
Customer.Rep_code = "";
Customer.Int_rep_key = "";
Customer.Int_rep_hou = "";
Customer.Fullname = row["Fullname"].ToString().Trim();
Customer.Custcode = row["Custcode"].ToString().Trim();
Customer.Category = row["Category"].ToString().Trim();
Customer.Address1 = row["Address1"].ToString().Trim();
Customer.Address2 = row["Address2"].ToString().Trim();
Customer.Address3 = row["Address3"].ToString().Trim();
Customer.Postcode = row["Postcode"].ToString().Trim();
Customer.Country = row["Country"].ToString().Trim();
Customer.Telephone = row["Telephone"].ToString().Trim();
Customer.Lat = Convert.ToDouble(row["Lat"]);
Customer.Lng = Convert.ToDouble(row["Lng"]);
Customer.County = row["County"].ToString().Trim();
//add to the collection (list)
Collection.Customers.Add(Customer);
}
temptablename = null;
return Collection;
}
However when I create a new Customer object and a new CustomerCollection object I am getting an error when adding the customer to the collection list.
Error:
Error 32 Cannot implicitly convert type
'Classes.Valueobjects.CustomerCollection' to
'System.Collections.Generic.List'
Your method is returning a List<CustomerCollection>:
public List<Valueobjects.CustomerCollection> dolist(DataTable temptablename)
{
//...
}
But the code is trying to return a CustomerCollection:
return Collection;
Just as the error says, these two types are different.
If a CustomerCollection is already a collection of customers, then semantically what is a List<Valueobjects.CustomerCollection>? A collection of collections? It seems like you're over-pluralizing your objects :)
There are two approaches here. Either return a CustomerCollection from the method:
public CustomerCollection dolist(DataTable temptablename)
{
//...
}
Or use a List<Customer> if you want to use generic lists as your collection containers:
public List<Customer> dolist(DataTable temptablename)
{
//...
var Collection = new List<Customer>();
//...
Collection.Add(Customer);
//...
return Collection;
}
Side note: You may want to stick to C# conventions for variable naming. As you can see from the code highlighting here on Stack Overflow, your variable names can easily be mistaken for classes/types, which can cause confusion when supporting the code.
Return a CustomerCollection instead of a List<Valueobjects.CustomerCollection>:
public Valueobjects.CustomerCollection Dolist(DataTable temptablename)
{
// ...
Your object has a list, it is not a list.
MSDN: Inheritance

How to use the Same Class on Client as on the Service?

How can I pass an entire defined class through a WCF service? I have the class defined on both the service and client side. I keep getting an error:
Best overloaded method match has some invalid arguments.
The whole class was copied from the client-side to the service-side.
Client side calling:
TransferProxy.PutTransferOnService(Transfer);
Defined on service:
[OperationContract]
bool PutTransferOnService(TypeTransfer Transfer);
I don't want to access individual items on the class from the client, I just want to move the WHOLE populated object through and do processing on the server side.
[DataContract]
public class TypeTransfer
{
private string userID;
private string transferNum;
private DateTime effectiveDate;
private int unitCount;
private int skuCount;
private string reason;
private string localStatus;
private string destStatus;
private string carrier;
private string sourceStore;
private string destinationStore;
private string inSeal;
private string outSeal;
[DataMember]
private List<TypeSOQ> correspondingSOQ = new List<TypeSOQ>();
[DataMember]
private List<TypeProductList> ProductList = new List<TypeProductList>();
public TypeTransfer() { }
// Function adds single item to transfer object
public void AddItem(int ProductID, string SKU, string PrimarySKU, string SCC, string ProductDescription, int TransferQty)
{
ProductList.Add(new TypeProductList
{
productID = ProductID,
sku = SKU,
primaryUPC = PrimarySKU,
scc = SCC,
description = ProductDescription,
transferQty = TransferQty
});
}
// Add SOQ to transfer object (can support multiple SOQ's)
public void AddSOQ(TypeSOQ soq)
{
correspondingSOQ.Add(soq);
}
// Function returns number of skus in Product List
public int GetSKUTotal()
{
return ProductList.Count();
}
// Function returns total number of items in transfer
public int GetItemTotal()
{
int itemtotal = 0;
for (int i = 0; i < ProductList.Count(); i++)
{
itemtotal += ProductList[i].transferQty;
}
return itemtotal;
}
// Return entire SOQ list
public List<TypeSOQ> GetSOQs()
{
return correspondingSOQ;
}
// Returns full product list in transfer object
public List<TypeProductList> GetProductList()
{
return ProductList;
}
[DataMember]
public string UserID
{
get { return userID; }
set { userID = value; }
}
[DataMember]
public string TransferNum
{
get { return transferNum; }
set { transferNum = value; }
}
[DataMember]
public DateTime EffectiveDate
{
get { return effectiveDate; }
set { effectiveDate = value; }
}
[DataMember]
public int UnitCount
{
get { return unitCount; }
set { unitCount = value; }
}
[DataMember]
public string Reason
{
get { return reason; }
set { reason = value; }
}
[DataMember]
public string LocalStatus
{
get { return localStatus; }
set { localStatus = value; }
}
[DataMember]
public string DestStatus
{
get { return destStatus; }
set { destStatus = value; }
}
[DataMember]
public string Carrier
{
get { return carrier; }
set { carrier = value; }
}
[DataMember]
public string SourceStore
{
get { return sourceStore; }
set { sourceStore = value; }
}
[DataMember]
public string DestStore
{
get { return destinationStore; }
set { destinationStore = value; }
}
[DataMember]
public string InSeal
{
get { return inSeal; }
set { inSeal = value; }
}
[DataMember]
public string OutSeal
{
get { return outSeal; }
set { outSeal = value; }
}
[DataMember]
public int SKUCount
{
get { return skuCount; }
set { skuCount = value; }
}
}
You said - The whole class was copied from the client-side to the service-side.
You don't need to copy your class to server side. just define your class in a separate library and give reference of that same library to both client and server.

How can the attributes of outer class can be accesed within the inner class in Composition Classes design?

I am totally unable to access the outer class attributes inside the inner class ...
even if i make object of outer class,, in inner class*which makes no sense in composition design* .. even then i cant access them ..
is there a way by which i can access these outer class attributes ?
Scenario is that there is some sports car which is constructed only if the customers who want to buy it exists! ..
namespace composition{
public class CustomCar
{
#region Attributes
private string name;
private string plateno;
private double cost;
private CarCustomer _customer = new CarCustomer();
#endregion
#region properties
public string Name
{
get { return name; }
set { name = value; }
}
public double Cost
{
get { return cost; }
set { cost = value; }
}
public string PlateNo
{
get { return plateno; }
set { plateno = value; }
}
public CarCustomer Customer
{
get { return _customer; }
set { _customer = value; }
}
#endregion
#region methods
public CustomCar()
{
Console.WriteLine("I am in custom car");
}
public CustomCar(string s1, string pno, double c, string s2, double n, double bc)
{
this.Name = s1;
this.PlateNo = pno;
this.Cost = c;
this.Customer.Name1 = s2;
this.Customer.Nic1 = n;
this.Customer.BargainCost = bc;
}
public double finalCost()
{
if (this.Customer.BargainCost < 10000)
{
double FinalCost = (this.Cost - this.Customer.BargainCost);
return FinalCost;
}
else
{
return this.Cost;
}
}
public void show()
{
Console.WriteLine(this.name + this.PlateNo + this.Customer.Name1 + this.Customer.Nic1);
}
#endregion
public class CarCustomer
{
private string name1;
private double Nic;
private double bargainCost;
public double BargainCost
{
get { return bargainCost; }
set { bargainCost = value; }
}
public double Nic1
{
get { return Nic; }
set { Nic = value; }
}
public string Name1
{
get { return name1; }
set { name1 = value; }
}
public CarCustomer()
{
Console.WriteLine("I have a customer");
}
public CarCustomer(string n1, double i1, double bc)
{
this.Name1 = n1;
this.Nic = i1;
this.BargainCost = bc;
}
public void showCustomer()
{
Console.WriteLine("Customer name: " + Name1);
Console.WriteLine("Customer NIC: " + Nic1);
}
}
}
}
There is nothing stopping you having a reference in the CarCustomer to the CustomCar object as well. This would then give you a one to one reference between the object. Were you instaiate this object is up to you in the Constructor of the CustomCar
public CustomCar(arguments)
{
this.Customer.CustomCar = this;
}
Or you could set it in the sets on the property accessors up to you. Try this
public class CustomCar
{
private string name;
private string plateno;
private double cost;
private CarCustomer _customer = new CarCustomer();
public string Name
{
get { return name; }
set { name = value; }
}
public double Cost
{
get { return cost; }
set { cost = value; }
}
public string PlateNo
{
get { return plateno; }
set { plateno = value; }
}
public CarCustomer Customer
{
get { return _customer; }
set { _customer = value; }
}
public CustomCar()
{
Console.WriteLine("I am in custom car");
}
public CustomCar(string name, string pno, double c, string customerName, double n, double bc)
{
this.Name = name;
this.PlateNo = pno;
this.Cost = c;
this.Customer.Name1 = customerName;
this.Customer.Nic1 = n;
this.Customer.BargainCost = bc;
this.Customer.Car = this;
}
public double finalCost()
{
if (this.Customer.BargainCost < 10000)
{
double FinalCost = (this.Cost - this.Customer.BargainCost);
return FinalCost;
}
else
{
return this.Cost;
}
}
public void show()
{
Console.WriteLine(this.name + this.PlateNo + this.Customer.Name1 + this.Customer.Nic1);
}
}
public class CarCustomer
{
private string name1;
private double Nic;
private double bargainCost;
private CustomCar customer;
public double BargainCost
{
get { return bargainCost; }
set { bargainCost = value; }
}
public double Nic1
{
get { return Nic; }
set { Nic = value; }
}
public string Name1
{
get { return name1; }
set { name1 = value; }
}
public CustomCar Car
{
get{return customer;}
set{customer = value;}
}
public CarCustomer()
{
Console.WriteLine("I have a customer");
}
public CarCustomer(string n1, double i1, double bc)
{
this.Name1 = n1;
this.Nic = i1;
this.BargainCost = bc;
}
public void showCustomer()
{
Console.WriteLine("Customer name: " + Name1);
Console.WriteLine("Customer NIC: " + Nic1);
}
}
Of course you can't access them. You've set their protection level to private. In order to get at them from an external resource their protection level has to be in line with the access level needed. In this case you should be able to change the modifier to protected and be able to access them.
However, looking at your class design, I think you would be better served using the automatic getter/setter syntax. You aren't doing anything particularly special in your property definitions, so it would make sense to get rid of the private variables and change your properties to this:
public string Name { get; set; }
public double Cost { get; set; }
public string PlateNo { get; set; }
public CarCustomer Customer { get; set; }
You'll still have public access to the variables through the properties and you won't have all the messiness of the extra variables.

Errors: How to save a many-to-many relationship in Castle Active Record?

I've been trying for hours to get many-to-many relationship to save with Castle ActiveRecord. What am I doing wrong? I can't find anything in the documentation or on google. There is data in the database.
Courses have a many to many relationship with Books.
Test code.
Database.Course c = new Database.Course();
c.Number = "CS 433";
c.Name = "Databases";
c.Size = 34;
c.Books = Database.Book.FindAll();
c.Save();
Also doesn't work
foreach(Database.Book b in Database.Book.FindAll()){
c.Books.Add(b);
}
Database Classes
[ActiveRecord]
public class Course : ActiveRecordValidationBase<Course>
{
private int? id;
private string number;
private string name;
private string description;
private int size; //number of students in class
//references
private IList books = new ArrayList();
public override string ToString()
{
return FormattedName;
}
public string FormattedName
{
get
{
return string.Format("{0} - {1}", Number, Name);
}
}
[PrimaryKey]
public int? Id
{
get { return id; }
set { id = value; }
}
[Property, ValidateNonEmpty]
public string Number
{
get { return number; }
set { number = value; }
}
[Property, ValidateNonEmpty]
public string Name
{
get { return name; }
set { name = value; }
}
[Property(ColumnType="StringClob")]
public string Description
{
get { return description; }
set { description = value; }
}
[Property]
public int Size
{
get { return size; }
set { size = value; }
}
[HasAndBelongsToMany(typeof(Book),
Table = "BookCourse", ColumnKey = "course_id", ColumnRef = "book_id", Inverse = true)]
public IList Books
{
get { return books; }
set { books = value; }
}
}
[ActiveRecord]
public class Book : ActiveRecordValidationBase<Book>
{
private int? id;
private string title;
private string edition;
private string isbn;
private bool is_available_for_order;
//relations
private IList authors = new ArrayList();
private IList bookordercount = new ArrayList();
private IList courses = new ArrayList();
private Inventory inventory;
public override string ToString()
{
return FormattedName;
}
public string FormattedName
{
//*
get {
string str;
if (Edition == null || Edition == "")
str = Title;
else
str = string.Format("{0} ({1})", Title, Edition);
if (Authors.Count != 0)
{
return string.Format("{0} by {1}", str, FormattedAuthors);
}
else
{
return str;
}
}
/*/
get
{
return Title;
}
//*/
}
public string FormattedAuthors
{
get
{
if (Authors.Count == 0) return "";
StringBuilder sb = new StringBuilder();
int i = 0, end = Authors.Count;
foreach (Author a in Authors)
{
i++;
sb.Append(a.FormattedName);
if (i != end) sb.Append("; ");
}
return sb.ToString();
}
}
[PrimaryKey]
public int? Id
{
get { return id; }
set { id = value; }
}
[Property, ValidateNonEmpty]
public string Title
{
get { return title; }
set { title = value; }
}
[Property]
public string Edition
{
get { return edition; }
set { edition = value; }
}
[Property, ValidateNonEmpty]
public string Isbn
{
get { return isbn; }
set { isbn = value; }
}
[Property]
public bool IsAvailableForOrder
{
get { return is_available_for_order; }
set { is_available_for_order = value; }
}
//relations
[HasAndBelongsToMany(typeof(Author),
Table = "BookAuthor", ColumnKey = "book_id", ColumnRef = "author_id")]
public IList Authors
{
get { return authors; }
set { authors = value; }
}
[HasMany(typeof(BookOrderCount), Table = "BookOrderCounts", ColumnKey = "BookId")]
public IList BookOrderCount
{
get { return bookordercount; }
set { bookordercount = value; }
}
[HasAndBelongsToMany(typeof(Course),
Table = "BookCourse", ColumnKey = "book_id", ColumnRef = "course_id")]
public IList Courses
{
get { return courses; }
set { courses = value; }
}
[OneToOne]
public Inventory Inventory
{
get { return inventory; }
set { inventory = value; }
}
}
Make sure you put the Inverse = true where you want it. From the Castle AR docs,
It is wise to choose one side of the
relation as the owner. The other side,
the non-writable, need to use
Inverse=true.
Put the Inverse = true on the other side of the relationship, like this:
[HasAndBelongsToMany(typeof(Book),
Table = "BookCourse", ColumnKey = "course_id", ColumnRef = "book_id")]
public IList<Book> Books
[HasAndBelongsToMany(typeof(Course),
Table = "BookCourse", ColumnKey = "book_id", ColumnRef = "course_id", Inverse = true)]
public IList<Course> Courses
You also have to add attributes to the top of both classes - at the moment they don't know what tables they're mapped to. Currently you have this:
public class Course : ActiveRecordBase<Course>
Add this (where "course" is the name of your Course table):
[ActiveRecord("course")]
public class Course : ActiveRecordBase<Course>

Categories