For starters, please forgive me and please correct me on my terminology. I am quite sure of the correct words to use for what I am trying to accomplish.
I have been given the task of building an ASP.Net Razor web site. It is something new to me. I am very proficient in PHP and ASP Classic. What I need to be able to figure out is how to declare a variable that is accessible everywhere. I do not know if in the .net world you call it a global variable or application variable or something else. But, here is how I would do this in Classic ASP.
In Classic ASP, I would have a file named VarFunct.asp. It would be the file that I declare my variables and have various functions I would access from anywhere. I would include the VarFunct.asp file on all of my pages. Anyway this is what I am really trying to do (written in how I would do it in Classic ASP)…
SelLoc = Request("SelLoc")
If Len(Trim(SelLoc)) = 0 Then
SelLoc = "All"
End If
In this case, Request("SelLoc") could be Request.QueryString or Request.Form. Then anywhere in my website I could use the variable SelLoc. So, in short... I need to be able to set a variable. Check to see if it is set by Request.Form, if not, check Request.QueryString, if not set the value to “All”. How do I write this? And where do I put it?
When I created the website using Visual Studio 2012, I selected ASP.NET Web Site (Razor V2).
This seems like it should be such a basic fundamental task of any website that has any kind of server side programming, but trying to find information and documentation online is near impossible, but probably because I am not using the correct terms for my question. I have not found any Razor tutorials that talk about setting variables that can be used globally across the website.
If someone could please help me out here by either telling me what I need to do or point me to a good tutorial, that would be great.
what you are looking for is called Static Class/Member
This will allow you to store and share data for the whole application.
BUT! since web server is multi-threaded, you wouldn't want to do this or else you might run into the case where the data is overwritten by another request before you finished the current one.
If you need to pass data from controller to your View you can use ViewBag dynamic object
If you need to use the data anywhere else (for example in a helper class) then do
HttpContext.Current.Application["VariableName"] = something
It is basically a dictionary and each request will have a different Application object
There are several ways of doing this.
For your example I would assume that this particular variable can be different for different users that are using the application at the same time. This is more of a Session scope than Application scope.
In this case you could simply use inheritance and make a base controller and/or base view model class that all your other controllers and/or view models inherit from. This way you can pass it back and forth between the view and controller and read/update it whenever you need to.
You could also use the Request and HttpContext and Session objects that are built into asp.net, if they fit your need. A brief overview of some of their functionality can be found here: https://learn.microsoft.com/en-us/aspnet/web-pages/overview/api-reference/asp-net-web-pages-api-reference --- google searching specific ones yields tons of results.
If you truly want Application scope, you can of course use a static class for you utilize static methods. Then you don't need to include the class in every other class, but you would need to fully name qualify the method when you call it.
I would not recommend static variables at this level though. I can't imagine very many things that would need to change for every single user that you would change while the application instance is running. Most of these sorts of items that we use are caches (generally db lookups and such, that we don't want to retrieve from the db each time, and RARELY get updated). If you utilize caches, be very aware of your thread safety when updating them. Here is an msdn on caching: https://msdn.microsoft.com/en-us/library/aa478965.aspx --- Or application configuration settings, like the application environment. We pull most of those from a config file, and they are read only, we don't change them within a running instance of the application.
Related
My project group and I are to develop a generic workflow system, and have decided to implement a single Node (a task in the workflow) as a C# Visual Studio Web API project (Using the ASP.NET MVC structure).
In the process of implementing a Node's logic, we've come across the trouble of how to store data in our Node. Our Node specifically consists of a few lists of Uri's leading to other Nodes as well as some status/state boolean values. These values are currently stored in a regular class but with all the values as internal static fields.
We're wondering if there's a better way to do this? Particularly, as we'd like to later apply a locking-mechanism, it'd be prefereable to have an object that we can interact with, however we are unsure of how we can access this "common" object in various Controllers - or rather in a single controller, which takes on the HTTP requests that we receive for ou Node.
Is there a way to make the Controller class use a modified constructor which takes this object? And if so, the next step: Where can we provide that the Controller will receive the object in this constructor? There appears to be no code which instantiates Web API controllers.
Accessing static fiels in some class seems to do the trick, data-wise, but it forces us to implement our own locking-mechanism using a boolean value or similar, instead of simply being able to lock the object when it is altered.
If I am not making any sense, do tell. Any answers that might help are welcome! Thanks!
Based on your comments, I would say the persistence mechanism you are after is probably one of the server-side caching options (System.Runtime.Caching or System.Web.Caching).
System.Runtime.Caching is the newer of the 2 technologies and provides the an abstract ObjectCache type that could potentially be extended to be file-based. Alternatively, there is a built-in MemoryCache type.
Unlike a static method, caches will persist state for all users based on a timeout (either fixed or rolling), and can potentially have cache dependencies that will cause the cache to be immediately invalidated. The general idea is to reload the data from a store (file or database) after the cache expires. The cache protects the store from being hit by every request - the store is only hit after the timeout is reached or the cache is otherwise invalidated.
In addition, you can specify that items are "Not Removable", which will make them survive when an application pool is restarted.
More info: http://bartwullems.blogspot.com/2011/02/caching-in-net-4.html
I am developing an ASP.NET MVC 5 application and I need to manage some global parameters, which are basically just a set of key-value-pairs. My requirements are the following:
Initial values are read from a server config file.
Parameters are available in every controller for both reading/writing and adding/deleting (like a new parameter can be added if certain controller is executed).
Parameters should surface subsequent request (either residing in Session or serialized in QueryString).
I should be possible to see and easily manage them (CRUD) using a special admin webpage.
My "brute force" approach for this would be just to implement a static class with List<Tuple<string,string>> to keep the settings, use System.Web.Configuration.WebConfigurationManager to populate initial values, use static properties to store and retrieve the list in a session variable and design a separate controller and view for managing the settings.
But this looks like re-inventing the wheel to me. Is there any (not necessarily full-fledged) pre-existing solution (in ASP.NET, or as a NuGet package) I might rest my efforts upon? Or maybe I am missing something fundamental in ASP.NET?
UPDATE: Depending on the nature of the parameter, some of them might have the lifetime of the Application, whereas some of them are bound to the current user session. Therefore they need to be either preserved in a Session object or "passed through" in every request.
That sounds like the most common approach, I don't see anything wrong with using session variables.
I am forced to use static variables because of the asp.net execution path. I have to have the same variables on the master page as well as the page being called. Static variables make it very easy to carry over variables because they remain static. Unfortunately these variables hang in the ether of memory because the app hasn't actually "exited". Is there a way to destroy these variables when I finished used them? I looked into
IDisposable
but its implementation is not... clean. Is there a way to destroy variables when the page finishes rendering?
I am forced to use static variables because of the asp.net execution path. I have to have the same variables on the master page as well as the page being called. Static variables make it very easy to carry over variables because they remain static.
You aren't "forced" to use static fields just to share data between a master page and its content page. You probably don't want to either: static fields will be shared between all requests from all users of your application, which means they need to be thread-safe and limited to data that is shared between all users.
There are many techniques to share data between master and content page. For example, you could use the HttpContext.Items dictionary, which exists only for the duration of a single request.
For anyone looking for a way to "pretend" static variables, here is how you can go about it:
public static Datatype data
{
get
{
return (Datatype)HttpContext.Current.Items["DATA"];
}
set
{
HttpContext.Current.Items["DATA"] = value;
}
}
As far as I understand this doesn't necessary solve the "kill static" values, but it should avoid any data collisions caused by static variables. I had my entire project referencing the static variable and changing it would of created more messy code than should be seen. This way, when the call goes out to get "DATA" from your static object, it doesn't grab whatever pointed at but rather uses the context list which gets killed after and is unique to your session.
You can set them to null. If you're using ASP.Net WebForms you can do this inside the Page.Unload event handler.
You should avoid using static properties in your master page and use Session[""] variables, they will be destroyed when the user ends the session.
Without knowing your setup, and thinking in a future of cloud environment as well, where you can have more than one server answering user requests and, you have no idea if the same server will answer all the requests of that user or the load balancer ask the other servers to continue, I would, as I currently do, give you 2 options
Before the options, in a Web Environment, it is good pratice to stop using Sessions or Static variables (for the reason above)
Use cookies
Why not use a cookie to pass value from one place to the other and when consumed, simply write the expiration data back one year and the cookie is gone!
Use MemCached
I always have a Cache layer between my application and the database, and it's the best way to keep values, not only from the database to provide to all users, but a good way to keep variables when we need cross application.
MemCached is free and runs fine on windows, plus there are several Cloud Services that offer this in their servers
I am using Monotouch to develop an iPhone App. I am using a web request to call a service that returns a cookie. My main aim is to be able to use the cookie as needed for web requests in various view controllers. I am assuming using the Shared Storage for the cookie is the way to go.
I have had a go at this and found the following hurdles:
The HttpWebResponse has a cookie collection made up of System.Net.Cookie objects.
The NSSharedStorage object only takes NSHttpCookie objects.
I haven't been able to figure out a way to turn a System.Net.Cookie object into an NSHttpCookie object. This is mainly because NSHttpCookie has only readonly properties and I am not sure how to create one using the constructors/static functions in C#.
So I really have two questions:
Is inserting the cookie into shared storage the best way to achieve my aim?
If so, how do I do this?
UPDATE:
Just to clarify a little further. The answer here is doing the opposite of what I want to do.
I don't think there's such thing as a NSSharedStorage. Is NSHTTPCookieStorage what you mean? If so, this wouldn't work for you. As per the documentation: "Cookies are not shared among applications in iOS". There also isn't a quick way to do what you want. You'll have to do something like what is suggested in the link you provided in your update. i.e. create an extension method (or some kind of utility method) that does the conversion.
You will likely have to manage your own collection of System.Net.Cookies in your app.
Membership.ApplicationName is a static string.
My issue is that if i want to change this value to interogate the membership of another application on the same database, the change is permanent, meaning the Application Name for the current site has now globally changed to this value.
In a perfect world i could call Membership.GetUser($username, $ApplicationName), but such a function doesnt exist.
Can anyone offer any ideas?
The Membership.ApplicationName is global by design. The MSDN documentation states that if you need an application that can change this value, it should be a single user app.
http://msdn.microsoft.com/en-us/library/system.web.security.membership.applicationname.aspx
(Read the Caution section under Remarks)
There are two alternatives to solving your problem:
1) Create a separate application for administering the users.
2) Write a custom Membership Provider that has the method you suggested. You would need to write the data access layer as well but the DB structure is well defined so it shouldn't be too hard to do.