FormatException 0 is not a valid value for Boolean - c#

I am getting a formatexception with the following code. Any one know how to make BooleanConverter convert from 0/1 to true/false.
bool bVal=true;
string sVal = "0";
Console.WriteLine(TypeDescriptor.GetConverter(bVal).ConvertFrom(sVal));
Thanks for the help!

Try the following
public static bool ConvertToBasedOnIntValue(string value) {
// error checking omitted for brevity
var i = Int32.Parse(value);
return value == 0 ? false : true;
}
Or you could use the following which won't throw exceptions but it will consider everything that is quite literally not 0 to be true
public static bool ConvertToBasedOnIntValue(string value) {
if ( 0 == StringComparer.CompareOrdinal(value, "0") ) {
return false;
}
return true;
}

If you're going to use Int32.Parse, use Int32.TryParse instead. It doesn't throw if the conversion fails, instead returning true or false. This means that it's more performant if all you're doing is checking to see if your input is a value. Example:
public static bool ConvertToBool(string value)
{
int val = 0;
return (int.TryParse(value, out val) && val == 0) ? false : true;
}
I have a tendency to go overboard on the ternary operator (x ? y : z), so here's a slightly easier-to-read version:
public static bool ConvertToBool(string value)
{
int val = 0;
if (int.TryParse(value, out val))
{
return val == 0 ? false : true;
}
return false;
}
(I tested them both. "1" returns true, "0" returns false.)

There are only two cases so can just check for them explicitly.

I just built a helper function that will handle the special case of booleans:
Private Shared Function StringConverter(ByVal colValue As String, ByVal propertyType As Type) As Object
Dim returnValue As Object
'Convert the string value to the correct type
Select Case propertyType
Case GetType(Boolean)
'Booleans need to be coded separately because by default only "True" and "False" will map to a Boolean
'value. SQL Server will export XML with Booleans set to "0" and "1". We want to handle these without
'changing the xml.
Select Case colValue
Case "0"
returnValue = False
Case "1"
returnValue = True
Case "False"
returnValue = False
Case "True"
returnValue = True
Case Else
Throw New ArgumentException("Value of '" & colValue & "' cannot be converted to type Boolean.")
End Select
Case Else
'Let .Net Framework handle the conversion for us
returnValue = TypeDescriptor.GetConverter(propertyType).ConvertFromString(colValue)
End Select
Return returnValue
End Function

Your original code was good enough, only you can't set the string value to "0" and "1". In your code, TypeConverter.ConvertFrom() will eventually invoke Boolean.TryParse(), the code for which looks like this (thanks Reflector!)
public static bool TryParse(string value, out bool result)
{
result = false;
if (value != null)
{
if ("True".Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = true;
return true;
}
if ("False".Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = false;
return true;
}
if (m_trimmableChars == null)
{
char[] destinationArray = new char[string.WhitespaceChars.Length + 1];
Array.Copy(string.WhitespaceChars, destinationArray, string.WhitespaceChars.Length);
destinationArray[destinationArray.Length - 1] = '\0';
m_trimmableChars = destinationArray;
}
value = value.Trim(m_trimmableChars);
if ("True".Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = true;
return true;
}
if ("False".Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = false;
return true;
}
}
return false;
}
So make the following change to your code and you should be good:
bool bVal = true;
string sVal = "false";
Console.WriteLine(TypeDescriptor.GetConverter(bVal).ConvertFrom(sVal));

string _sOne = "1";
string _sTrue = "TrUe";
bool _bRandom = !Convert.ToBoolean(__sTrue);
string _sResult = Convert.ToBoolean(_sOne);
string _sResultB = Convert.ToBoolean(_sTrue);
string _sResultC = _bRandom.ToString();

Related

Search if a string exists in a list

