System.NullReferenceException while Serializing XML [duplicate] - c#

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I want to serialize simple class as for example like below and write to XML file.
Sample Class file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SampleXMLSerializeDeserialize
{
public class SampleXML
{
public SampleXML()
{
}
public List<IndividualInfo> IndividualInfo { get; set; }
public List<CommunicationInfo> Communication { get; set; }
}
public class IndividualInfo
{
public String Name { get; set; }
public String Age { get; set; }
}
public class CommunicationInfo
{
public String presentAdd { get; set; }
public String permanentAdd { get; set; }
}
}
Serialization Method:
namespace SampleXMLSerializeDeserialize
{
class Program
{
static void Main(string[] args)
{
SampleXML s = new SampleXML();
s.IndividualInfo[0].Name="Jyoti";
s.IndividualInfo[0].Age = "25";
s.Communication[0].permanentAdd = "Dhaka";
s.Communication[0].presentAdd = "Dhaka";
XmlSerializer serializer = new XmlSerializer(typeof(SampleXML));
StreamWriter str = new StreamWriter(Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) + #"\SAM.XML");
serializer.Serialize(str, s);
}
}
}
I am getting System.NullReferenceExeption at following line: s.IndividualInfo[0].Name="Jyoti";
Would you please help, what I am missing

You never instantiate the [0] object of the collection and the collection itself. Use this:
s.IndividualInfo = new List<IndividualInfo>();
s.IndividualInfo.Add(new IndividualInfo { Name = "Jyoti" });

Have your constructor as
public SampleXML()
{
IndividualInfo = new List<IndividualInfo>();
Communication = new List<CommunicationInfo>();
}
the list is not being initialized and is null.
do the same for the other list as well.
And then use the Add method instead of indexed access.
s.IndividualInfo.Add(new IndividualInfo { Name = "Jyoti", Age = 25 });

Related

JsonConvert.SerializeObject is escaping "#" in my object [duplicate]

