Passing multiple variables between pages and using them - c#

I have three variables I'm trying to pass from one page to another: Two checboxlists (just the checked values) and one DateTime.
I'm getting the checked items like this (this is just for one of these checkboxlists which is called lstUsers):
string cblvalues = "";
foreach (ListItem cbitem in lstUsers.Items)
{
if (cbitem.Selected)
{
cblvalues += cbitem.Value + "-";
}
}
cblvalues = cblvalues.Trim('-');
Response.Redirect("Results.aspx?cblvalues=" + cblvalues);
How would I pass the other checkboxlist and the DateTime to "Results.aspx" as well? I've seen a few different examples such as Server.Transfer, and I'm not sure which one is correct here.
And for using them on the Results.aspx page, would I just do:
string cblvalues = Request.QueryString["cblvalues"];

You can put as many values as you like on the query string. (Though as query strings get very long the web server would eventually impose a limit.) Here you simply append one key/value pair:
Response.Redirect("Results.aspx?cblvalues=" + cblvalues);
Just use a & to separate additional key/value pairs:
Response.Redirect("Results.aspx?cblvalues=" + cblvalues + "&moreValue=" + moreValues);
If you do get to the point where the query string becomes absurdly long and you basically have a lot of data to pass to the next page, then you'd be looking at other ways of doing this. A simple alternative may be to store the values in session state, redirect the user, then pull the values from session state. Something as simple as this:
Session["cblvalues"] = cblvalues;
Session["moreValues"] = moreValues;
Response.Redirect("Results.aspx");
Then in Results.aspx you can get the values:
var cblValues = Session["cblvalues"];
// etc.
You might also clear the session values once you get them, if the session doesn't need to keep carrying them:
Session.Remove("cblvalues");

You can pass multiple values through query string by seperated them with a &
so your snippet will be like the following:
Let cblSecond be the second combobox then;
// Building first value here
foreach (ListItem cbitem in cblSecond.Items)
{
if (cbitem.Selected)
{
cblSecondValues += cbitem.Value + "-";
}
}
Response.Redirect("Results.aspx?cblvalues=" + cblvalues + "&cblSecondValues=" + cblSecondValues);
So that you can access them separately like this:
string cblvalues = Request.QueryString["cblvalues"];// gives you the first value
string cblSecondValues= Request.QueryString["cblSecondValues"];// gives you the second value

Response.Redirect(String.Format("Results.aspx?value1={0}&value2={1}&value3={2}", Value1, Value2, Value3));

If you really want to pass them using querystring then you ahouls include them as well
Response.Redirect("Results.aspx?cblvalues=" + cblvalues + "&cblvalues1=" + cblvalues + "&datetimemy=" + datetimevalue);
Form of a query string like below
http://server_name/path/aspxfile?field1=value1&field2=value2&field3=value3..&fieldn=valuen
As other answer mentioned, there are multiple ways like using Session or cookies or as well you can expose those control values as public properties and use then in next page using Page.PreviousPage property but the restriction is that you will have to use either of Server.Transfer() or Server.Execute() method instead of Response.Redirect.

Related

Retrieving and updating data from InfoPath repeating tables

I've found this link helpful in getting data out of field in infopath. Unfortunately, after i attempt to set value back every time users made change on field, it appears to be infinite loop and cause error.
Here is my code:
XPathNavigator xNavigation = this.MainDataSource.CreateNavigator();
XPathNodeIterator xNodeIterator = xNavigation.Select(“/my:myFields/my:group1/my:group2”, this.NamespaceManager);
while (xNodeIterator.MoveNext()){
string mystring = xNodeIterator.Current.SelectSingleNode(“my:County”, this.NamespaceManager).Value;
xNodeIterator.Current.SelectSingleNode(“my:County”, this.NamespaceManager).SetValue("mystring"+ mystring);
}
What's the problem here? Please help me.
As I mentioned in the comments, you could use XPathNavigator to go through the list without using While loop:
EDITED, based on more info from comments:
foreach (XPathNavigator nav in xNavigation.Select(“/my:myFields/my:group1/my:group2”, this.NamespaceManager))
{
string mystring = myTextBox.Text + ", " + "GUID"; //replace "GUID" with the actual GUID which you need
nav.SelectSingleNode("my:field3", this.NamespaceManager).SetValue("mystring"+ mystring);
}
Basically, you should not get the value of the element/node, then set the same element/node's value after adding something to it. That will cause an exponential string expansion.

How to Avoid Updating item searched by Dictionary?

