I am very new to .net. I have a class which has get and set property. Now if I want to assign value to this array , I am facing null reference. I am unable to assign value ORM.a[i] = dr["SUMMARY"].ToString();
public class method1
{
public string[] a{ get; set; }
public double[] b{ get; set; }
}
publiv method1 GetResponseData()
{
int i = 0;
method1 ORM = new method1 ();
foreach (DataRow dr in dtResultHistory.Rows)
{
ORM.a[i] = dr["SUMMARY"].ToString() ;
ORM.b[i] = Convert.ToDouble( dr["AVG_TIME"]);
}
return ORM ;
}
you are facing null exception because you havent created instace of it.
something like
string[] a = new string [size];
If you are not having details about how many element i going to be there , i suggest you make use of List.
Example :
public class method1
{
public method1()
{
a = new List<string>();
b = new List<double>();
}
public List<string> a{ get; set; }
public List<double> b{ get; set; }
}
you code after this will be
public method1 GetResponseData()
{
int i = 0;
method1 ORM = new method1();
foreach (DataRow dr in dtResultHistory.Rows)
{
ORM.a.Add(dr["SUMMARY"].ToString());
ORM.b.Add(Convert.ToDouble( dr["AVG_TIME"]));
}
return ORM ;
}
The error happens because both a and b property hasn't been initialized. Initialized them first in the class constructor:
public class method1
{
public method1() {
this.a = new string[100]; // We take 100 as an example of how many element the property can handle.
this.b = new double[100];
}
public string[] a{ get; set; }
public double[] b{ get; set; }
}
Related
I have two model list and master model. I need to access and store value to the model properties. not sure how to do this using a viewModel? previously I was using viewData list and now I wan to test viewModel.
<---Model--->
public class Master
{
public List<Table1> T1 { get; set; }
public List<Table2> T2 { get; set; }
}
public class Table1
{
public string sample1 { get; set; }
public string sample1 { get; set; }
}
public class Table2
{
public string sample1 { get; set; }
public string sample2 { get; set; }
}
<--Controller-->
Master master = new Master();
var getSamples = _db.dbSamples.Where(y => y.sample == "xxxx");
foreach(var row in T1) <<---- I need help correcting this part. I believe this is not right...
{
foreach (var item in getSamples)
{
row.sample1 = item.A;
row.sample2 = item.B;
}
}
return View(master);
public class Master
{
public List<Table1> T1 { get; set; }
public List<Table2> T2 { get; set; }
}
public class Table1
{
public string sample1 { get; set; }
public string sample2 { get; set; }
}
public class Table2
{
public string sample1 { get; set; }
public string sample2 { get; set; }
}
<--Controller-->
Master master = new Master();
var getSamples = _db.dbSamples.Where(y => y.sample == "sample1");
var table1List = new List<Table1>();
var table2List = new List<Table2>();
var masterData= new Master();
foreach (var item in getSamples)
{
var data = new Table1();
data.A = item.A;
data.B = item.B;
table1List.add(data);
}
master.T1 = table1List;
var getSamples1 = _db.dbSamples.Where(y => y.sample == "sample2");
foreach (var item in getSamples1)
{
var data2 = new Table2();
data2.A = item.A;
data2.B = item.B;
table2List.add(data2);
}
master.T2 = table2List;
return View(master);
I assume that what you are trying to do is this. If it is not, please elaborate on the question.
Updated code. Change variable names accordingly.
Im looping through all the results from the SQL query in a .Net Core project. here is Model
public class Mymessagesinfo
{
public int MyMessagesCount { get; set; }
public List<int> MessagesIDs { get; set; }
public List<int> MessagesSendersid { get; set; }
public List<string> MessagesSenders { get; set; }
public List<string> MessagesTitles { get; set; }
public List<string> MessagesInformation { get; set; }
public List<string> MessagesStatus { get; set; }
}
I loop through the users messages in my controller then i pass that model to the view
sqlcon.Open();
int? userid = HttpContext.Session.GetInt32("UserID");
SqlCommand sqlcom = new SqlCommand("select * from messages where Messagereceiver=" +userid , sqlcon);
SqlDataReader reader = sqlcom.ExecuteReader();
if(reader.HasRows)
{
int index = 0;
while(reader.Read())
{
string s;
s = reader[0].ToString();
Mymessages.MessagesIDs.Add(int.Parse(s));
Mymessages.MessagesSendersid.Add(int.Parse(reader[1].ToString()));
Mymessages.MessagesTitles.Add(reader[3].ToString());
Mymessages.MessagesInformation.Add(reader[4].ToString());
Mymessages.MessagesStatus.Add(reader[5].ToString());
index++;
}
Mymessages.MyMessagesCount = index;
}
the very first line Mymessages.MessagesIDs.Add(int.Parse(s)); it throws an exception saying System.NullReferenceException: 'Object reference not set to an instance of an object
i wanted to make sure that reader was holding the results so i added int s and checked on it and it was holding the value it was supposed to.
whats going wrong here? is this how we are supposed to pass list-like data to the view?
You need to initlize MessagesIDs in entity Mymessages, like this:
var Mymessages = new Mymessagesinfo()
{
MessagesIDs = new List<int>()
};
Mymessages.MessagesIDs.Add(id);
Or just define the class like this,
public class Mymessagesinfo
{
public int MyMessagesCount { get; set; }
public List<int> MessagesIDs { get; set; } = new List<int>();
public List<int> MessagesSendersid { get; set; } = new List<int>();
public List<string> MessagesSenders { get; set; } = new List<string>();
public List<string> MessagesTitles { get; set; } = new List<string>();
public List<string> MessagesInformation { get; set; } = new List<string>();
public List<string> MessagesStatus { get; set; } = new List<string>();
}
Here is how I would restructure what you have to make it work.
First, your model class:
public class Mymessagesinfo
{
public List<MessageInfo> Messages { get; set; } = new List<MessageInfo>();
}
public class MessageInfo
{
public int ID { get; set; }
public int Senderid { get; set; }
public string Sender { get; set; }
public string Title { get; set; }
public string Information { get; set; }
public string Status { get; set; }
}
With this approach you have a list of message objects, instead of a bunch of lists containing property data.
Here is how I would suggest you load it from SQL Server:
var data = new Mymessagesinfo();
int? userid = HttpContext.Session.GetInt32("UserID");
var messagesTable = new System.Data.DataTable("messages");
using (var sqlcom = sqlcon.CreateCommand())
{
sqlcom.CommandText = $"select * from messages where Messagereceiver='{userid}'";
using (var adapter = new SqlDataAdapter(sqcom))
{
adapter.Fill(messagesTable);
}
}
// we are now done with SQL and have the data in memory...
foreach(DataRow row in messagesTable.Rows)
{
data.Messages.Add( new MessageInfo {
ID = row.Field<int>(0),
Senderid = row.Field<int>(1),
Sender = row.Field<string>(2),
Title = row.Field<string>(3),
Information = row.Field<string>(4),
Status = row.Field<string>(5),
});
}
return View(data);
This is a lot cleaner and by using a DataAdapter and DataTable you minimize the amount of time that the connection to the database is connected.
Here is how you would use this model in an MVC View:
#Model Mymessagesinfo
<div>
<!-- This is where you can display the properties of the message. //-->
<ul>
#foreach(var message in Model.Messages)
{
<li> #message.Title - #message.Id </li>
}
<ul>
<div>
If I construct a View Model with a List like this:
public class ProductsViewModel
{
public bool ProductBool { get; set; }
public string ProductString { get; set; }
public int ProductInteger { get; set; }
public List<Product> ProductList { get; set; }
}
it works fine. But I've seen code that constructs a similar Model like so:
public class ProductsViewModel
{
public bool ProductBool { get; set; }
public string ProductString { get; set; }
public int ProductInteger { get; set; }
public List<Product> ProductList { get; set; }
public ProductsViewModel()
{
this.ProductList = new List<Product>();
}
}
What does the extra contructor element actually do?
When you create an object of the class ProductsViewModel with the statement:
ProductsViewModel obj = new ProductsViewModel();
It automatically instantiate the ProductList. The values in obj now are:
ProductBool = false;ProductString = null;ProductInteger = 0;ProductList = new ProductList();
If you write obj.ProductList.Count() it will give 0
If you remove this constructor or the statement inside the constructor and create object of Class ProductsViewModel as created above. The values in obj will be:
ProductBool = false;ProductString = null;ProductInteger = 0;ProductList =null
If you write obj.ProductList.Count() it will give
Exception of NullReference
I am trying to serialize my code.
When I set the Order property of class members using XmlElement ASP.Net, I got exception on this line;
XmlSerializer serializer = new XmlSerializer(typeof(HotelListResponse));
Exception is;
Inconsistent sequencing: if used on one of the class's members,the 'Order' property is required on all particle-like members,please explicitly set 'Order' using XmlElement, XmlAnyElement or XmlArray custom attribute on class member '_hotelId'.
Code is:
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
StreamReader responsereader = new StreamReader(response.GetResponseStream());
var responsedata = responsereader.ReadToEnd();
xmldoc = (XmlDocument)JsonConvert.DeserializeXmlNode(responsedata);
xmldoc.Save(#"C:\New folder\myfile.xml");
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add("hotelId");
dt.Columns.Add("name");
dt.Columns.Add("address1");
dt.Columns.Add("address2");
dt.Columns.Add("city");
dt.Columns.Add("postalCode");
dt.Columns.Add("countryCode");
dr = dt.NewRow();
XmlSerializer serializer = new XmlSerializer(typeof(HotelListResponse));
Stream reader = new FileStream(#"C:\New folder\myfile.xml", FileMode.Open);
HotelListResponse htype = (HotelListResponse)serializer.Deserialize(reader);
dt.ReadXml(#"C:\New folder\myfile.xml");
foreach(hoteltype ht in htype.hotel){
GridView1.DataSource = dt;
GridView1.DataBind();
}
//responsereader.Close();
//request.GetResponse().Close();
}
}
catch (WebException ex)
{
if (ex.Response == null)
throw new NullReferenceException("WebException response");
throw ex;
}
}
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlRoot("HotelListResponse")]
public class HotelListResponse
{
[System.Xml.Serialization.XmlElementAttribute("hotel")]
public hoteltype[] hotel;
[System.Xml.Serialization.XmlElement(Order = 0)]
public hoteltype[] Items {
get {
return this.hotel;
}
set {
this.hotel = value;
}
}
}
[Serializable]
[XmlType("hoteltype")]
public class hoteltype
{
hoteltype(){}
public int _hotelId;
public string _name;
public string _address1;
public string _address2;
public string _city;
public int _postalCode;
public string _countryCode;
[XmlElement]
public hoteltype[] htype;
[System.Xml.Serialization.XmlElement(Order=1)]
public int hotelId
{
get {
return _hotelId;
}
set{
_hotelId = value;
}
}
[System.Xml.Serialization.XmlElement(Order=2)]
public string name
{
get
{
return _name;
}
set
{
_name = value;
}
}
[System.Xml.Serialization.XmlElement(Order=3)]
public string address1
{
get
{
return _address1;
}
set
{
_address1 = value;
}
}
[System.Xml.Serialization.XmlElement(Order=4)]
public string address2
{
get
{
return _address2;
}
set
{
_address2 = value;
}
}
[System.Xml.Serialization.XmlElement(Order=5)]
public string city
{
get
{
return _city;
}
set
{
_city = value;
}
}
[System.Xml.Serialization.XmlElement(Order=6)]
public int postalCode
{
get
{
return _postalCode;
}
set
{
_postalCode = value;
}
}
[System.Xml.Serialization.XmlElement(Order=7)]
public string countryCode
{
get
{
return _countryCode;
}
set
{
_countryCode = value;
}
}
}
As described in the exception, as soon as you use Order=xx, all of the serializable properties and fields on the class must be ordered. However, it seems that _hotelId may have been intended to be a private backing field. Since XmlSerializer serializes public fields as well, this may be unintentional. If _hotelId really must be public but you don't want it serialized, then you can use XmlIgnore.
I'm guessing your class might look something like:
[System.SerializableAttribute()]
public partial class HotelListResponse
{
[System.Xml.Serialization.XmlElement(Order = 0)]
public string SomeOrderedField
{
get;
set;
}
// ** Problem may be here
// Because the field is public, XmlSerializer will try to serialize this
public int _hotelId;
[System.Xml.Serialization.XmlElement(Order = 1)]
public int HotelId
{
get
{
return _hotelId;
}
set
{
_hotelId = value;
}
}
Edit Yes, that's exactly the problem
Make your backing fields private - that's why you've got the public Property accessors for.
public int _hotelId; => private int _hotelId;
public string _name; => private string _name;
etc.
Edit
[XmlElement(Order=0)]
public hoteltype[] htype;
I would also change it to a property at the same time. Use the automatic backing fields if you are using .NET 3.5 or higher.
[XmlElement(Order=0)]
public hoteltype[] htype
{
get;
set;
}
Edit
If you applied the above systematically, your serializable classes should look like:
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlRoot("HotelListResponse")]
public class HotelListResponse
{
// This is bad practice - never make a backing field public
//[System.Xml.Serialization.XmlElementAttribute("hotel")]
//public hoteltype[] hotel;
// Use the >= .Net 3.5 automatic properties - this way you don't need
// the backing field at all, which will prevent confusion over
// 'what gets serialized'
[System.Xml.Serialization.XmlElement(Order = 0)]
public hoteltype[] Items
{
get;
set;
}
}
[Serializable]
[XmlType("hoteltype")]
public class hoteltype
{
public hoteltype() { }
[System.Xml.Serialization.XmlElement(Order = 0)]
public hoteltype[] htype
{
get;
set;
}
[System.Xml.Serialization.XmlElement(Order = 1)]
public int hotelId
{
get;
set;
}
[System.Xml.Serialization.XmlElement(Order = 2)]
public string name
{
get;
set;
}
[System.Xml.Serialization.XmlElement(Order = 3)]
public string address1
{
get;
set;
}
[System.Xml.Serialization.XmlElement(Order = 4)]
public string address2
{
get;
set;
}
[System.Xml.Serialization.XmlElement(Order = 5)]
public string city
{
get;
set;
}
[System.Xml.Serialization.XmlElement(Order = 6)]
public int postalCode
{
get;
set;
}
[System.Xml.Serialization.XmlElement(Order = 7)]
public string countryCode
{
get;
set;
}
}
And testing the above via a serialize / deserialize cycle like so:
XmlSerializer serializer = new XmlSerializer(typeof(HotelListResponse));
HotelListResponse X = new HotelListResponse();
X.Items = new hoteltype[2];
X.Items[0] = new hoteltype();
X.Items[0].address1 = "address1";
X.Items[1] = new hoteltype();
X.Items[1].address1 = "address2";
using (Stream writer = new FileStream(#"C:\temp\myfile.xml", FileMode.Create))
{
serializer.Serialize(writer, X);
writer.Flush();
}
Stream reader = new FileStream(#"C:\temp\myfile.xml", FileMode.Open);
HotelListResponse htype = (HotelListResponse)serializer.Deserialize(reader);
The following file Deserializes:
<?xml version="1.0"?>
<HotelListResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Items>
<hotelId>0</hotelId>
<address1>address1</address1>
<postalCode>0</postalCode>
</Items>
<Items>
<hotelId>0</hotelId>
<address1>address2</address1>
<postalCode>0</postalCode>
</Items>
</HotelListResponse>
I have a nice dataset loop working, but I need to run another loop based on an ID in the parent loop.
I set up a generic list in a separate class, but I'm totally stumped on how to actually call it. I've Googled it but can't find an example I understand.
EDIT:
List Code...
public class BinList
{
public static List<Bin> GetById(int binOrderSiteID)
{
List<Bin> bins = new List<Bin>();
SqlConnection conn;
SqlCommand comm;
SqlDataReader reader;
using (conn = new SqlConnection(myConnectionHere))
{
comm = new SqlCommand("dbo.sl_BinsBySite", conn);
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.Add(new SqlParameter("#binOrderSiteID", SqlDbType.Int));
comm.Parameters["#binOrderSiteID"].Value = binOrderSiteID;
try
{
conn.Open();
reader = comm.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Bin b = new Bin();
b.BinQty = reader["binQty"].ToString();
b.BinType = reader["binType"].ToString();
b.BinWasteGroupName = reader["binWasteGroupName"].ToString();
b.BinCollectionFrequencyType = reader["binCollectionFrequencyType"].ToString();
b.BinDeliveryStartDate = reader["binDeliveryStartDate"].ToString();
b.BinEmptyCharge = reader["binEmptyCharge"].ToString();
b.BinRentalCharge = reader["binRentalCharge"].ToString();
b.BinDutyOfCareCharge = reader["binDutyOfCareCharge"].ToString();
b.BinDeliveryCharge = reader["binDeliveryCharge"].ToString();
bins.Add(b);
}
}
}
finally
{
conn.Close();
}
}
return bins;
}
}
This is a repository for each field
public class Bin
{
public string BinQty { get; set; }
public string BinType { get; set; }
public string BinWasteGroupName { get; set; }
public string BinCollectionFrequencyType { get; set; }
public string BinDeliveryStartDate { get; set; }
public string BinEmptyCharge { get; set; }
public string BinRentalCharge { get; set; }
public string BinDutyOfCareCharge { get; set; }
public string BinDeliveryCharge { get; set; }
}
Code to that calls the loops
public class PDFCreator
{
public static int BinOrderID { get; set; }
private int binOrderID = 0;
public PDFCreator(int intBinOrderID)
{
//Lots of code here
//Data conenection/datatable code here
foreach (DataRow row in dt.Rows)
{
//lots of code here
//dont know how to connect up or call the List
something?? = BinList.GetById(Convert.ToInt32(row["binOrderSiteID"].ToString()));
foreach (//somnething here)
}
}
}
Sorry I didn't add my code initially. I didn't want to show it cos I thought it was pants.
Any ideas?
Cheers,
Numb
To call BinList GetById
var binList = BinList.GetById((int)row["binOrderSiteID"]);
foreach (var bin in binList)
{
// do what you need to do with bin variable
}