I'm Getting a querystring data in ASP.NET C# and I need both its string value and int.Parse value of it (if it can be parsed). (in the example I'm skipping checking for null values as it has no effect on my question)
value = Request.QueryString["value"];
id = int.TryParse(Request.QueryString["value"], out id)
the code above does what I need but I just got curious if I could write it in one sentence so I tried this:
if (int.TryParse(Request.QueryString["value"], out id))) value=Request.QueryString["value"];
in this case I don't get the string value if it can't be parsed but I will get Its parsed value.
Any suggestions? I don't have a problem with my code I'm just asking out of curiosity that if it can be done in single line of code.
The almost-one-liner version would be
// id and value still need to be defined, of course!
int.TryParse(value = Request.QueryString["value"], out id)
Your code shouldn't work: if id is an int it won't be able to hold the bool coming out from TryParse.
You can this out,
int id;
string value = int.TryParse(Request.QueryString["value"], out id)) ? Request.QueryString["value"] : null;
Inline output variables are supported with C# 7.0 (released back in March '17)
var value = int.TryParse(Request.QueryString["value"], out int id) ? Request.QueryString["value"] : null;
id (output variable) will contain the parsed value or default(int)
No, you do not (want) do assignments in conditionals.
Also, if you're assigning it to value then you should utilize value for efficiency.
value = Request.QueryString["value"];
id = int.TryParse(value, out id)
Lastly, you sure about id? You're assigning it to the boolean return of TryParse, yet assigning the out to it as well. I think your code is incorrect, though you say it is good.
I would assume you mean to do this:
var value = Request.QueryString["value"];
int id = -1;
if(int.TryParse(value, out id))
/* Do work here */
You cant declare it all on one line, but if you have multiple int variables you could delclare them all on one line.
Note: if int.TryParse fails is actually sets the out parameter to 0, with out parameters it needs to be assigned before leaving the method so I guess this is why.
eg:
private void test()
{
int id, id2, id3 = int.MinValue;
string value1 = int.TryParse(Request.QueryString["value1"].ToString(), out id) ? Request.QueryString["value1"].ToString() : null;
string value2 = int.TryParse(Request.QueryString["value2"].ToString(), out id2) ? Request.QueryString["value2"].ToString() : null;
string value3 = int.TryParse(Request.QueryString["value3"].ToString(), out id3) ? Request.QueryString["value3"].ToString() : null;
}
If we change Alex's answer to use out int id we don't even need to declare id in a separate line.
int.TryParse(value = Request.QueryString["value"], out int id);
I like my own personal example for others who may need it with null checking and returning both a string and a conversion. You could move the local string variable out if you needed to.
//Sets nUnitPrice to 0 if the value entered is not a double. If null remains 0.00.
if (dgvQuote[colUnitPrice.Index, nRow].Value != null)
{
var unitPriceSubString = dgvQuote[colUnitPrice.Index, nRow].Value.ToString().Replace("$", "").Trim();//Substring local variables reduce the number of times substringing needs to be called.
nUnitPrice = double.TryParse(unitPriceSubString, out _)
? Convert.ToDouble(unitPriceSubString)
: 0.00;
}
Related
I have a problem while reading my DataBase.
Until now I was sure that when I read some doubles from MySQL (they are stored as doubles not as strings / varchar), they are returned with a dot as decimal separator. (10.5). But now I notice that in fact, they are returned with a coma?
I lately created a new table (one month ago), but just now I noticed that its double values are returned with a comma , instead of the dot ..
I checked and the tables are all in uff8_unicode_ci.
I don't understand because I was sure that , could not be used in MySQL, also checked that on that link.
Nota : This is maybe due to the fact that I use several computers for tests, some are in French, some in Russian?
Edit :
To edit the table I do the following :
string request = "UPDATE [vegasteel].consumables SET ID_MACHINE=" + this.idMachine + ",GROUPE="PLASMA",TYPE=\'\',DETAIL=\'14\',SPEED=10.5,TIME=5.5,COST=0.5 WHERE ID=" + this.id;
DataBase.Update(request);
Then to read it :
if (this.OpenConnection() == true)
{
IDataReader dataReader = ExecuteReader(query);
while (dataReader.Read())
{
Consumable consumable = new Consumable();
consumable.ID = Convert.ToInt64(dataReader["ID"].ToString());
consumable.IdMachine = Convert.ToInt64(dataReader["ID_MACHINE"].ToString());
consumable.Groupe = dataReader["GROUPE"].ToString();
consumable.Type = dataReader["TYPE"].ToString();
consumable.Detail = dataReader["DETAIL"].ToString();
if(consumable.Groupe=="PLASMA")
{
string toto = "";
}
consumable.Speed = Global.ConvertToDouble(dataReader["SPEED"].ToString());
consumable.Time = Global.ConvertToDouble(dataReader["TIME"].ToString());
consumable.Cost = Global.ConvertToDouble(dataReader["COST"].ToString());
list.Add(consumable);
}
this.CloseConnection();
}
the Global.ConvertToDouble is a function I made to add a comma or a dot regarding the current culture. But the problem is when I read it, dataReader["COST"] equals 0,5, and not 0.5
Edit 2 :
As asked, here is Global.ConvertToDouble function, but as I explained the problem is before that function, as comma is sent instead of dot to the function.
public static double ConvertToDouble(this string strToParse, char decimalSymbol = '.')
{
if (strToParse.Contains('E'))
{
strToParse = "0";
}
string tmp = Regex.Match(strToParse, #"([-]?[0-9]+)([\s])?([0-9]+)?[." + decimalSymbol + "]?([0-9 ]+)?([0-9]+)?").Value;
if (tmp.Length > 0 && strToParse.Contains(tmp))
{
var currDecSeparator = System.Windows.Forms.Application.CurrentCulture.NumberFormat.NumberDecimalSeparator;
tmp = tmp.Replace(".", currDecSeparator).Replace(decimalSymbol.ToString(), currDecSeparator);
return double.Parse(tmp);
}
return double.NegativeInfinity;
}
You should not be converting the columns to string and then parsing them. You should read them directly as the type they are.
consumable.Speed = (double) dataReader["SPEED"];
or
consumable.Speed = Convert.ToDouble(dataReader["SPEED"]);
Note on null handling
(Thanks #mjwills for mentioning this)
The results from the db may contain null values and there are many ways of handling nulls in results with IDataReader (you can see SQL Data Reader - handling Null column values or Null safe way to get values from an IDataReader or search the broader web).
For example you will need to decide if you want null or default value (0 for double) when the return value is null.
To get you started here's a helper method (which can easily be changed into a extension method, and maybe even made generic so that you can deal with ints and other types).
public static double GetNotNullExample(IDataReader reader, string colName, double valueIfNull)
{
var colIndex = reader.GetOrdinal(colName);
if (!reader.IsDBNull(colIndex))
return reader.GetDouble(colIndex);
else
return valueIfNull;
}
What's happening
After you reinstalled your computer the culture has changed. The following snippet shows the impact of the culture on the ToString method.
double pie = 3.14; // ;)
CultureInfo.CurrentCulture = new CultureInfo("en-US", false);
Console.WriteLine(pie.ToString());
Console.WriteLine(pie.ToString(CultureInfo.InvariantCulture));
CultureInfo.CurrentCulture = new CultureInfo("ru-RU", false);
Console.WriteLine(pie.ToString());
Console.WriteLine(pie.ToString(CultureInfo.InvariantCulture));
Output
3.14
3.14
3,14
3.14
But I still want to ToString() and then parse
Don't.
If you were to continue ToString()->Parse approach, you would have to ensure that ToString is called with InvariantCuture.
consumable.Speed = Global.ConvertToDouble(dataReader["SPEED"]
.ToString(CultureInfo.InvariantCulture));
Whenever I open my form (the one which stuff is being sent to) it crashes because a of a certain part. The part that is breaking it is Convert.ToInt32(txt_cost). Im looking to know how this should be sent to my other form without crashing the program
private void btn_HomepageSearch_Click(object sender, EventArgs e)
{
if (isValidData())
{
string destination = cbo_Destination.Text;
DateTime checkIn = date_FlightDate.Value;
frm_BookingPg frm_HomePge = new frm_BookingPg(cbo_Destination.Text, cbo_AmountOfPeople.Text, Convert.ToInt32(txt_cost));
frm_HomePge.Show();
this.Hide();
}
}
Assuming you have an integer in your text box, i believe that should be
Convert.ToInt32(txt_cost.Text)
if it still crashes then the value of txt_cost can't be a valid int. try the below
var intValue = 0;
if (int.TryParse(txt_cost.Text, out intValue))
{
//do something with intValue
}
EDITED
( Code part from the comment of #Minimarshman ) :
case "ten":
price1 = 10;
break;
decimal total = price * price1;
txt_cost.Text = total.ToString("c");
So as you can see you're converting decimal to string and then assign that into a TextBox's Text property.
ALWAYS leave some margin for errors especially when you're doing software development. Meaning that you should NEVER TRUST that user will use your software as it was intended. Your usage of Convert.ToInt32(txt_cost) shows that you trust your/user data too much.
To deal with this you have to check every data that you're converting if it really is a valid data. c# has many built-in methods/functions that will validate that and the one you should use is decimal.TryParse which ensures that data is valid for the type conversion.
Another thing is that you're using special format for your ToString ("C") which indicates that it should put currency mark in the string. You have to remember to then get rid of this.
Code explanation :
decimal IfValueIsConvertibleItWillBeHeldHere = 0;
if(decimal.TryParse(txt_cost.Text.Split(' ')[0], out IfValueIsConvertibleItWillBeHeldHere)
{
frm_BookingPg frm_HomePge = new frm_BookingPg(
cbo_Destination.Text,
cbo_AmountOfPeople.Text,
(int)IfValueIsConvertibleItWillBeHeldHere // see the difference ?
);
frm_HomePge.Show();
this.Hide();
}
else
{
// show some message to the user that input was invalid
}
Remarks :
Doing so leaves you with chaotic code because converting from decimal to int using explicit type conversion will trim that value. For example decimal d = 0.5M; explicitly converted to int like int i = (int)d; will return 0 because it trims down the part after decimal mark ..
You should rewrite your frm_BookingPg to accept decimal type instead of int type so that the value will be accurate :
public frm_BookingPg(string destination, string amountOfPeople, decimal cost)
Instead of your actual :
public frm_BookingPg(string destination, string amountOfPeople, int cost)
Have you tried replacing
Convert.ToInt32(txt_cost)
with just an int32 literal value?
As follows:-
frm_BookingPg frm_HomePge = new frm_BookingPg(cbo_Destination.Text, cbo_AmountOfPeople.Text, 1234);
does it still crash?
I am new to c# programming and I recently bumped into one problem which looks pretty basic.I store the string value like SV_1 in the variable lastServiceNo and split it using Split function and the result is stored in string array called index.Basically index[1] has some numeric value bt as string. now I want to convert string into int. In the following code , it behaves as expected until parse function is encountered.I could not understand why does this parse function returning 0 as index[1] has some numeric value in it. Can somebody point the problem please??
public string GenerateServiceNo() {
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return "SV_"+(lastIndex++).ToString();
}
int.Parse(string s) throws an exception if the number is too bug in terms of data size or the string "s" is not in the correct numerical format.
The format that this method accepts is "[ws][sign]number[ws]" where:
[ws] is optional for one or more whitespace(" ")
[sign] is optional for "+" or "-"
Check here for the full reference.
Thus said, I can assure you that if int.Parse(index[1]) returns 0 then that means index[1] equals "[ws][sign]0[ws]" using the transcript above.
However, looking at your code, I can conclude that you're incrementing a local variable after assignment without using its incremented value afterwards. Perhaps you meant that this operation shouldn't be 0?
If that's the case then I believe this is what you're trying to achieve:
public string GenerateServiceNo()
{
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return string.Format("SV_{0}", ++lastIndex);
}
Assuming index[1] == "0", this method will now return "SV_1".
Input string was not in correct form.
I'm getting an exception on runtime as "System.FormatException".
Follwing lines shows exception-
public int Task
{
get
{
return Int32.Parse(TaskText.Text);
}
set
{
TaskText.Text = value.ToString();
}
}
public int Project
{
get
{
return Int32.Parse(ProjectText.Text);
}
set
{
ProjectText.Text = value.ToString();
}
}
I also tried -
Convert.ToInt32(TaskText.Text)
Convert.ToInt32(ProjectText.Text)
I need to pass these to following constructor,
Harvest_TimeSheetEntry entry = new Harvest_TimeSheetEntry(client,starttime,stoptime,task,project);
this constructor is stored in some class with task and project as integer parameters. And I can't change it because if i changed, it affects other code.
It looks as though you're getting your input from controls accepting user input, which is just asking for failure, since a user can potentially enter something that doesn't represent an integer value. You can use TryParse to avoid this:
var result = 0;
if (int.TryParse(TaskText.Text, out result)) {
return result;
}
return 0;
So, if the value of TaskText.Text == "1", this will succeed; if the value of TaskText.Text == "aaaa", this will fail - and return zero. You example would raise the appropriate exception, as experienced.
However, an exception might be the right thing to happen here, if you can't handle a bad value, don't have an alternative, and the application relies on the input to move forward. More likely, you could do with some validation on your input fields to prevent bad data being submitted.
Since your Harvest_TimeSheetEntry constructor expects task and project to be integers, you must have a list of integers that correspond to the different tasks and projects. Now you can't expect Int32 to know which task corresponds to which number, can you?
I would suggest you use ComboBoxes for TaskText and ProjectText. Then, you can assign the correct corresponding integer to each ComboBoxItem.Tag.
Please note that this goes far beyond the kind of answers you should expect from SO.
if you do not use MVVM or binding you can simply do the check before your need it. t
int task;
int project;
if(!Int32.TryParse(TaskText.Text, out task))
{} //errorhandling here
if(!Int32.TryParse(ProjectText.Text, out project))
{}//errorhandling here
//all fine
var entry = new Harvest_TimeSheetEntry(client,starttime,stoptime,task,project);
You must check if you can parse it into Integer
try
Int32 foo =0;
if (Int32.TryParse(TaskText.Text, out foo))
{
return foo;
}
On the previous page i have
protected void SqlCheckout_Inserted(object sender, SqlDataSourceStatusEventArgs e)
{
string CustID;
if (e.Exception == null)
{
CustID = e.Command.Parameters["#CustomerID"].Value.ToString();
Response.Redirect("Payment.aspx?id=" + CustID);
}
}
Then on my payment page
protected void DetailsView1_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
int intCustID;
int intOrderID;
intCustID = int.Parse(Request.QueryString["CustomerID"]);
//save shopping cart
ShoppingCart objCart;
//retreive shoppping cart from session
objCart = (ShoppingCart)Session["shoppingCart"];
//the shopping cart cannot be empty
if (objCart != null)
{
//save Cart
intOrderID = objCart.SaveCart(intCustID);
e.Values["OrderID"] = intOrderID;
Session["OrderID"] = intOrderID;
}
else
{
e.Cancel = true;
}
}
Im following a tutorial EDIT: That allows me to insert data into a database, and for some reason at this line of code Im getting an error saying Input string was not in correct format EDIT: and The ' value cannot be null' ... any tips?
The querystring parameter id is not an integer.
If you're unsure of the validity of a parameter, use TryParse instead.
int intCustId;
if(int.TryParse(Request.QueryString["id"], out intCustId)
{
// Do stuff
}
else
{
// Handle error
}
First, make sure Request.QueryString["id"] is not null or empty.
int intCustID = string.IsNullOrEmpty(Request.QueryString["id"]) ? 0 : int.Parse(Request.QueryString["id"]);
This will:
Check if your Request.QueryString["id"] is null or empty.
if yes, it will return zero otherwise, it will parse the string to int
Assign parsed int value to intCustID
You can also use :
int intCustID = Convert.ToInt32(Request.QueryString["id"]);
Based on your comment:
Im getting an error saying Input string was not in correct format
EDIT: and The ' value cannot be null' ... any tips?
It sounds like when you arrive on this page you do not have id in the query string. So most likely your url looks like this:
http://mysite.com/mypage.aspx
and it needs to look like this:
http://mysite.com/mypage.aspx?id=1234
In order to fix this you will most likely need to go to the previous page (the page that you navigate TO the page with the error FROM) and figure out why id isn't getting passed in the query string.
UPDATE
Your original code suggested you were trying to pull:
Request.QueryString["id"]
While your update suggests:
Request.QueryString["CustomerID"]
Based on your comment below neither of these are correct. You need to match the query string exactly (including case). Try the code below:
Request.QueryString["ID"]
As other's have mentioned you should probably be using TryParse also.
This means that the the string that Request.QueryString["id"] returns is not an integer.
What you get is probably either
empty, so that you are trying to convert an empty string
a non-numeric string, which obviously cannot be converted to an integer
a decimal format number, like "5.0", instead of "5", which also would give this exception. In that case you can use double.Parse instead, and convert to int afterwards.