public bool VerifyId(List<string> sheetData)
{
if (sheetData.Where(q => q == "-1007401").First())
return true;
else
return false;
}
I have this bool function where if it finds that string, it returns true. But why is the Where not working?
I was able to fix it by using the list.Contains(string) function.
if (sheetData.Contains("-1007401")
return true
else
return false

How to combine multiple IF statements in C#

I have some flawed logic here..my goal is if all of the fields have "" value then return true, otherwise return false. How can I fix this in C# ?
public bool CheckFieldsAreEmpty()
{
Driver.WaitForElementValueNull(smtpHostInputField);
if (smtpHostInputField.GetAttribute("value") == "")
return true;
Driver.WaitForElementValueNull(smtpPortInputField);
if (smtpPortInputField.GetAttribute("value") == "")
return true;
Driver.WaitForElementValueNull(usernameInputField);
if (usernameInputField.GetAttribute("value") == "")
return true;
Driver.WaitForElementValueNull(passwordInputField);
if (passwordInputField.GetAttribute("value") == "")
return true;
Driver.WaitForElementValueNull(senderInputField);
if (senderInputField.GetAttribute("value") == "")
return true;
Driver.WaitForElementValueNull(receiverInputField);
if (receiverInputField.GetAttribute("value") == "")
return true;
else return false;
I believe something like this should work. I couldn't find what class all of those variables belong to, but replace var with the proper class and I think this should work.
logic: Add all variables to a List, use a lambda function to return if all of the list match GetAttribute("value") == ""
// Replace var with class type, or parent
List<var> allFields = new List<var> { smtpHostInputField, smtpPortInputField, sernameInputField, passwordInputField, senderInputField, receiverInputField };
foreach (var field in allFields) { Driver.WaitForElementValueNull(field); }
return allFields.All(t => t.GetAttribute("value") == "");
To illustrate #madreflection’s (correct) suggestion from the comments, consider this code:
public bool CheckFieldsAreEmpty()
{
Driver.WaitForElementValueNull(smtpHostInputField);
if (smtpHostInputField.GetAttribute("value") != "")
return false;
Driver.WaitForElementValueNull(smtpPortInputField);
if (smtpPortInputField.GetAttribute("value") != "")
return false;
Driver.WaitForElementValueNull(usernameInputField);
if (usernameInputField.GetAttribute("value") != "")
return false;
Driver.WaitForElementValueNull(passwordInputField);
if (passwordInputField.GetAttribute("value") != "")
return false;
Driver.WaitForElementValueNull(senderInputField);
if (senderInputField.GetAttribute("value") != "")
return false;
Driver.WaitForElementValueNull(receiverInputField);
if (receiverInputField.GetAttribute("value") != "")
return false;
return true;
}
Of course, as #Daniel-Lord’s answer highlights, you can centralize this repetitive logic using either a loop or a LINQ query.
Another way to solve this would be to extract WaitForElementValueNull call and empty string check to a separate method. Something like that:
private static bool WaitForElementValueNullAndEmpty(InputFieldType inputField)
{
Driver.WaitForElementValueNull(inputField);
return inputField.GetAttribute("value") == "";
}
public bool CheckFieldsAreEmpty()
{
return WaitForElementValueNullAndEmpty(smtpHostInputField) ||
WaitForElementValueNullAndEmpty(smtpPortInputField) ||
WaitForElementValueNullAndEmpty(usernameInputField) ||
WaitForElementValueNullAndEmpty(passwordInputField) ||
WaitForElementValueNullAndEmpty(senderInputField) ||
WaitForElementValueNullAndEmpty(receiverInputField);
}
The code above will match the algorithm that was provided, however if you want to check if ALL the values is empty then || should be replaced with && (As it was noticed by Jeremy Caney)

Word interop Range: expanding by a line unit considered a bad parameter

This is attempted inside an Application-level add-in.
The documentation for expanding a Range indicates that supplying a WdUnits parameter as a reference object should succeed. And it does, for most of the WdUnits collection. But, bafflingly, not for WdUnits.wdLine. The following code seems to always fail:
object lineUnit = WdUnits.wdLine;
var rng = document.Range(document.Content.Start, document.Content.Start);
// throws COMException with ErrorCode -2146824168: Bad Parameter
tempRange.Expand(ref lineUnit);
but the same operation on a Selection succeeds:
object lineUnit = WdUnits.wdLine;
document.Range(document.Content.Start, document.Content.Start).Select();
// Word groks this happily
Globals.ThisAddIn.Application.Selection.Expand(ref lineUnit);
Why on earth is this the case?
You know, I consider that a bug in the interop. The way I got around it was to use wdSentence and write other code for tables (to identify rows). I had to do this for my DeleteWhere wrapper method.
public bool DeleteWhere(string value, StringContentType type = StringContentType.Item, bool caseSensitive = true)
{
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
bool ret = false;
if (type == StringContentType.Line)
{
ret = DeleteRowWhere(value, caseSensitive);
}
object mytype = type.ToWdUnits();
if (type == StringContentType.Line)
{
mytype = Microsoft.Office.Interop.Word.WdUnits.wdSentence;
}
Microsoft.Office.Interop.Word.Range range = doc.Content;
object matchword = true;
while (range.Find.Execute(value, caseSensitive, matchword))
{
range.Expand(ref mytype);
range.Delete();
ret = true;
}
return ret;
}
private bool DeleteRowWhere(string value, bool caseSensitive = true)
{
bool ret = false;
string search = caseSensitive ? value : value?.ToUpperInvariant();
foreach (Microsoft.Office.Interop.Word.Table table in doc.Tables)
{
for (int x = 1; x <= table.Rows.Count; x++)
{
for (int y = 1; y <= table.Columns.Count; y++)
{
string val = caseSensitive ? table.Cell(x, y).Range.Text : table.Cell(x, y).Range.Text?.ToUpperInvariant();
if (val != null && val.Contains(search))
{
table.Rows[x].Delete();
ret = true;
}
}
}
}
return ret;
}

How can I validate something without using regular expressions in C#?

HI how can I validate a string, but without using regular expressions. For example how can validate this: xxx/xxxx where x is a digit? thanks
Something like that:
bool ValidateExpression(string expression)
{
string[] parts = expression.Split("/");
if (
parts.Length != 2
|| parts[0].Length != 3
|| parts[1].Length != 4
) return false;
int parsed;
return Int32.TryParse(parts[0], out parsed) && Int32.TryParse(parts[1], out parsed);
}
To be used later as
bool isValid = ValidateExpression("123/4567");
You can use Char.IsDigit to check if characters are a digit. For your specific case, you could do something like this:
public bool IsMyStringValid(string myString)
{
foreach(var c in myString)
if(!Char.IsDigit() && !c == '/') return false;
return true;
}
This is actually more specific to your case (3 digits, one '/' at index 3, followed by 4 digits):
public bool IsMyStringValid(string myString)
{
if(myString.Length != 8) return false;
for(var i = 0; i <8, i++)
if(!Char.IsDigit(myString[i]) || (i == 3 && myString[i] == '/') return false;
return true;
}
For that specific format you can use:
bool valid =
value.Length == 8 &&
value.Take(3).All(Char.IsDigit) &&
value[3] == '/' &&
value.Skip(4).All(Char.IsDigit);
Try this :
public bool ValidateString(string str)
{
var strArr = str.Split('/');
return strArr[0].All(char.IsDigit) && strArr[1].All(char.IsDigit);
}
hope this help;
I would use the .All to check something like this so no matter what the string is
if there is a non digit in it, it will not pass
public static bool IsMyStringValid(string strValidateString)
{
bool boolIsValid = false;
if (strValidateString.All(Char.IsDigit))
{
boolIsValid = true;
}
return boolIsValid;
}

C# If Statement with value from field in Table

How do I write this statement to get a value back from the database or table and validate that if the Value = Yes it will return the "Result =10" part. The field is called "ApprovedStatus" the value will either be "No" or "Yes".
Visual Studio Tells me this: "The name 'Yes' does not exist in the current context"
If (ApprovedStatus.Equals = Yes)
{
result = 10;
}
else
{
result = 1;
}
Try if (ApprovedStatus == "Yes") if it's a string, or if (ApprovedStatus) if it's a bool.
If ApprovedStatus is of type bool, do:
if (ApprovedStatus)
Should it be string, do NOT do this
if(ApprovedStatus == "Yes")
because this will equal false if ApprovedStatus = "yes"
Instead use
if(StringComparer.OrdinalIgnoreCase.Equals(ApprovedStatus,"Yes"))
result = 10;
else
result = 1;
Note that if you do
if (ApprovedStatus.ToString().ToUpper().Equals("YES"))
or
if( ApprovedStatus.Equals("whatever",StringComparison.OrdinalIgnoreCase))
it will throw a null reference exception if ApprovedStatus is null.
...which is possible to likely if the value comes from a database.
Best guess given the limited info available... (Assuming ApprovedStatus is a String)
if(ApprovedStatus == "Yes")
{
result = 10;
}
else
{
result = 1;
}
or
if(ApprovedStatus.Equals("Yes"))
{
result = 10;
}
else
{
result = 1;
}
Use String.Compare -- it's more efficient.
if(String.Compare(ApprovedStatus, "Yes", true)==0){
result = 10;
} else {
result = 1;
}
Boolean values in C# are true and false. You should consult a basic C# tutorial, but your check has probably to look like this:
if (ApprovedStatus)
{
result = 10;
}
else
{
result = 1;
}
It can be written shorter as:
result = ApprovedStatus ? 10 : 1;
if (ApprovedStatus.Equals("Yes")) <-- Case Sensitive
{
}
or
if (ApprovedStatus.ToString().ToUpper() == "YES")
{
}

Categories