I have this class:
public class address
{
public string address1;
public string address2;
public string city;
}
Now whenever a page load I fill these values based on the session userid in parent user control,
on_load of parent page
{
connect to database;
get the info
address.address1 = "171, broadway";
}
now across the child user controls on this page I want to use these values...
address.address1 and so on without hitting database again, this is a sample data actual data is long enough to use session.
What is the best way of doing it?
Save the Data in the current session and call it every time you need
This will help Storing custom objects in Sessions
If Data is too big then just bind the data to all controls before "get the info"
Add a property called Address to each UserControl that should have access to this data. Then in the parent UserControl, set this property for each control.
Related
I have a user control that is being integrated to the page on run time, now here on the page i have a few HTML control whose values need to save too, as i have written the save method logic to the user control because it has many content their to save in DB, but what i am missing is how to save the page content to the DB using the same Save Method?
If my understanding is correct, you just need to pass the values to the UC, just declare public properties in your UC and assign the values at runtime:
Check the following example:
Public properties approach
In the UC code behind
public string Street
{
get
{
return this.ViewState["c"] as string;
}
set
{
this.ViewState["c"] = value;
}
}
public void Save()
{
...
// your logic to save the UC data
// save the custom properties too, this.Street
{
In the ASPX code behind
this.myAddressTemplateControl.Street = myOtherControl.Text;
Accessing directly the page object
In the UC code behind
this.Page.FindControl("myPageControlID");
In my page i have used Session["user_id"] to know the status of user. Is there any page specific property to replace Session["user_id"].
Session is the best place to store user id!
You can wrap user id keeping using next extension method:
as far as Page.User returns IPrincipal then:
public static string UserId (this IPrincipal user)
{
get
{
return HttpContext.Current.State["user_id"];
}
set
{
HttpContext.Current.State["user_id"] = value;
}
}
Usage (inside a web page);
this.Request.User.UserId; // get, set
you can use a query string to store the user id instead of a session, moving it along from page to page.
another option is to use a viewstate, but this is limited per page and does not move along to other pages
I'm looking for some ideas to best persist an object over multiple page requests without the use of session variables, cookies, context cache, view state or a session database.
I have a web form (ASPX) that will contain several user controls that will act as "pages", and these controls will be displayed in a one-at-a-time-manner:
<uc1:UserControl1 id="controlStep1" runat="server" visible="true" />
<uc2:UserControl2 id="controlStep2" runat="server" visible="false" />
<uc3:UserControl3 id="controlStep3" runat="server" visible="false" />
I have an object that I use to contain various parameters. These parameters come into the application as query string values and this object lazy loads them. For example:
public class Situation
{
private string _jobId;
private JobType _jobType;
public string JobId
{
get
{
if (!String.IsNullOrWhitespace(_jobId))
return _jobId;
_jobId = GetFromQueryString("jid");
return _jobId;
}
}
public JobType JobType
{
get
{
if (_jobType != JobType.Default)
return _jobType;
_jobType = GetEnumFromQueryString("jtype", typeof(JobType));
return _jobType;
}
}
}
I'd like to persist this Situation object while the customer is in the web application, proceeding through a wizard-style interface as the user controls' visibilities are toggled. At the moment, I'm creating an instance of the Situation object in an HttpModule during the customer's first request and storing it in HttpContext.Current.Items, but I'd like to use lazy loading so that the various Situation object properties are only loaded as needed. However, if for example a property is accessed on controlStep1, I'd like to persist the state of the object so that if that same property is accessed on controlStep2, the getter doesn't have to go back to the query string to get the requested property's value. I could serialize the object and deserialize in an HttpModule, but if a property is accessed and loaded, it wouldn't be remembered on the next request.
Any suggestions?
File system is sometimes a useful persistance mechanism.
The users of my web application may have more than one browser window (or tab) open and pointed to the same page. We're using cookie based session id's, and the user will usually work within the same session id in both browsers/tabs. I would like to be able to uniquely identify which browser window (and tab) that requested an ASP.NET page (in order to make sure, that data stored in the session does not get mixed up).
(e.g. I would be happy if the browser would generate and send a window/tab-id with the http request, as it publishes HTTP_USER_AGENT)
Any ideas?
--thomas
If I was going to implement something like this I would probably start with a Dictionary<Type, List<Guid>> and store this in the users session. I would also probably make this be a custom type that delegates the dictionary and have a factory method that works similar to
public Guid GeneratePageIdentifier(Page thepage)
{
var guid = Guid.New();
if(_dictionary[thepage.GetType()] == null)
_dictionary[thepage.GetType()] = new List<Guid> { guid };
else
((List<Guid>)_dictionary[thepage.GetType()]).Add(guid);
return guid;
}
Then embed the guid that's returned from that method on the VIewState of the page. On your page methods that execute actions that you need to validate which page it is you would be able to validate that guid is inside the collection do something. You might also want to implement a custom a type with a guid property to enscapulate more information about why you're doing this or what you need for it to be meaningful.
The Viewstate on each page will be different, maybe you can use some kind of unique identifier created on every page loaded?
It is by default not possible due to the stateless nature of the web, but you could add a "page identifier" that gets generated with each opened page and transmitted for every action.
I'd recommend that you refactor the application in a way that those mixups can't happen, no matter from which page/tab/window the request originates.
As Mark Redman said, you can use Viewstate + Session in order to store values specific to the page.
ViewState is good for storing the key (string), Session for storing whatever type of complex objects.
Use the ViewState or a hidden field in order to load at the first call a GUID.
public string PageUid
{
get
{
if (ViewState["UID"] == null)
ViewState.Add("UID", Guid.NewGuid().ToString());
return ViewState["UID"].ToString();
}
}
Then use the session to get/set your values using this key:
string MyPagesessionVariable
{
get
{
if (Session["MYVAR" + PageUid] == null)
{
Session["MYVAR" + PageUid] = "VALUE NOT SHARED WITH OTHER TABS/WINDOWS";
}
return Session["MYVAR" + PageUid];
}
set
{
Session["MYVAR" + PageUid] = value;
}
}
Let's say I have a list of categories for navigation on a web app. Rather than selecting from the database for every user, should I add a function call in the application_onStart of the global.asax to fetch that data into an array or collection that is re-used over and over. If my data does not change at all - (Edit - very often), would this be the best way?
You can store the list items in the Application object. You are right about the application_onStart(), simply call a method that will read your database and load the data to the Application object.
In Global.asax
public class Global : System.Web.HttpApplication
{
// The key to use in the rest of the web site to retrieve the list
public const string ListItemKey = "MyListItemKey";
// a class to hold your actual values. This can be use with databinding
public class NameValuePair
{
public string Name{get;set;}
public string Value{get;set;}
public NameValuePair(string Name, string Value)
{
this.Name = Name;
this.Value = Value;
}
}
protected void Application_Start(object sender, EventArgs e)
{
InitializeApplicationVariables();
}
protected void InitializeApplicationVariables()
{
List<NameValuePair> listItems = new List<NameValuePair>();
// replace the following code with your data access code and fill in the collection
listItems.Add( new NameValuePair("Item1", "1"));
listItems.Add( new NameValuePair("Item2", "2"));
listItems.Add( new NameValuePair("Item3", "3"));
// load it in the application object
Application[ListItemKey] = listItems;
}
}
Now you can access your list in the rest of the project. For example, in default.aspx to load the values in a DropDownList:
<asp:DropDownList runat="server" ID="ddList" DataTextField="Name" DataValueField="Value"></asp:DropDownList>
And in the code-behind file:
protected override void OnPreInit(EventArgs e)
{
ddList.DataSource = Application[Global.ListItemKey];
ddList.DataBind();
base.OnPreInit(e);
}
Premature optimization is evil. That being a given, if you are having performance problems in your application and you have "static" information that you want to display to your users you can definitely load that data once into an array and store it in the Application Object. You want to be careful and balance memory usage with optimization.
The problem you run into then is changing the database stored info and not having it update the cached version. You would probably want to have some kind of last changed date in the database that you store in the state along with the cached data. That way you can query for the greatest changed time and compare it. If it's newer than your cached date then you dump it and reload.
If it never changes, it probably doesn't need to be in the database.
If there isn't much data, you might put it in the web.config, or as en Enum in your code.
Fetching all may be expensive. Try lazy init, fetch only request data and then store it in the cache variable.
In an application variable.
Remember that an application variable can contain an object in .Net, so you can instantiate the object in the global.asax and then use it directly in the code.
Since application variables are in-memory they are very quick (vs having to call a database)
For example:
// Create and load the profile object
x_siteprofile thisprofile = new x_siteprofile(Server.MapPath(String.Concat(config.Path, "templates/")));
Application.Add("SiteProfileX", thisprofile);
I would store the data in the Application Cache (Cache object). And I wouldn't preload it, I would load it the first time it is requested. What is nice about the Cache is that ASP.NET will manage it including giving you options for expiring the cache entry after file changes, a time period, etc. And since the items are kept in memory, the objects don't get serialized/deserialized so usage is very fast.
Usage is straightforward. There are Get and Add methods on the Cache object to retrieve and add items to the cache respectively.
I use a static collection as a private with a public static property that either loads or gets it from the database.
Additionally you can add a static datetime that gets set when it gets loaded and if you call for it, past a certain amount of time, clear the static collection and requery it.
Caching is the way to go. And if your into design patterns, take a look at the singleton.
Overall however I'm not sure I'd be worried about it until you notice performance degradation.