In .NET WinForms C# app, I have a Dictionary<string, RefItemDetails> collection named listItems. I store data in it on start of the app. In a static class I have as follows:
// listItems is populated bt reading a file.
// No other operations are performed on it, except finding an item.
public static Dictionary<string, RefItemDetails> itemsList;
// Find RefItemDetails of barcode
public static RefItemDetails FindRefItem(string barcode)
{
RefItemDetails itemDet = null;
try
{
//if (itemsList.TryGetValue(barcode, out itemDet) == false)
// System.Diagnostics.Debug.WriteLine("Barcode " + barcode + " not found in Items");
//itemDet = itemsList.First(item => item.Key == barcode);//.First(item => item.Barcode == barcode);
if (itemsList.ContainsKey(barcode))
itemDet = itemsList[barcode];
}
catch (Exception)
{
itemDet = null;
}
return itemDet;
}
For retrieving an item from listItems in another class, I use :
refScannedItem = null;
// Get Unit Barcode & Search RefItem of it
refScannedItem = UtilityLibrary.FindRefItem(boxItem.UnitBarcode.Trim());
// Display BOX item details
refScannedItem.Barcode = boxItem.BoxBarcode.Trim();
refScannedItem.Description = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
refScannedItem.Retail *= boxItem.Quantity;
refScannedItem.CurrentCost *= boxItem.Quantity;
Here what happens above is, I search for an item & I get it "refScannedItem" and I append the Description of it by "BOX of " + boxItem.Quantity + " " + refScannedItem.Description; . So if the original Description was "Aquafina", I make it "BOXof 10 Aquafina". The nest time I scan the same product, I find the product, but now its descrption has become "Box of 10 Aquafina", so my line of setting Description turns to "BOX of 10 BOX of 10 Aquafina". The same goes on like "BOX of 10 BOX of 10 BOX of 10 Aquafina" and so on.
As you cna see in my find code, I had initially used TryGetValue, then tried using LINQ, then tried using ContainsKey, but in all of them why does the value of listItem get updated.
I understand that as TryGetValue has out parameter, so the value is passed as a reference, and then it will be chnaged. But in listItems[key] also updates it !!! How can I avoid this to happen ? I had selected Dictionary collection for easy & fast searching, but this part gives a lot of problems and a big bug too on my app. I couldn't find nay solution where the receive the value but shouldn't be updated. All articles shows how to search & update it.
Kindly suggest a solution for the above. Any help is highly appreciated.
Thanks
You return a pointer to the item contained in your Dictionary, so it makes sense that any manipulations you make to this Object will be stored in the original Dictionary object.
What you want to do is, in FindRefItem, return a pointer to a copy of your RefItemDetails object.
An easy way to do this would be to write a new constructor.
Something like:
public RefItemDetails(RefItemDetails original)
{
this.Barcode = original.Barcode ;
this.Description = original.Description ;
this.Retail = original.Retail ;
this.CurrentCost = original.CurrentCost ;
//Set any other properties here
}
and then replace return itemDet; with return new RefItemDetails(itemDet);
I think you are going about this the wrong way.
You shouldn't have a writeable Description property that you update whenever the quantity changes.
Instead, I think you should have a separate Name property which contains the name of the item (e.g. Aquafina) and a dynamically-created readonly Description property like so:
public string Description
{
get
{
return string.Format("Box of {0} {1}", Quantity, Name);
}
}
Or something along similar lines.
This should do the trick:
if (!refScannedItem.Description.StartsWith("BOX of "))
{
refScannedItem.Description = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
}
You are getting an object from a Dictionary - and then changing it, so of course it's properties will change in the Dictionary as well ... you haven't cloned it so why would you be taking a copy?
The solution is quite simply not to change the values of the item and use the amended text in a different way:
var amendedDescription = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
Looks like you need to make a copy of the RefItemDetails to make modifications to after you get it back from the call to UtilityLibrary.FindRefItem(boxItem.UnitBarcode.Trim())

How can I output a list of field names and values that were changed?