This question already has answers here:
How can I change property names when serializing with Json.net?
(4 answers)
Closed 6 months ago.
I'm having an issue with JsonConvert.SerializeObject when I try to serialize my object with:
var statementOfAccount = new
{
main = new
{
#xm = "https://api-path.com",
RESTHeader = new
{
Responsibility = "Responsibility ",
RespApplication = "AR",
NLSLanguage = "AMERICAN"
}
}
};
And giving me:
{
"main": {
"xm": "https://api-path.com",
"RESTHeader": {
"Responsibility": "Responsibility",
"RespApplication": "AR",
"NLSLanguage": "AMERICAN"
}
}
}
So basically it's removing the # from #xm and please note that I can't change the name of the property so I need a solution that will serialize it as is.
one way would be to create a custom class instead of using an anonymous
public class Custom
{
....
[JsonProperty["#xm"]
public string #xm {get; set;}
....
}
since your anonymous object properties are known and can't cause any property overlaping, another way is to replace a json string after serialization
json=json.Replace("xm:","#xm:");
https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-customize-properties?pivots=dotnet-6-0
this solved my problem to use JsonPropertyName but with JsonSerializer.Serialize instead of JsonConvert.SerializeObject so the problem was me using an anonymous object as most of you suggested but using JsonPropertyName only worked with JsonSerializer.Serialize, it didn't work with JsonConvert.SerializeObject
solution:
public class Main
{
[JsonPropertyName("#xm")]
public string #xm { get; set; }
public RESTHeader RESTHeader { get; set; }
}
public class RESTHeader
{
public string Responsibility { get; set; }
public string RespApplication { get; set; }
public string NLSLanguage { get; set; }
}
public class Root
{
public Main main { get; set; }
}
var statementOfAccount = new Root
{
main = new Main
{
#xm = "https://api-path",
RESTHeader = new RESTHeader
{
Responsibility = "Responsibility ",
RespApplication = "AR",
NLSLanguage = "AMERICAN"
}
}
};
var json = System.Text.Json.JsonSerializer.Serialize(statementOfAccount);

Traversing an XML file using Linq to XML not working as expected

Sorry for the somewhat basic question, but what can I say. I can't figure it out. The problem is that there's a foreach loop that's supposed to iterate through the rows (sections) and while it works for the first section, the second time through the loop it doesn't seem to read the second section. The same data is stored in version. BTW, the way the method is called I would be passing in ProductName as a parameter (There will be multiple products represented here and also a version number (e.g. v2.0.0) that I'll need to filter the results for too.
So I have an XML file that looks like this:
<Products>
<ProductName1>
<v2.0.0>
<GUID>"{B5ECEC43-5406-4E4D-96D9-456823100313}"</GUID>
<VersionNameToUninstall>"2.0.0 - 2.0.2"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-2.0.0-Uninst.iss"</UninstallResponseFile>
</v2.0.0>
<v2.0.3>
<GUID>"{1D6C02D7-8E87-43BE-8AB2-1FF0E5ACD410}"</GUID>
<VersionNameToUninstall>"2.0.3"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-2.0.3-Uninst.iss"</UninstallResponseFile>
</v2.0.3>
</ProductName1>
<ProductName2>
<v3.0.0>
<GUID>"{ABCDEC43-5406-4E4D-96D9-456823101234}"</GUID>
<VersionNameToUninstall>"2.2.0 - 2.2.2"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-2.2.0-Uninst.iss"</UninstallResponseFile>
</v3.0.0>
<v4.0.0>
<GUID>"{5D6C02D7-8E87-43BE-8AB2-1FF0E5ACD589}"</GUID>
<VersionNameToUninstall>"4.0.0"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-4.0.0-Uninst.iss"</UninstallResponseFile>
</v4.0.0>
</ProductName2>
</Products>
There will only be 10 or so versions (e.g. v2.x.x) so there's not a lot of data here. So I created a multidimensional (nested) class/struct to hold the data and when I try my code to read the data it's not working.
Here are the classes/stucts (I've tried both and neither works) that I'm trying to populate:
public class TopLevelObject
{
public string Version { get; set; }
public RowLevelObject Row {get;set;}
}
public struct RowLevelObject
{
public string Guid { get; set; }
public string VersionName { get; set; }
public string UninstallFileName { get; set; }
}
So here's my code. Please just ignore the Stream - that's so I can embed this XML file in the .exe and not have it be a separate file:
public static List<TopLevelObject> GetGUIDSFromFile(string GUIDKey)
List<InstallScriptMSIXMLTopLevelObject> installScriptMSIXMLTopLevelObjectList = new List<InstallScriptMSIXMLTopLevelObject>();
Stream GUIDXmlFileStream = typeof(PGCommonCA).Assembly.GetManifestResourceStream("PGCommonCA.ProductGUIDs.xml");
XElement xElement = XElement.Load(GUIDXmlFileStream);
var versions = xElement.Elements(GUIDKey).Descendants();
foreach (var version in versions)
{
TopLevelObject topLevelObject = new TopLevelObject();
RowLevelObject rowLevelObject = new RowLevelObject();
TopLevelObject.Version = version.Name.LocalName;
RowLevelObject.Guid = version.Element("GUID").Value;
RowLevelObject.VersionName = version.Element("VersionNameToUninstall").Value;
RowLevelObject.UninstallFileName = version.Element("UninstallResponseFile").Value;
TopLevelObjectList.Add(topLevelObject);
}
return TopLevelObjectList;
}
I know there are many ways to read XML and my choice doesn't work so I'm looking for another simple solution.
The following works :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement productName = doc.Root;
List<TopLevelObject> top = productName.Elements().Select(x => new TopLevelObject() {
Version = x.Name.LocalName,
Row = new RowLevelObject() {
Guid = (string)x.Element("GUID"),
VersionName = (string)x.Element("VersionNameToUninstall"),
UninstallFileName = (string)x.Element("UninstallResponseFile")
}
}).ToList();
}
}
public class TopLevelObject
{
public string Version { get; set; }
public RowLevelObject Row { get; set; }
}
public struct RowLevelObject
{
public string Guid { get; set; }
public string VersionName { get; set; }
public string UninstallFileName { get; set; }
}
}
I figured it out (many thanks to jdweng!!). Here's the final solution based on the revised XML at the top:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static TopLevelObject GetInfo(string xmlKey)
{
XDocument doc = XDocument.Load(FILENAME);
XElement productName = doc.Root;
List<TopLevelObject> top = productName.Descendants(xmlKey).Elements().Select(x => new TopLevelObject() {
Version = x.Name.LocalName,
Row = new RowLevelObject() {
Guid = (string)x.Element("GUID"),
VersionName = (string)x.Element("VersionNameToUninstall"),
UninstallFileName = (string)x.Element("UninstallResponseFile")
}
}).ToList();
}
}
public class TopLevelObject
{
public string Version { get; set; }
public RowLevelObject Row { get; set; }
}
public struct RowLevelObject
{
public string Guid { get; set; }
public string VersionName { get; set; }
public string UninstallFileName { get; set; }
}
}

