C# Array Syntax when using object oriented programming [duplicate] - c#

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
I have the following partial classes:
public partial class FormInstance
{
private string referenceField;
public string Reference
{
get { return this.referenceField; }
set { this.referenceField = value; }
}
}
public partial class FormField
{
private string fieldNameField;
private string fieldValueField;
public string FieldName
{
get { return this.fieldNameField; }
set { this.fieldNameField = value; }
}
public string FieldValue
{
get { return this.fieldValueField; }
set { this.fieldValueField = value; }
}
}
public partial class EFormData
{
private FormInstance formInstanceField;
private FormField[] formDataField;
public FormInstance EFormInstance
{
get { return this.formInstanceField; }
set { this.formInstanceField = value; }
}
public FormField[] FormData
{
get { return this.eformDataField; }
set { this.eformDataField = value; }
}
}
I have a method as follows which has a parameter that is of the above class object type:
public int writeEformData(EformData formFields)
{
object[] results = this.Invoke("writeEformData", new object[] {
formFields});
return ((int)(results[0]));
}
In my code I'm trying to initialise the EformData object as follows:
EformData eformData = new EformData ();
eformData.EformInstance.Reference = "1234";
eformData.FormData[0].FieldName = "txt_name";
eformData.FormData[0].FieldValue = "John Doe";
eformData.FormData[1].FieldName = "txt_address";
eformData.FormData[1].FieldValue = "10 Acacia Ave";
int result = web.writeEformData(eformData);
but when I debug I get error on line 2 eformData.EformInstance.Reference = "1234";
An unhandled exception of type 'System.NullReferenceException' occurred
Additional information: Object reference not set to an instance of an object.
Whats the correct syntax to initialise the EformData object and assigning values as I'm trying to do above?

replace
eformData.EformInstance.Reference = "1234";
with
eformData.EFormInstance = new FormInstance() { Reference = "1234" };
..and you will have the same troulbe in the following lines. You have to create a instance of each object before you can set a value to its properties
eformData.FormData = new FormField[2];
eformData.FormData[0] = new FormField() { FieldName = "txt_name", FieldValue = "John Doe" };

Related

How to ignore JSON property basing on the other property value in .NET using System.Text.Json serializer?

I am having an exemplary .NET class:
public class Foo
{
public string Name { get; set; }
public int Age { get; set; }
}
Is it possible to serialize Name property only if Age is > 18 using JsonSerializer.Serialize(...) method? Would it be possible to achieve such behaviour without implementing custom serializer, eg. using some attributes? Thanks in advance for any help.
You can either write custom converter for the type or use .NET 7 approach with customizing contract:
var foos = new[] { new Foo { Age = 1, Name = "Should not show" }, new Foo { Age = 19, Name = "Name" } };
var result = JsonSerializer.Serialize(foos, new JsonSerializerOptions
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
Modifiers = { SkipUnderagedName }
}
});
Console.WriteLine(result); // prints "// [{"Age":1},{"Name":"Name","Age":19}]"
static void SkipUnderagedName(JsonTypeInfo ti)
{
if (ti.Type.IsAssignableTo(typeof(Foo)))
{
var prop = ti.Properties.FirstOrDefault(p => p.Name == nameof(Foo.Name));
if (prop is not null)
{
prop.ShouldSerialize = (obj, _) =>
{
var foo = obj as Foo;
return foo?.Age >= 18;
};
}
}
}
Since you don't want any custom serializers your can try this code. It returns Name property value eguals null if Age < 19. When Name is null, serializer ignores this property.
public class Foo
{
private string _name;
[System.Text.Json.Serialization.JsonPropertyName("Name")]
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string _Name
{
get { return Age > 18 ? _name : null; }
set { _name = value; }
}
[System.Text.Json.Serialization.JsonIgnore]
public string Name
{
get { return _name; }
set { _name = value; }
}
public int Age { get; set; }
}

JsonObject<List<string>> can't add any data

I tried writing to db using Pomelo.EntityFramework.Mysql with the following code, but it failed. (I know that this is not the fault of Pomelo.EntityFramework.)
public class Element
{
[Key]
public string Id { get; set; }
public JsonObject<List<string>> Tags { get; set; }
}
and
Element element = new Element();
element.ElementId = Guid.NewGuid().ToString();
element.Tags = new List<string>() { "user" };
element.Tags.Object.Add("newtag");
jsonobject only converts "user" to json.(["user"])
What did I make a mistake?
EDIT
i try rewrite code of Pomelo.JsonObject
just changed this code.
public string Json
{
get { return SerializeObject(Object); }
set
{
try
{
Object = string.IsNullOrWhiteSpace(value)
? default(T)
: DeserializeObject<T>(value);
_originalValue = value;
}
catch
{
Object = null;
_originalValue = string.Empty;
}
}
}
from
public string Json
{
get { return _originalValue; }
set
{
try
{
Object = string.IsNullOrWhiteSpace(value)
? default(T)
: DeserializeObject<T>(value);
_originalValue = value;
}
catch
{
Object = null;
_originalValue = string.Empty;
}
}
}
Now it works perfectly.

