How to set the value of a property if it is null? - c#

I am trying to write my first WCF Service. Right now I just want to take a bunch of properties of an object and write them to SQL Server.
Not all the property values will always be set so I would like to receive the object on the service side, loop through all the properties on the object and if there are any of a string datatype that are not set, set the value to "?".
All the properties of object are defined of type string
I am trying the following code found here but get the error "Object does not match target type." on the line indicated below
foreach (PropertyInfo pInfo in typeof(item).GetProperties())
{
if (pInfo.PropertyType == typeof(String))
{
if (pInfo.GetValue(this, null) == "")
//The above line results in "Object does not match target type."
{
pInfo.SetValue(this, "?", null);
}
}
}
How should I be checking if a property of string type on an object has not been set?

The value returned from PropertyInfo.GetValue is object. However, since you know the value is a string (because you checked in the line above) you can tell the compiler "I know this is a string" by doing a cast:
if (pInfo.PropertyType == typeof(String))
{
string value = (string) pInfo.GetValue(this, null);
if (value == "")
{
Also, I would add an extra null check in there, just in case the value is null or empty. Luckily, there's the string.IsNullOrEmpty method for that:
if (pInfo.PropertyType == typeof(String))
{
string value = (string) pInfo.GetValue(this, null);
if (string.IsNullOrEmpty(value))
{

Related

C# get property value with reflection has not default value

I have this code:
messageDto = new CorrelationDto()
{
timestamp = default,
};
var isDefault = messageDto.GetType().GetProperty("timestamp").GetValue(messageDto) == default; // FALSE
var isDefault2 = messageDto.timestamp == default; // TRUE
where timestamp is a DateTime.
As you can see, getting the value through reflection and comparing to default return false. Do you have any idea why it's happening and how should I do to check for default values?
Thanks
== EDIT ==
It has been pointed to me that the return value of GetValue() is an object and so it must be casted to DateTime in order for the default to work. Unfortunately I cannot because I'm running this test on all the properties of an object to discover if this object is initialized or not (so I check for null or default value). And the messageDto in reality is a generic type so I don't know the types of its properties a priori.
GetValue returns an object of type object, because it can't know at compile time what the type of the property is. The default value of an object is null, but since DateTime is a value type, its default value cannot be null.
Cast the result of GetValue to DateTime.
If I correctly understood you, this is how I solved this problem:
private static bool IsValueNumericDefault(object value)
{
var intVal = 1;
var doubleVal = 1.0;
return (int.TryParse($"{value}", out intVal) || double.TryParse($"{value}", out doubleVal)) &&
(intVal == default || doubleVal == default);
}
I check random object value through casting it to string and try parse to type that I check. Value parameter is returned by reflection method .GetValue(). You can try to parse it to DateTime or any other type that you check.

C# how Set property dynamically by string?

First of all I'm not into programming, but could figure out the basic concept
up to my needs.
In the below code, I want to set the property by name "Gold" in something like:
_cotreport.Contract = COTReportHelper.ContractType."Blabalbal"
protected override void OnBarUpdate()
{
COTReport _cotreport = COTReport(Input);
_cotreport.Contract=COTReportHelper.ContractType.Gold;
_cotreport.OpenInterestDisplay=COTReportHelper.OpenInterestDisplayType.NetPosition;
double index = _cotreport.Commercial[0];
OwnSMA.Set(index);
}
I tried below code, but the system says: "
Object reference not set to an instance of an object"
Please help!
System.Reflection.PropertyInfo PropertyInfo = _cotreport.GetType().GetProperty("ContractType");
PropertyInfo.SetValue(_cotreport.Contract,"Gold",null);
PropertyInfo.SetValue(_cotreport.Contract,Convert.ChangeType("Gold",PropertyInfo.PropertyType),null);
You're trying to set get a property named "ContractType" on _cotreport and set it's value with on _cotreport.Contract. That's not going to work for two reasons.
The property name (from what I can tell in your code) is Contract not ContractType.
You need to set the value on _cotreport.
Try this instead
System.Reflection.PropertyInfo property = _cotreport.GetType().GetProperty("Contract");
property.SetValue(_cotreport, COTReportHelper.ContractType.Gold, new object[0]);
If you want to set the enum value by name, that's a separate issue. Try this
var enumValue = Enum.Parse(typeof(COTReportHelper.ContractType), "Gold");
property.SetValue(_cotreport, enumValue, new object[0]);
PropertyInfocould be null, and may not be if you used the property name: Contract. And you should be able to specify COTReportHelper.ContractType.Gold as the value directly. And you specify the property as the instance to be modified, but the PropertyInfo represents that, you should specify the owning instance on which the property value should be set.
Something like this:
System.Reflection.PropertyInfo PropertyInfo = _cotreport.GetType().GetProperty("Contract");
PropertyInfo.SetValue(_cotreport, COTReportHelper.ContractType.Gold, null);
This method sets value of property of any object and returns true if assignment was successfull:
public static Boolean TrySettingPropertyValue(Object target, String property, String value)
{
if (target == null)
return false;
try
{
var prop = target.GetType().GetProperty(property, DefaultBindingFlags);
if (prop == null)
return false;
if (value == null)
prop.SetValue(target,null,null);
var convertedValue = Convert.ChangeType(value, prop.PropertyType);
prop.SetValue(target,convertedValue,null);
return true;
}
catch
{
return false;
}
}

How to i return the value of a property if i dont know the propertyname at run-time?

And let's assume for simplicity that the value of the property needs to always be returned as a string.
public string GetTheValueOfTheProperty(PropertyInfo propertyInfo,Object myObject){
string propname = propertyInfo.Name;
if (propName == "IsSelected"){
return myObject.IsSelected.ToString();
}
//...
}
This works, but it doesn't work if I don't know the name of the property. How would I do that in that scenario ?
http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.getvalue.aspx
You can call propertyInfo.GetValue(myObject, null);.
You can convert to a string with ToString(), but you should check for null values first - otherwise you'll get a NullReferenceException.
The PropertyInfo object lets you invoke the property on the object:
object value = propertyInfo.GetGetMethod().Invoke(myObject, new object[] { });

how can I check whether the session is exist or with empty value or null in .net c#

Does anyone know how can I check whether a session is empty or null in .net c# web-applications?
Example:
I have the following code:
ixCardType.SelectedValue = Session["ixCardType"].ToString();
It's always display me error for Session["ixCardType"] (error message: Object reference not set to an instance of an object). Anyway I can check the session before go to the .ToString() ??
Something as simple as an 'if' should work.
if(Session["ixCardType"] != null)
ixCardType.SelectedValue = Session["ixCardType"].ToString();
Or something like this if you want the empty string when the session value is null:
ixCardType.SelectedValue = Session["ixCardType"] == null? "" : Session["ixCardType"].ToString();
Cast the object using the as operator, which returns null if the value fails to cast to the desired class type, or if it's null itself.
string value = Session["ixCardType"] as string;
if (String.IsNullOrEmpty(value))
{
// null or empty
}
You can assign the result to a variable, and test it for null/empty prior to calling ToString():
var cardType = Session["ixCardType"];
if (cardType != null)
{
ixCardType.SelectedValue = cardType.ToString();
}

What's the recommended way to start using types from a returned DataRow in C#?

When looping through a DataRow and encountering types such as
DataRow dr;
dr["someString"]
dr["someInteger"]
dr["somedata"]
What's the best way to get them into their corresponding data types? dr["foo"] is just a generic object.
Also, are these able to be easily converted to nullable types? dr["someInteger"] could be null.
When reading from a DataRow, your biggest enemy is a null value. In a DataRow, when a value is null, it is not equals to null: It is equals to DBNull.Value.
if(DBNull.Value == null)
{
// Will never happen
}
Unless you know that your field cannot be null, it is not safe to cast. For example, the following example will fail if the data is DBNull:
string name = (string)dr["Name"];
If you can use the LINQ extensions, you can include the reference System.Data.DataSetExtensions and the namespace System.Data and call
string name = dr.Field<string>("Name");
If you cannot use LINQ, then you have to fall back to checking for null value with
string name = null;
if(!dr.IsNull("Name"))
name = (string)dr["Name"];
Or you could code your own Field function like this:
public static T GetValue<T>(object value)
{
if (value == null || value == DBNull.Value)
return default(T);
else
return (T)value;
}
and get your value this way:
string name = GetValue<string>(dr["Name"]);
If you can use .net 3.5, then you can use the Field extension method to more easily access the data if you know the type. An example would be:
string somestring= row.Field<string>("SomeString");
Otherwise you're stuck with casting the field to the type of the object the old fashioned way.
Simply casting the values to the right type should work:
(string) dr["someString"];
(int?) dr["someInteger"];
(byte[]) dr["somedata"];
string GetString(DataRow dr, string ColumnName)
{
if (dr.IsNull(ColumnName))
{
return null;
}
return (string)dr[ColumnName];
}
Another option is to use "as"
string str = dr["someString"] as string;
if it's DBNull.Value (or any other object not of type string), then str will get a real "null". Otherwise it will get the proper string value.
For value types, you can use nullable, i.e.
int? i = dr["someint"] as int?;
Again, it will get a real "null" instead of DBNull.Value. However, with nullable types you have to remember to use .Value, i.e.
int x = i.Value + 5;

Categories