How do you use a class as a property in another class, then instantiate it? [C#] [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 5 years ago.
I'm trying to get a better understanding of classes, the class 'Address' is used as a type in the property 'ShippingAddress' in the class 'Person', but I was wondering how do I assign values to the address properties because the way it is below gives me an error:
Found on .NET Tutorials
**An unhandled exception of type 'System.NullReferenceException' occurred in Classes_and_Objects.exe
Additional information: Object reference not set to an instance of an object.**
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Classes_and_Objects
{
class Program
{
static void Main(string[] args)
{
Person john = new Person();
john.FirstName = "John";
john.LastName = "Doe";
john.ShippingAddress.StreetAddress = "78 Fake Street" ;
john.ShippingAddress.City = "Queens";
john.ShippingAddress.State = "NY";
john.ShippingAddress.PostalCode = "345643";
john.ShippingAddress.Country = "United States";
}
}
public class Address
{
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Address ShippingAddress { get; set; }
}
}
}
You need to instantiate the address too. Here is how you should write your code:
static void Main(string[] args)
{
Person john = new Person();
john.FirstName = "John";
john.LastName = "Doe";
john.ShippingAddress = new Address();
john.ShippingAddress.StreetAddress = "78 Fake Street" ;
john.ShippingAddress.City = "Queens";
john.ShippingAddress.State = "NY";
john.ShippingAddress.PostalCode = "345643";
john.ShippingAddress.Country = "United States";
}
Jhon.shippingadress = new Address();

WCF: Object Reference Not Set To Instance Of a an Object [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 7 years ago.
I have a CibilResponse Class that has properties that are of class type (TUEF class). I am trying to assign value to CibilEnquiryEnq.Tuef.Version but i am getting null reference error. Before you mark this question as duplicate let me mention that I have read some of the similar questions and their answers on SO and post which I have initialized tuef in the constructor as you can see in my code. Can you please point out if you can what is it that I am doing wrong?
ICIBIL.cs
[ServiceContract]
public interface ICIBIL
{
[OperationContract]
string InsertCibil(CibilResponse cibilResponse);
[OperationContract]
string GenerateEnquiry(CibilEnquiry testObj);
}
[DataContract]
public class CibilResponse
{
[DataMember]
public string ResponseString { get; set; }
[DataMember]
public string Business { get; set; }
[DataMember]
public string MkrId { get; set; }
}
[DataContract]
public class CibilEnquiry
{
[DataMember]
public TUEF Tuef { get; set; }
public CibilEnquiry()
{
this.Tuef = new TUEF();
}
}
[DataContract]
public class TUEF
{
[DataMember]
public string SegmentTag { get; set; }
[DataMember]
public string Version { get; set; }
[DataMember]
public string MemberReferenceNumber { get; set; }
}
Appication :
CibilWcfService.CIBIL obj = new CibilWcfService.CIBIL();
CibilWcfService.CibilEnquiry CibilEnquiryEnq = new CibilWcfService.CibilEnquiry();
CibilEnquiryEnq.Tuef.Version = "123";// null reference error here
string res = obj.GenerateEnquiry(CibilEnquiryEnq);
Can you try the below. C# is case sensitive.
using CbilFileReader.CibilWcfService;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
CIBIL obj = new CIBIL();
CibilEnquiry CibilEnquiryEnq = new CibilEnquiry();
TUEF objtuef = new TUEF();
objtuef.Version = "123";
CibilEnquiryEnq.Tuef = objtuef;
string res = obj.GenerateEnquiry(CibilEnquiryEnq);
}
}
}
This might do the trick for you
CibilWcfService.CIBIL obj = new CibilWcfService.CIBIL();
CibilWcfService.CibilEnquiry CibilEnquiryEnq = new CibilWcfService.CibilEnquiry();
CibilWcfService.CibilEnquiry.Tuef ObjTUEF = new CibilWcfService.CibilEnquiry.Tuef();
ObjTUEF.Version="123";
CibilEnquiryEnq.Tuef = ObjTUEF;
string res = obj.GenerateEnquiry(CibilEnquiryEnq);

Deserialize from WebServices C#