How to initialise nested arrays

Forgive a stupid question but I am new to C# & OOP.
Can anyone help me prevent a “System.NullReferenceException:”?
I’m trying to do an assignment following instructions and using what we’ve learned to date (arrays, classes and constructors).
I’ve created an array of StudentSubjects classes and embedded this in an array of Student classes.
I want to print out details of each student’s subjects.
I can access the StudentArray[0] fields OK but can’t get to the StudentArray[0].StudentSubjectsArray[0] fields because "Object reference not set to an instance of an object”
I’ve spent 2 weeks looking for an answer but cannot find any examples of how to set
StudentArray[0].StudentSubjectsArray[0].SubjectName = "Algebra";
Any advice most appreciated. My code is below ....
using System;
namespace Nested_Arrays
{
public class Program
{
static void Main(string[] args)
{
Student[] StudentArray = new Student[1];
Console.WriteLine($"Hello");
StudentArray[0] = new Student();
StudentArray[0].StudentName = "Peter";
StudentArray[0].StudentLocation = "Australia";
Console.WriteLine($"{StudentArray[0].StudentName,10} {StudentArray[0].StudentLocation,15}");
StudentArray[0].StudentSubjectsArray[0].SubjectName = "Algebra";
StudentArray[0].StudentSubjectsArray[0].StudentsResult = "Pass";
Console.WriteLine($"{StudentArray[0].StudentName,10} {StudentArray[0].StudentLocation,15} {StudentArray[0].StudentSubjectsArray[0].SubjectName,15} {StudentArray[0].StudentSubjectsArray[0].StudentsResult,10}");
Console.WriteLine($"Goodbye");
}
public class Student
{
public string StudentName;
private string studentName
{ get { return studentName; } set { studentName = value; } }
public string StudentLocation;
private string studentLocation
{ get { return studentLocation; } set { studentLocation = value; } }
public StudentSubjects[] StudentSubjectsArray;
private StudentSubjects[] studentSubjectsArray
{ get { return studentSubjectsArray; } set { studentSubjectsArray = value; } }
//Constructor
public Student() { }
}
public class StudentSubjects
{
public string SubjectName;
private string subjectName
{ get { return subjectName; } set { subjectName = value; } }
public string StudentsResult;
private string studentsResult
{ get { return studentsResult; } set { studentsResult = value; } }
//Constructor
public StudentSubjects() { }
}
}
}
You just need to add the following:
StudentArray[0].StudentSubjectsArray = new StudentSubjects[1];
StudentArray[0].StudentSubjectsArray[0] = new StudentSubjects();
// and only then
StudentArray[0].StudentSubjectsArray[0].SubjectName = "Algebra";
In my opinion, a good practice is to initialize arrays in the constructor. In this way you are sure it is not null when using the object.
So do something like:
//Constructor
public Student() {
this.studentSubjectsArray = new StudentSubjects[1];
}
As others have said, you need to create the arrays before you assign objects in the array, although you can do both at the same time.
For example, if you want to do it all in one line, this would work:
Student[] StudentArray = {
new Student {
StudentName = "Peter",
StudentLocation = "Australia",
StudentSubjectsArray = new[] {
new StudentSubjects {
SubjectName = "Algebra",
StudentsResult = "Pass"
}
}
}
};

