I have the following property:
IDictionary<string, object> Values { get; }
The property has a few values having one of them the key "culture".
I tried to use that value and casting to a string:
String value = (String)data.Values["culture"] ?? defaultCulture;
This works when the item has some value but when it doesn't I get the error:
Unable to cast object of type 'System.Web.Mvc.UrlParameter' to type 'System.String'.
BTW, System.Web.Mvc.UrlParameter:
http://msdn.microsoft.com/en-us/library/system.web.mvc.urlparameter%28v=vs.108%29.aspx
In the debugger data.Values["culture"] has the value {}. I tested and:
var test_1 = data.Values["culture"] == null; // returns false
var test_2 = data.Values["culture"].ToString() == null; // returns false
How do I check if data.Values["culture"] has something in it or not?
Apparently, you are storing a UrlParameter in that dictionary entry. If you want to get a string out, you will need to use ToString().
The exact expression to use will depend on the type of defaultCulture. If it is a string, then
String value = data.Values["culture"] == null ? defaultCulture : data.Values["culture"].ToString();
if it is a UrlParameter, then
String value = (data.Values["culture"] ?? defaultCulture).ToString();
If you want to get the string if it indeed is a string and a default value otherwise, you can test the type of the valuer using as. Something like:
(data.Values["culture"] as string) ?? defaultCulture
Try this:
String value = (String) (data.Values["culture"] ?? defaultCulture);
The idea is to check for null before trying to cast.
did you use this?
string.IsNullOrWhiteSpace(somestring)
Related
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.
_callReportCode = reader["Call Report Code"].ToString();
I am attempting to handle the possibility for the object I am calling ToString on to be NULL.
I am going to be using the above statement with several variables and I dont want to make an individual try/catch for each one... what is the best way to do null checking for strings.
Other datatypes ive been doing this:
int.TryParse(reader["Account Number"].ToString(), out _accountNumber);
In this code "reader" refers to a SqlDataReader but thats not really important for this question.
Use the null-coalescing operator: ??
callReportCode = (reader["Call Report Code"] ?? "").ToString();
If the data in your field is DBNull.Value (rather than null), this will still work, because DBNull.Value is not null, so the ?? won't be used, and DBNull.Value.ToString() is "", which is what you'd want.
Convert.ToString(reader["Call Report Code"]);
It will return string.Empty if the value is null.
Source: http://msdn.microsoft.com/en-us/library/astxcyeh.aspx
Update: it also works with DBNull, I've just verified.
Update 2: I decided to bring a more complete test here, just to be sure:
DBNull dbNull = null;
DBNull dbNullEmpty = DBNull.Value;
string stringNull = null;
string stringEmpty = string.Empty;
var outcome1 = Convert.ToString(dbNull);//Empty string
var outcome2 = Convert.ToString(dbNullEmpty);//Empty string
var outcome3 = Convert.ToString(stringNull);//NULL
var outcome4 = Convert.ToString(stringEmpty);//Empty string
If your string is nullable, you need to check the value returned from the SqlDataReader against DBNull.Value:
_callReportCode = reader["Call Report Code"] as string;
If the object returned by reader["Call Report Code"] is not a string, it's DBNull.Value, so the as cast is going to set the value of _callReportCode to null as well.
If you must set the string to a non-null in case the database value is missing, add ??, like this:
_callReportCode = (reader["Call Report Code"] as string) ?? string.Empty;
My suggestion is to never convert ToString when the data isn't a string, and if the data is already a string, then calling ToString is redundant, and a cast is all that's required.
I am making an assumption that the datatype in the database is integer, in which case, you can use a nullable int.
int? accountNumber = reader["Account Number"] == DBNull.Value ? null : (int?)reader["Account Number"];
I have made an extension method to do just this thing.
public static class SqlDataReaderExtensions
{
public static T Field<T>(this SqlDataReader reader, string columnName)
{
object obj = reader[columnName];
if (obj == null)
{
throw new IndexOutOfRangeException(
string.Format(
"reader does not contain column: {0}",
columnName
)
);
}
if (obj is DBNull)
{
obj = null;
}
return (T)obj;
}
}
Usage
int? accountType = reader.Field<int?>("Account Number"); // will return NULL or the account number.
The easiest way I have found is
_callReportCode = reader["Call Report Code"] + "";
i have some easiest and common Method.
public static string ToNULLString(this string Values)
{
if (string.IsNullOrEmpty(Values))
{
return "";
}
else
{
return Values.ToString();
}
}
use in C#
string item = null;
string value = item.ToNULLString();
you could create a method that you call when you want to make the check.
This way you have to type the try catch only once...
or you can create an extension method for string class to do this
_callReportCode = Convert.ToString(reader["Call Report Code"]) should ensure there are no null there.
Use following line of code:
_callReportCode = String.IsNullorEmpty(reader["Call Report Code"]) ?
String.Empty :
reader["Call Report Code"].ToString();
instead of the following line:
_callReportCode = reader["Call Report Code"].ToString();
I like using a combination of the null-coalescing operator and the null conditional operator:
string nn = MyObject.myNullableVar?.ToString() ?? "";
it's basically the same as this
string ss = (MyObject.MyNullableVar == null) ? "" : MyObject.MyNullableVar.ToString();
but shorter.
You can perform a check using String.IsNullOrEmpty() to ensure that it isn't going to be null, or you could write an extension method to perform some action if it's not null and another / nothing if it is.
I need to check if there is a param on the uri request.
So I need to check if that param is set. Is there a function on .NET/C#?
An unset value will be null or empty:
value = Request["param"];
if (String.IsNullOrEmpty(value))
{
// param is not set
}
If the param name is in the query string but the value is not, it will be empty. If the name is not in the query string, the value will be null. For example.
¶m1=¶m2=value
// Request["param1"] is String.Empty
// Request["param3"] is null
Yes, you can use HttpUtility.ParseQueryString() utility method which returns NameValueCollection and then cust call Get():
bool contains = HttpUtility.ParseQueryString(uri.Query)
.Get("ParameterName") != null;
Get() method
Returns A String that contains a comma-separated list of the values associated
with the specified key from the NameValueCollection, if found;
otherwise, null
EDIT:
If you have an instance of the HttpRequest then just use built in indexer like below:
bool contains = Request["ParamName"] != null;
In c# not implemented object is NULL. But if you try to acces to this object you will get the exception. You cat try to catch it or just add # before your variable.
So C# isset looks like this (for array of strings)
// Isset
internal static bool isset(String[] m, int index)
{
return (#m[index] == null) ? false : true;
}
Use it like this: if (App.isset(parts, 1)) cat = parts[1];
Or just "in plase" solution
if (#parts[1] != null) cat = parts[1];
I hope this ansver will help you.
You could use try and catch to wrap your uri request?
catch for NullReferenceException or just exception?
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[] { });
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;