Here's my issue : I need to get a list of resources from a web services, and deserialize it into object. But it doesn't work, despite the facts my code worked with another xml file. So I can't figure why it doesn't work, and I'm stuck with that !
Here's the XML :
<ResourceDataSet xmlns="http://schemas.microsoft.com/office/project/server/webservices/ResourceDataSet/">
<Resources>
<RES_UID>blabla</RES_UID>
<RES_NAME>blabla</RES_NAME>
<RES_CODE>blabla</RES_CODE>
<RES_GROUP>blabla</RES_GROUP>
<RES_COST_CENTER>blabla</RES_COST_CENTER>
</Resources>
<Resources>
<RES_UID>blabla</RES_UID>
<RES_NAME>blabla</RES_NAME>
<RES_CODE>blabla</RES_CODE>
<RES_GROUP>blabla</RES_GROUP>
<RES_COST_CENTER>blabla</RES_COST_CENTER>
</Resources>
<Resources>
<RES_UID>blabla</RES_UID>
<RES_NAME>blabla</RES_NAME>
<RES_CODE>blabla</RES_CODE>
<RES_GROUP>blabla</RES_GROUP>
<RES_COST_CENTER>blabla</RES_COST_CENTER>
</Resources>
</ResourceDataSet>
The class I want to deserialize into :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Threading.Tasks;
using System.Collections;
namespace TestWPF
{
[Serializable()]
public class Employee
{
[System.Xml.Serialization.XmlElement("RES_UID")]
public int RES_UID { get; set; }
[System.Xml.Serialization.XmlElement("RES_NAME")]
public String RES_NAME { get; set; }
[System.Xml.Serialization.XmlElement("RES_CODE")]
public String RES_CODE { get; set; }
[System.Xml.Serialization.XmlElement("RES_GROUP")]
public String RES_GROUP { get; set; }
[System.Xml.Serialization.XmlElement("RES_COST_CENTER")]
public String RES_COST_CENTER { get; set; }
public Employee()
{ }
public Employee(int r_id, String res_name, String res_code, String res_group, String res_cost_center)
{
this.RES_UID = r_id;
this.RES_NAME = res_name;
this.RES_CODE = res_code;
this.RES_GROUP = res_group;
this.RES_COST_CENTER = res_cost_center;
}
}
[Serializable()]
[System.Xml.Serialization.XmlRoot("ResourceDataSet")]
public class EmployeeList //: IEnumerator, IEnumerable
{
public EmployeeList() {Items = new List<Employee>();}
[XmlArray("ResourceDataSet")]
[XmlArrayItem("Resources")]
public List<Employee> Items {get;set;}
}
}
And the code I use to deserialize :
EmployeeList lstEmployee = null;
XmlSerializer xs = new XmlSerializer(typeof(ServersList));
StreamReader sr = new StreamReader("testEmployee.xml");
lstEmployee = (EmployeeList)serializer.Deserialize(sr);
reader.Close();
for (int i = 0; i < lstEmployee.Items.Count(); i++)
{
MessageBox.Show(lstEmployee.Items[i].RES_NAME);
}
And when I try to launch I receive this error message :
Firstly your xml file is invalid - RES_UID is expecting an int, so even when you get your serialization working you'll run into that problem.
You're also not taking into account the namespace. The following class works:
[Serializable()]
public class Employee
{
[System.Xml.Serialization.XmlElement("RES_UID")]
public int RES_UID { get; set; }
[System.Xml.Serialization.XmlElement("RES_NAME")]
public String RES_NAME { get; set; }
[System.Xml.Serialization.XmlElement("RES_CODE")]
public String RES_CODE { get; set; }
[System.Xml.Serialization.XmlElement("RES_GROUP")]
public String RES_GROUP { get; set; }
[System.Xml.Serialization.XmlElement("RES_COST_CENTER")]
public String RES_COST_CENTER { get; set; }
public Employee()
{ }
public Employee(int r_id, String res_name, String res_code, String res_group, String res_cost_center)
{
this.RES_UID = r_id;
this.RES_NAME = res_name;
this.RES_CODE = res_code;
this.RES_GROUP = res_group;
this.RES_COST_CENTER = res_cost_center;
}
}
[Serializable()]
[System.Xml.Serialization.XmlRoot("ResourceDataSet", Namespace = "http://schemas.microsoft.com/office/project/server/webservices/ResourceDataSet/")]
public class EmployeeList //: IEnumerator, IEnumerable
{
public EmployeeList() {Items = new List<Employee>();}
[XmlElement("Resources", Type = typeof(Employee))]
public List<Employee> Items {get;set;}
}
}
and your calling code with the typos fixed:
EmployeeList lstEmployee = null;
XmlSerializer xs = new XmlSerializer(typeof(EmployeeList));
StreamReader sr = new StreamReader("testEmployee.xml");
lstEmployee = (EmployeeList)xs.Deserialize(sr);
sr.Close();
for (int i = 0; i < lstEmployee.Items.Count(); i++)
{
MessageBox.Show(lstEmployee.Items[i].RES_NAME);
}
Remember to fix your xml to be ints otherwise it still won't work
You need to either decorate your root entity with the XmlRoot attribute or Or specify the root attribute when de serializing at runtime.
Here is a thread about this issue
https://stackoverflow.com/a/1557145/1305119

Categories

Resources