Encounter Nullpointer error [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 7 years ago.
I am having problem with nullpointer. I cant seem to understand why my code is wrong. Any help will be greatly appreciated. This is my code:
protected void Page_Load(object sender, EventArgs e)
{
Product aProd = new Product();
// Get Product ID from querystring
string prodID = Request.QueryString["ProdID"].ToString(); (null pointer occurs at this line. )
prod = aProd.getProduct(prodID);
//Display product details on web form
lbl_ProdName.Text = prod.Product_Name;
lbl_ProdDesc.Text = prod.Product_Desc;
lbl_Price.Text = prod.Unit_Price.ToString("c");
img_Product.ImageUrl = "~\\Images\\" + prod.Product_Image;
//Store the value in invisible fields
lbl_Price.Text = prod.Unit_Price.ToString();
lbl_ProdID.Text = prodID.ToString();
}
These are the code for Product.cs. I still have no idea where my codes went wrong
public class Product
{
string _connStr = ConfigurationManager.ConnectionStrings["HealthDBContext"].ConnectionString;
private string _prodID = null;
private string _prodName = string.Empty;
private string _prodDesc = ""; // this is another way to specify empty string
private decimal _unitPrice = 0;
private string _prodImage = "";
private int _stockLevel = 0;
// Default constructor
public Product()
{
}
// Constructor that take in all data required to build a Product object
public Product(string prodID, string prodName, string prodDesc,
decimal unitPrice, string prodImage, int stockLevel)
{
_prodID = prodID;
_prodName = prodName;
_prodDesc = prodDesc;
_unitPrice = unitPrice;
_prodImage = prodImage;
_stockLevel = stockLevel;
}
// Constructor that take in all except product ID
public Product(string prodName, string prodDesc,
decimal unitPrice, string prodImage, int stockLevel)
: this(null, prodName, prodDesc, unitPrice, prodImage, stockLevel)
{
}
// Constructor that take in only Product ID. The other attributes will be set to 0 or empty.
public Product(string prodID)
: this(prodID, "", "", 0, "", 0)
{
}
// Get/Set the attributes of the Product object.
// Note the attribute name (e.g. Product_ID) is same as the actual database field name.
// This is for ease of referencing.
public string Product_ID
{
get { return _prodID; }
set { _prodID = value; }
}
public string Product_Name
{
get { return _prodName; }
set { _prodName = value; }
}
public string Product_Desc
{
get { return _prodDesc; }
set { _prodDesc = value; }
}
public decimal Unit_Price
{
get { return _unitPrice; }
set { _unitPrice = value; }
}
public string Product_Image
{
get { return _prodImage; }
set { _prodImage = value; }
}
public int Stock_Level
{
get { return _stockLevel; }
set { _stockLevel = value; }
}
Request.QueryString["ProdID"] is returning null.
So your ToString() call cause a System.NullPointerException
Solution : ensure that your Request.QueryString["ProdID"] call sends you back the correct object, or test the result yourself:
var obj = Request.QueryString["ProdID"];
string prodID = obj == null ? String.Empty : obj.ToString();

C# retrieve properties through reflection [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Get property value from string using reflection in C#
I have an application that merges fields from a database into emails and letters. As there are different users they request different fields to be merged, and as I create a new mergefield the documentation also has to be reworked. This gives problems so I want to automate the documentation.
I came up with the following code (in this example I defined only 2 mergefields, called stringField, but currently it's allmost 100):
namespace ReflectionTest
{
public class clReflection
{
private System.Data.DataTable dtClient = new System.Data.DataTable();
public int ClientNumber { get; set; }
public int AdressNumber { get; set; }
public stringField ClientName
{
get
{
stringField _ClientName = new stringField();
_ClientName.FieldContent = "Obama";
_ClientName.FieldNote = "Last name of client";
//Available email and available letter should be default true
return _ClientName;
}
set { }
}
public stringField ClientEmail
{
get
{
stringField _ClientEmail = new stringField();
_ClientEmail.FieldContent = "obama#whitehouse.gov";
_ClientEmail.FieldNote = "use only tested email adresses";
_ClientEmail.AvailableLetter = false;
return _ClientEmail;
}
set
{ }
}
}
public static class FindStringFields
{
public static System.Data.DataTable stringFields()
{
System.Data.DataTable dtStringFields = new System.Data.DataTable();
dtStringFields.Columns.Add(new System.Data.DataColumn("FieldName", typeof(string)));
dtStringFields.Columns.Add(new System.Data.DataColumn("FieldNote", typeof(string)));
dtStringFields.Columns.Add(new System.Data.DataColumn("AvailableEmail", typeof(bool)));
clReflection test = new clReflection();
System.Reflection.PropertyInfo[] props = test.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
for (int i = 0; i < props.Length; i++)
{
if (props[i].PropertyType == typeof(stringField))
{
dtStringFields.Rows.Add(new object[] { props[i].Name , "FieldNote", true });
}
}
return dtStringFields;
}
}
public class stringField
{
private bool _AvailableEmail = true;
private bool _AvailableLetter = true;
public string FieldContent { get; set; }
public string FieldNote { get; set; }
public bool AvailableEmail
{
get { return _AvailableEmail; }
set { AvailableEmail = value; }
}
public bool AvailableLetter
{
get { return _AvailableLetter; }
set { _AvailableLetter = value; }
}
}
}
If you fire the instruction: System.Data.DataTable dtTest = FindStringFields.stringFields();
you get a datatable with all defined stringFields.
However, apart from the name of the stringfield I can't retrieve the properties of a stringfield.
How do I instantiate a found stringField so I can retrieve the other properties?
Thanks,
Rob
Use Type.GetProperties method to get all public properties of type
Type type = typeof(stringField);
PropertyInfo[] properties = type.GetProperties();
Also there is overload where you can specify BindingFlags.
Then you can get values of properties:
object value = property.GetValue(_ClientEmail);
If you have the string field name try with this:
public static object GetPropValue( object src, string propName )
{
return src.GetType( ).GetProperty( propName ).GetValue( src, null );
}
Extracted from this SO post:
Get property value from string using reflection in C#
You can do something like this:
//its better to use a property than get it from the array every time!
PropertyInfo pi = prop[i];
//get the underlying value
stringField underlyingStringField = prop.GetValue(test, null) as stringField;
//use the underlying value now
Debug.Write(underlyingStringField.AvalilableEmail);
...

Categories