I'm still learning C# whilst building an MVC web app. Trying to find a way to create a list of values that were changed by a user during an edit operation.
Here's one way I have that would work:
public List<string> SaveVehicleTechnicalInformation(VehicleAssetTechnicalInformationViewModel editmodel)
{
// Create a list of fields that have changed
List<string> changes = new List<string>();
var record = db.VehicleAssetTechnicalInformations.Find((int)editmodel.RecordID);
if (editmodel.Make != null && editmodel.Make != record.Make)
{
changes.Add(" [Make changed from " + record.Make + " to " + editmodel.Make + "] ");
record.Make = editmodel.Make;
}
if (editmodel.Model != null && editmodel.Model != record.Model)
{
changes.Add(" [Model changed from " + record.Model + " to " + editmodel.Model + "] ");
record.Model = editmodel.Model;
}
return changes;
}
But... As you can tell, I am going to need to write an IF/ELSE statement for every single field in my database. There are about 200 fields in there. I'm also worried that it's going to take a long time to work through the list.
Is there some way to go through the list of properties for my object iteratively, comparing them to the database record, changing them if necessary and then outputting a list of what changed.
In pseudo code this is what I guess I am after:
foreach (var field in editmodel)
{
if (field != database.field)
{
// Update the value
// Write a string about what changed
// Add the string to the list of what changed
}
}
Because I'm still learning I would appreciate guidance/tips on what subject matter to read about or where I can independently research the answer. The gaps in my skill are currently stopping me from being able to even research a solution approach.
Thanks in advance.
You can try to use Reflection for your purposes. Something like this
var fields = editmodel.GetType().GetFields();
foreach (var item in fields)
{
if (item.GetValue(editmodel) == database.field)
{
// Update the value
// Write a string about what changed
// Add the string to the list of what changed
}
}
I think I have found the hint I was looking for...
System.Reflection
More specifically, the FieldInfo.GetValue() method.
I was previously unaware of what System.Reflection was all about, so I'll research this area further to find my solution.

passing more than one variable to another page in asp.net

I want to pass more than one variable to other web pages.
I try this code
string adi = TaskGridView.SelectedRow.Cells[3].Text;
string soyadi = TaskGridView.SelectedRow.Cells[3].Text;
Response.Redirect("Default2.aspx?adi=" + adi);
Response.Redirect("Default2.aspx?soyadi=" + adi);
but it doesnt work how can I do?
The safest way is to use String.Format() with Server.UrlEncode():
Response.Redirect(String.Format("Default2.aspx?adi={0}&soyadi={1}", Server.UrlEncode(adi), Server.UrlEncode(soyadi)));
This will ensure that the querystring values will not be broken if there is an ampersand (&) for example, in the value.
Then on Default2.aspx you can access the values like:
Server.UrlDecode(Request.QueryString["adi"]);
Concatenate them like this:
Response.Redirect("Default2.aspx?adi=" + adi + "&soyadi=" + soyadi);
When passing query string parameters, use the ? symbol just after the name of the page and if you want to add more than one parameter, use the & symbol to separate them
In the consuming page:
protected void Page_Load(object sender, EventArgs e)
{
var adi = this.Request.QueryString["adi"];
var soyadi = this.Request.QueryString["soyadi"];
}
You can also use the session to pass values from one page to another
Set the values in the page where you want to pass the values from in to a session
Session["adi"] = TaskGridView.SelectedRow.Cells[3].Text;
Session["soyadi"] = TaskGridView.SelectedRow.Cells[3].Text;
In the Page where you want to retrieve- You do like this..
string adi=(string)(Session["adi"]);
string soyadi=(string)(Session["soyadi"]);
You can as well pass values through ViewState or Session the diffrent with what you doing now is: People will not see anything in your url and have no idea what happend in backend. It's good when you passing some "topsecret" data ;P

storing multiple values in single viewstate object

hi guy's here is one problem regarding asp.net state managenment.
I want to store three values into single viewstate.Is it possible to store in single or i will go for three viewstate variables.
the basic need is that,I am using gridview rowcommand event for finding three values.
and i wanted to use these values in button_click event.it is directely not possible so i prefer viewstate.
if any other way to do this you can post.I am new in .net development so please share some knowledge of you.
You can make a class, and mark it with a Serializable attribute. Then make a list instance of that class and store it as 1 item in the viewstate. This is when you have a lot of values to store. However yours is a simple case I think:
[Serializable()]
class SomeData
{
public string Value1 {get; set;}
public string Value2 {get; set;}
public string Value3 {get; set;}
}
Add to viewstate:
ViewState.Add("myData", new SomeData () {Value1 = "A",
Value2 = "B",
Value2 = "3"});
Retrieve back from ViewState on postback:
var data = (SomeData)ViewState["myData"];
Label1.Text = string.Format("{0}, {1}, {2}",
data.Value1, data.Value2, data.Value3);
You can use whatever separator you want.
But your code would be a lot cleaner if you used three separate variables.
Let .net handle the viewstate. Using one variable seems like an unnecessary complication.
In your scenario you don't need ViewState - you can store them in variables in the code behind because the rowcommand and button_click will both fire on the same post back. You only need to store items in ViewState if they're needed across post backs.
You can use any separator. For e.g.:
ViewState["items"] = item1 + "~" + item2 + "~" + item3
For retrieving values from ViewState, split the values by "~".

Categories