I have one class Person and it has some public properties . Now I want to serialize person class but with some selected properties only. This can be achieve by making that property private but I don't want to change any property as private.
If its not possible using serialisation then, what is another way to create xml doc for object with selected properties only.
Note: All properties must be public.
class Program
{
static void Main(string[] args)
{
Person person = new Person();
using (MemoryStream memoryStream = new MemoryStream())
{
XmlSerializer xmlSerializer = new XmlSerializer(person.GetType());
xmlSerializer.Serialize(memoryStream, person);
using (FileStream fileStream = File.Create("C://Output.xml"))
{
memoryStream.WriteTo(fileStream);
fileStream.Close();
}
memoryStream.Close();
}
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public double Salary { get; set; }
public Person()
{
Id = 1;
Name = "Sam";
Salary = 50000.00;
}
}
Current Output
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Id>1</Id>
<Name>Sam</Name>
<Salary>50000</Salary>
</Person>
Expected Output
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Salary>50000</Salary>
</Person>
You could use an XmlIgnore attribute..
public class Person
{
[XmlIgnore]
public int Id { get; set; }
[XmlIgnore]
public string Name { get; set; }
public double Salary { get; set; }
public Person()
{
Id = 1;
Name = "Sam";
Salary = 50000.00;
}
}
See this
can you give a try to below code and just use XmlIgnore attribute on he properties which you not require :-
[XmlIgnore]
public int Id { get; set; }
[XmlIgnore]
public string Name { get; set; }
public double Salary { get; set; }
Related
I have this class:
[XmlRoot(ElementName ="Lesson")]
public class LessonOld
{
public LessonOld()
{
Students = new List<string>();
}
public string Name { get; set; }
public DateTime FirstLessonDate { get; set; }
public int DurationInMinutes { get; set; }
public List<string> Students { get; set; }
}
And I'm using this code to serialize it:
TextWriter writer = new StreamWriter(Path.Combine(UserSettings, "Lessons-temp.xml"));
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<LessonOld>));
xmlSerializer.Serialize(writer, tempList);
writer.Close();
(Note that that is a List<LessonOld>)
Here is my resulting XML:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfLessonOld xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<LessonOld>
<FirstLessonDate>0001-01-01T00:00:00</FirstLessonDate>
<DurationInMinutes>0</DurationInMinutes>
<Students />
</LessonOld>
</ArrayOfLessonOld>
I would like to change it to serialize as <ArrayOfLesson and <Lesson> for the XML elements. Is this possible? (As you can see, I've already tried using [XmlRoot(ElementName ="Lesson")])
You're almost there. Use:
[XmlType(TypeName = "Lesson")]
instead of
[XmlRoot(ElementName = "Lesson")]
Of course you can test it easily; your code with the above change
[XmlType(TypeName = "Lesson")]
public class LessonOld
{
public LessonOld()
{
Students = new List<string>();
}
public string Name { get; set; }
public DateTime FirstLessonDate { get; set; }
public int DurationInMinutes { get; set; }
public List<string> Students { get; set; }
}
class Program
{
static void Main(string[] args)
{
TextWriter writer = new StreamWriter(Path.Combine(#"C:\Users\Francesco\Desktop\nanovg", "Lessons-temp.xml"));
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<LessonOld>));
xmlSerializer.Serialize(writer, new List<LessonOld> { new LessonOld() { Name = "name", DurationInMinutes = 0 } });
writer.Close();
}
}
produces this
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfLesson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Lesson>
<Name>name</Name>
<FirstLessonDate>0001-01-01T00:00:00</FirstLessonDate>
<DurationInMinutes>0</DurationInMinutes>
<Students />
</Lesson>
</ArrayOfLesson>
As I've seen it, XmlRoot works fine when you want to serialize a single object.
Consider this code, derived from yours:
[XmlRoot(ElementName = "Lesson")]
public class LessonOld
{
public LessonOld()
{
Students = new List<string>();
}
public string Name { get; set; }
public DateTime FirstLessonDate { get; set; }
public int DurationInMinutes { get; set; }
public List<string> Students { get; set; }
}
class Program
{
static void Main(string[] args)
{
TextWriter writer = new StreamWriter(Path.Combine(#"C:\Users\Francesco\Desktop\nanovg", "Lessons-temp.xml"));
XmlSerializer xmlSerializer = new XmlSerializer(typeof(LessonOld));
xmlSerializer.Serialize(writer, new LessonOld() { Name = "name", DurationInMinutes = 0 });
writer.Close();
}
}
It will output
<?xml version="1.0" encoding="utf-8"?>
<Lesson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>name</Name>
<FirstLessonDate>0001-01-01T00:00:00</FirstLessonDate>
<DurationInMinutes>0</DurationInMinutes>
<Students />
</Lesson>
I want to convert a c# class to an xml file without declaring default values in it. If I declare values on every propery in the class I got it to work and the XML has all the properties in it. The primarydata is my class with properties in it.
var pD = new PrimaryData();
XmlSerializer serializerPrimaryData = new XmlSerializer(typeof(PrimaryData));
serializerPrimaryData.Serialize(File.Create(xmlLocation), pD,ns);
But I dont want to declare any values.
If i run this code I get just:
<?xml version="1.0"?>
<PrimaryData />
I don't get the properties in the class as you can see. So how can I get the properties in the class without declaring them to a default value?
Any suggestions?
I have followed this guide: https://codehandbook.org/c-object-xml/
But he is declaring default values to his class.
public class PrimaryData
{
public PrimaryData();
public string BatchId { get; set; }
public CurrentOperation CurrentOperation { get; set; }
public Heat Heat { get; set; }
public string MaterialId { get; set; }
public List<Operation> Operations { get; set; }
public OrderInfo OrderInfo { get; set; }
public Plate Plate { get; set; }
}
Just set default values.
public class Employee
{
public string FirstName { get; set; } = "";
public string LastName { get; set; } = "";
}
public static void Main(string[] args)
{
var employee = new Employee();
var sw = new StringWriter();
var se = new XmlSerializer(employee.GetType());
var tw = new XmlTextWriter(sw);
se.Serialize(tw, employee);
Console.WriteLine(sw.ToString());
Console.Read();
}
Result
<?xml version="1.0" encoding="utf-16"?>
<Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<FirstName />
<LastName />
</Employee>
Second solution is to set XmlElement(IsNullable = true)
public class Employee
{
[XmlElement(IsNullable = true)]
public string FirstName { get; set; }
[XmlElement(IsNullable = true)]
public string LastName { get; set; }
}
I have no clue what you are trying to do ...
XML serialization just makes a mirror of the object in different structure (aka XML - object will be represented by structured text).
If your class has no properties, nothing will be serialized to XML but only the base empty object.
My suggestion is to make a class with Dictionary<string, object> as property. Then you will be able to write into the Dictionary and serialize it.
But, it has some drawbacks. XML Serialization (if I remember correctly) does not support Dictionaries, so I would go with DataContract instead.
That might work :)
[DataContract]
public class PrimaryData
{
[DataMember(Name = "Data", Order = 0, IsRequired = true)]
public Dictionary<string, object> Data { get; set; }
}
You should add this annotation to your properties:
[XmlElement(IsNullable = true)]
public string Prop { get; set; }
The result in your xml should be something like this:
<Prop xsi:nil="true" />
i have structure in XML file:
<Employee>
<EmpId>1</EmpId>
<Name>Sam</Name>
<Phone Type="Home">423-555-0124</Phone>
<Phone Type="Work">424-555-0545</Phone>
</Employee>
and class:
public class Phone
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlText]
public string Value { get; set; }
}
public class Employee
{
[XmlElement("EmpId")]
public int Id { get; set; }
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("Phone", ElementName = "Phone")]
public Phone phone_home { get; set; }
[XmlElement("Phone2", ElementName = "Phone")]
public Phone phone_work { get; set; }
public Employee() { }
public Employee(string home, string work)
{
phone_home = new Phone()
{
Type = "home",
Value = home
};
phone_work = new Phone()
{
Type = "work",
Value = work
};
}
public static List<Employee> SampleData()
{
return new List<Employee>()
{
new Employee("h1","w1"){
Id = 1,
Name = "pierwszy",
},
new Employee("h2","w2"){
Id = 2,
Name = "drugi",
}
};
}
}
but my problem is that i can't add Two XmlElement with names "Phone". When i try to compile it then i have exception about two same name of XmlElement (repeat: Phone). How can i resolve it?
Use this:
[XmlType("Phone")]
public class Phone
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlText]
public string Value { get; set; }
}
[XmlType("Employee")]
public class Employee
{
[XmlElement("EmpId", Order = 1)]
public int Id { get; set; }
[XmlElement("Name", Order = 2)]
public string Name { get; set; }
[XmlElement(ElementName = "Phone", Order = 3)]
public Phone phone_home { get; set; }
[XmlElement(ElementName = "Phone", Order = 4)]
public Phone phone_work { get; set; }
public Employee() { }
public Employee(string home, string work)
{
phone_home = new Phone()
{
Type = "home",
Value = home
};
phone_work = new Phone()
{
Type = "work",
Value = work
};
}
public static List<Employee> SampleData()
{
return new List<Employee>()
{
new Employee("h1","w1"){
Id = 1,
Name = "pierwszy",
},
new Employee("h2","w2"){
Id = 2,
Name = "drugi",
}
};
}
}
Serialize code:
var employees = Employee.SampleData();
System.Xml.Serialization.XmlSerializer x =
new System.Xml.Serialization.XmlSerializer(employees.GetType());
x.Serialize(Console.Out, employees);
Here is your result:
<?xml version="1.0" encoding="windows-1250"?>
<ArrayOfEmployee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Employee>
<EmpId>1</EmpId>
<Name>pierwszy</Name>
<Phone type="home">h1</Phone>
<Phone type="work">w1</Phone>
</Employee>
<Employee>
<EmpId>2</EmpId>
<Name>drugi</Name>
<Phone type="home">h2</Phone>
<Phone type="work">w2</Phone>
</Employee>
</ArrayOfEmployee>
You are using the [XmlRoot] attribute on your Phone class. [XmlRoot] defines the root of the document, and there can only be one root element in an xml document. Your Employee class should have the [XmlRoot] attribute based on the xml you showed us.
There should be no attributes on your Phone class, only on the Employee.Phone member of your Employee class, as you have it now.
Consider replacing the work and home Phone properties on your Employee class with a property that is a List of Phone objects. This is more flexible (in case you end up supporting other types than work or home), and .net xml serialization knows how to deal with it.
See Is it possible to deserialize XML into List<T>? .
Just replace the phone_home and phone_work properties with this:
[XmlElement("Phone"]
public List<Phone> Phones { get; set; }
The serialized xml should be the same as what you've specified above.
How should I get the <site-standard-profile-request> child element to deserialize correctly so that it does not show up as null?
The deserialization process is perfect; I just need to get the child element <site-standard-profile-request> to serialize as well.
//<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
//- <person>
// <first-name>Storefront</first-name>
// <last-name>Doors</last-name>
// <headline>CEO at StorefrontDoors.NET</headline>
//- <site-standard-profile-request>
// <url>http://www.linkedin.com/profile?viewProfile=&key=147482099&authToken=-Igm&authType=name&trk=api*a216630*s224617*</url>
// </site-standard-profile-request>
// </person>
[XmlRoot("person")]
[Serializable()]
public class LinkedIn
{
[XmlElement("first-name")]
public string FirstName { get; set; }
[XmlElement("last-name")]
public string LastName { get; set; }
[XmlElement("headline")]
public string Headline { get; set; }
public string URL { get; set; }
}
string profile = oauth.APIWebRequest("GET", "https://api.linkedin.com/v1/people/~", null);
//
LinkedIn lkIn = null;
BufferedStream stream = new BufferedStream(new MemoryStream());
stream.Write(Encoding.ASCII.GetBytes(profile), 0, profile.Length);
stream.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(stream);
XmlSerializer serializer = new XmlSerializer(typeof(LinkedIn));
lkIn = (LinkedIn)serializer.Deserialize(sr);
stream.Close();
You'll need another serializable class with just the url as a property. Eg,
[XmlRoot("site-standard-profile-request")]
[Serializable()]
public class StandardProfile
{
public string url { get;set;}
}
And then your existing class should use it, something like
[XmlRoot("person")]
[Serializable()]
public class LinkedIn
{
[XmlElement("first-name")]
public string FirstName { get; set; }
[XmlElement("last-name")]
public string LastName { get; set; }
[XmlElement("headline")]
public string Headline { get; set; }
public StandardProfile Profile { get;set; }
}
I haven't tested this code, but should be pretty close.
Hope that helps.
What I'm trying to do is serialize Nested classes. My code first:
[Serializable]
public class SampleClass
{
[Serializable]
public class Person
{
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("Age")]
public ushort Age { get; set; }
}
[Serializable]
public class Adress
{
[XmlElement("Street")]
public string Street { get; set; }
[XmlElement("House number")]
public int Number { get; set; }
}
public SampleClass()
{
}
public SampleClass(string _name, byte _age, string _street, int _number)
{
Person p = new Person();
p.Name = _name;
p.Age = _age;
Adress a = new Adress();
a.Street = _street;
a.Number = _number;
}
}
I want to get xml like this
<?xml version="1.0"?>
<SampleClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<Person>
<Name></Name>
<Age></Age>
</Person>
<Adress>
<Street></Street>
<HouseNumber></HouseNumber>
</Adress>
</SampleClass>
When I serialize this SimleClass:
using (Stream str = new FileStream(#"C:/test.xml", FileMode.Create))
{
XmlSerializer serial = new XmlSerializer(typeof(SampleClass));
SampleClass sClass = new SampleClass("John",15,"Street",34);
serial.Serialize(str, sClass);
label1.ForeColor = Color.Black;
label1.Text = "Ok";
}
It's give me test.xml file but inside of that file is :
<?xml version="1.0"?>
<SampleClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
What am I doing wrong?
Thanks for advance:)
What you really want serialize is this :
Person p = new Person();
p.Name = _name;
p.Age = _age;
Adress a = new Adress();
But these variables are local.
Create a property of each one and decorate them with the serializable attribute too. Now it will work.
public SampleClass(string _name, byte _age, string _street, int _number)
{
this.Person = new Person();
Person p = this.Person;
p.Name = _name;
p.Age = _age;
this.Adress = new Adress();
Adress a = this.Adress;
a.Street = _street;
a.Number = _number;
}
[Serializable]
public Person Person { get; set; }
[Serializable]
public Adress Adress { get; set; }
BTW: Address takes 2 d.
If you serialize an instance of the main class, the serializer will serialize an instance of the nested class if and only if the object graph contains one. In this respect, nested classes are exactly the same as all other classes.
Basically you have to create properties for the nested class in the main one
This line is invalid:
[XmlElement("House number")]
As an element name can't have a space in it.
The reason you are getting an empty XML file is that your SampleClass has no properties to serialize.
In the constructor you are creating a Person and Address which are thrown away as soon as the method exists as you are not using them for anything. Change your code as follows and you should have more success.
[Serializable]
public class SampleClass
{
[Serializable]
public class Person
{
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("Age")]
public ushort Age { get; set; }
}
[Serializable]
public class Adress
{
[XmlElement("Street")]
public string Street { get; set; }
[XmlElement("HouseNumber")]
public int Number { get; set; }
}
public SampleClass()
{
}
public SampleClass(string name, byte age, string street, int number)
{
this.Person = new Person
{
Age = age,
Name = name
};
this.Adress = new Adress
{
Street = street,
Number = number
}
}
public Person Person { get; set; }
public Address Address { get; set; }
}