in my page1.aspx.cs I have this
resultsHtml.Append("<a class='btn btn-warning' href='report.aspx?asset=" + rd["n_asset_id"].ToString() + "'><i class='fa fa-paw'></i></a> ");
so in my report.aspx I will catch the value.
Session["passThis"] = Request.QueryString["asset"];
However in my action.cs I created a class that will store the list. I'm thinking of adding a session there but everytime i will the store() it will just create another List.
public static void store() {
List<string> ast = new List<string>();
}
How can I achieve this feat? I'm running out of ideas.
I think that the best approach would be to extract assets list into property (so you can easily access it from other parts of code. In property getter, code checks if there's list in session.
In Store method you're accessing List of assets (List<string) and, if there is asset parameter in current Request, adds it to your list of assets. Notice that accessing Session is done through HttpContext.Current.Session because of static metod/property.
public static void Store()
{
string assetValue = HttpContext.Current.Request["asset"];
if (!string.IsNullOrEmpty(assetValue))
AssestsList.Add(assetValue);
}
public static List<string> AssestsList
{
get
{
if (HttpContext.Current.Session["assets"] == null)
{
HttpContext.Current.Session["assets"] = new List<string>();
}
return HttpContext.Current.Session["assets"] as List<string>;
}
set
{
HttpContext.Current.Session["assets"] = value;
}
}
so, to use this, just call Store() from your code.
If you have some questions, feel free to ask.
Related
Hey all new to the MVC world so I'm sure I am not doing something correct here. I am trying to call a function from the model page from my view index page to populate some tooltips.
In my model:
public class tips
{
public List<string> allTips()
{
List<string> theTips = new List<string>();
theTips.Add("example 1");
theTips.Add("example 2");
return theTips;
}
private List<string> _tips;
public List<string> getTips { get { return _tips; } set { _tips = allTips(); } }
}
And in my view:
public ActionResult Index()
{
var blah = new tips().getTips;
ViewBag.pageTips = blah;
return getMainData();
}
And then I have this on the razor page:
#Html.Raw(ViewBag.pageTips[1])
Which should display example 2 on the page but instead it just displays null as the value for the toolTips.
Currently it has a value of null when it gets to the return for the pageTips in my view.
So what would I be doing incorrectly? I put some stops here and there and notice that it never calls the allTips() function so that's a good starting place as to what I need to do in order to do that.
I just figured that calling the .getTips would fire off the theTips function?
You seem to be confusing constructors with properties in your model, which is very strange. I suspect you want something like this instead:
public class TipsObj
{
// a property
public List<string> Tips { get; set; }
// a constructor
public TipsObj()
{
Tips = new List<string>();
Tips.Add("example 1");
Tips.Add("example 2");
}
}
The idea here is that the constructor is called by default when you create a new instance of the object, so your Tips property will automatically be populated right away just by creating an instance of this.
Then in your controller action you can simply do this:
var tips = new TipsObj();
ViewBag.pageTips = tips.Tips;
Which will create an instance of the TipsObj and set a ViewBag property to the Tips property of that instance. Which was initialized in the constructor of that object.
Note that none of this really has anything to do with MVC, this is just creating an object in C# and using a property on that object.
Note also that I changed some of the names here. In C# class names should begin with a capital letter. Also, you don't want to call everything "tips" (and you don't want to call anything "blah"). Using meaningful and intuitive names makes your code easier to understand, which will help you understand what you're writing.
You are misunderstanding the concept of setter and using it as an "initializer", a setter is meant to set the value, to change it in other word. if you want to initialize it do it in the constructor.
Here you are using two different Lists, I don't really know why.
A working code would be:
public class tips
{
public tips()
{
_tips = new List<string>();
_tips.Add("example 1");
_tips.Add("example 2");
}
private List<string> _tips;
public List<string> getTips { get { return _tips; } set { _tips = value; } }
}
Then in the controller:
ViewBag.pageTips = new tips().getTips;
Then call it this way in the view:
#Html.Raw(ViewBag.pageTips[1])
Change your model like the following:
public class Tips
{
private List<string> _tips {get; set;}
public Tips()
{
_tips = new List<string>();
_tips.Add("example 1");
_tips.Add("example 2");
}
public List<string> getTips()
{
return _tips;
}
}
Then use it :
ViewBag.pageTips = new Tips().getTips();
There are a few things wrong here, but I'll start with answering your question directly... the reason ViewBag.pageTips[1] is null is because you never initialize the _tips array in your model. The only code that would do that is in the getTips property's setter, which is never invoked. If you attach a debugger it'll be apparent :)
You could refactor this in a few ways, including changing the allTips() method to a constructor, and initializing your collection there.
I don't want to put an example of that directly though. You mentioned you were new to MVC, so I want to show you how this should really be done. One of the big benefits of MVC is Model Binding, so forget about ViewBag.
Try this instead:
The Model
using System.Collections.Generic;
namespace WebApplication1.Models
{
public class TipsModel
{
public List<string> Tips { get; }
public TipsModel()
{
Tips = new List<string> {"example 1", "example 2"};
}
}
}
The Controller
public ActionResult Index()
{
var model = new TipsModel();
return View(model);
}
The View
#model WebApplication1.Models.TipsModel
#{
ViewBag.Title = "Index";
}
#Model.Tips[1]
I want to store static values in a class for later use use on any page in the web. The values will be the same for all users.
Page_Init: Retrieve global variables from their respective sources and assign them to their static objects inside the classes within the GlobalStaticVariables class.
I call to set the static values from the MasterPage like so
protected void Page_Init(object sender, EventArgs e)
{
Web.StartUp.SetGlobalStaticVariables(this.Page);
}
///Removed most objects for the sake of brevity
public static Info.GlobalStaticVariables SetGlobalStaticVariables(object _this)
{
Info.GlobalStaticVariables.Some_StringValue = ConfigurationManager.AppSettings["Some_StringValue"].ToString();
Info.GlobalStaticVariables.Database.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
Info.GlobalStaticVariables.IIS.DomainName = ((Page)_this).Request.Url.Host;
}
///Removed most objects for the sake of brevity
public class Info
{
public class GlobalStaticVariables
{
public static string Some_StringValue { get; set; }
public class Database
{
public static string ConnectionString { get; set; }
}
public class Ldap
{
public static List<string> ServerList { get; set; }
}
}
}
I thought that I should first see if the Session object exists, then create if it doesn't as I have read that sometimes static values can be lost due to appPool recycle, etc.
I figured I should do this from the MasterPage since I have to reference "Session" but I don't know how I would pass the Page object to a property in a class file.
I use the following in the MasterPage to store the current user so I thought that I could do a similar thing with global variables. So far I have been unsuccessful.
public MyClass.Users.CurrentUser GetSetCurrentUser
{
get
{
if (Session["CurrentUser"] == null) GetSetCurrentUser = new MyClass.Users.CurrentUser();
return (MyClass.Users.CurrentUser)Session["CurrentUser"];
}
set { Session.Add("CurrentUser", value); }
}
With the previous though, I also have to add the following to each page that wants to reference the GetSetCurrentUser property (Master.GetSetCurrentUser ), but I would prefer to avoid this if possible.
<%# MasterType VirtualPath="~/mp.Master" %>
Unfortunately when I tried the same with GlobalStaticVariables no intellisense appeared aside from .Equals, .GetHashCode, .GetType and .ToString.
I want to be able to call the property GlobalStaticVariables from any page for easy access to it's static values.
Perhaps my thought process is flawed in attempting to do it this way, but I can't think of another way. Perhaps I needs to step away from this for awhile and enjoy the holiday, but I can't, I'm on a mission. :-)
Thank-you for you time and suggestions.
You're looking for HttpApplicationState that is available in your page by Context property which holds an Application property.
How you can use it:
void Page_Load(object sender, EventArgs e)
{
var last = Context.Application["lastActivity"];
lblLastActivity.Text = last == null?"(none)": ((DateTime) last).ToString();
Context.Application["lastActivity"] = DateTime.Now;
}
One other option is the use of Cache which works similar but objects stored in the Cache can get removed from the cache (to free memory). You should be able to reload the objects in that case though.
If I have been researching this correctly, I got some help before and a user said that it would be good to use a Dictionary to store my Country and Places.
So I create my Dictionary:
Dictionary<string, NewCountryClass> NTCD = new Dictionary<string, NewcountryClass>();
When the user clicks the button it will trigger this class where I wanted it to create a instance of newCountryClass inside the Dictionary at runtime. It would add the string which would be the newCountryTitle.Country and then the Class.
public void AddCountryCollection()
{
newCountryClass = new NewCountryClass(newCountry,"");
Collections.Add(newCountryClass);
NTCD.Add(newCountryClass.Country, newCountryClass);
}
So lets say the user has has added the Country which has created this Dictionary at Runtime, and they have added 4 Countries, but now want to go back and add a Place label inside the second Country.
This is the newCountryClass:
private string _country;
public string Country
{
get { return _country; }
set
{
if (_country.Equals(value))
return;
_country= value;
RaisePropertyChanged(() => Country);
}
}
private ICollection<string> _places;
public ICollection<string> Places
{
get
{
if (_places== null)
_places= new ObservableCollection<string>();
return _places;
}
set
{
if (value == _places)
return;
_places= value;
RaisePropertyChanged(() => Places);
}
}
If they have created 4, and they want to add a Place to the list inside that Country of the second one they created, how would I find it?
I found an answer I simply use the key I stored:
NTCD["GER"].Places.Add("New Place inside GER");
If I only want to know the second one, either take a List<NewCountryClass> and iterate by index with foror take a OrderedDictionary. It takes object key, object value as parameters on add and I can access it via NTCD[3].
I have face a requirement,
I want client access a data center but without use database , so I want my web app can retain a global or Application session variable, that contains the data, every client can access the same data... I am try to declare in golabl, but seem it only can store String but others ...
how to solve this problem ?
thanks.
Another option of defining a global variable is by creating a static class with a static property:
public static class GlobalVariables
{
public static string MyGlobalVariable { get; set; }
}
You can make this more complex if you are going to use this as a data store, but the same idea goes. Say, you have a dictionary to store your global data, you could do something like this:
public static class GlobalData
{
private static readonly object _syncRoot = new object();
private static Dictionary<string, int> _data;
public static int GetItemsByTag(string tag)
{
lock (_syncRoot)
{
if (_data == null)
_data = LoadItemsByTag();
return _data[tag];
}
}
private static Dictionary<string, int> LoadItemsByTag()
{
var result = new Dictionary<string, int>();
// Load the data from e.g. an XML file into the result object.
return result;
}
}
To Share the data with all application users, you can use ASP.NET Application object. Given is the sample code to access Application object in ASP.NET:
Hashtable htblGlobalValues = null;
if (Application["GlobalValueKey"] != null)
{
htblGlobalValues = Application["GlobalValueKey"] as Hashtable;
}
else
{
htblGlobalValues = new Hashtable();
}
htblGlobalValues.Add("Key1", "Value1");
htblGlobalValues.Add("Key2", "Value2");
this.Application["GlobalValueKey"] = htblGlobalValues;
Application["GlobalValueKey"] can be used anywhere in the whole application by any user. It will be common to all application users.
You can stuff data into the Application object if you want. It isn't persistent across application instances, but that may sufficient.
(I'm not for a minute going to suggest this is a best practice, but without a clearer picture of the requirements, that's all I can suggest.)
http://msdn.microsoft.com/en-us/library/system.web.ui.page.application.aspx
http://msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx
If you are using WebApplication or MVC just go to Global.asax (in WebSite project you need to add Global.asax from the add new item menu).
I will explain to deploy two global variables for your web application:
Open the Global.asax file, then define your variable in Application_Start function as following:
void Application_Start(object sender, EventArgs e)
{
Application.Lock();
Application["variable1"] = "Some Value for variable1";
Application["variable2"] = "Some Value for variable2";
Application.UnLock();
}
If you want to use that those global variables in aspx pages just need to call them like this:
<p>I want to call variable1 <%=Application["variable1"].ToString() %></p>
<p>I want to call variable1 <%=Application["variable2"].ToString() %></p>
But if you want to use that those global variables in server-side call'em like this:
protected void Page_Load(object sender, EventArgs e)
{
string str1 = Application["variable1"].ToString();
string str2 = Application["variable2"].ToString();
}
Note: You must be aware that these global variables are public to all users and aren't suitable for authentication jobs.
You can also use Cache, which has advantages like ability to set expire time/date.
I am sure that I have made some painfully obvious blunder(s) that I just cannot see. I am hoping one of you can set me straight.
I my session management is working perfectly except that if a user on one machine enters data, a user who starts a session on another machine will also retreive the session information from the first. Not so good. :(
I call my sessions like this:
UserInfo userinfo = UserInfo.Session;
My session mgt class uses this:
static UserInfo userInfo;
static public UserInfo Session
{
get
{
if (userInfo == null)
{
userInfo = new UserInfo();
userInfo.ResetSessionTime();
}
return userInfo;
}
}
I read and write the data like this. I realize that I could serialize the entire class, but it seems like a lot more overhead to serialize and deserialize an entire class each time the class is called as opposed to just grabbing the one or two items I need.
Decimal _latitude;
private String SessionValue(String sKey, String sValue, String sNewValue)
{
String sRetVal = "";
if (sNewValue == null)//not wanting to update anything
{
if (sValue == null)//there is no existing value
{
sRetVal = (String)System.Web.HttpContext.Current.Session[sKey];
}
else
{
sRetVal = sValue;
}
}
else
{
System.Web.HttpContext.Current.Session[sKey] = sNewValue;
sRetVal = sNewValue;
}
return sRetVal;
}
public Decimal Latitude
{
get { return SessionValue("Latitude", _latitude); }
set { _latitude = SessionValue("Latitude", _latitude, value); }
}
Thanks for your help
1) You're using statics for your UserInfo, which means that a single instance of this class is shared among all requests coming to your web server.
2) You're not only storing values in the session (which isn't shared among users) but also in an instance variable, which in this case WILL be shared among users.
So the value of _latitude is causing you this issue. A simple solution is this:
public class Userinfo
{
public Decimal Latitude
{
get { return System.Web.HttpContext.Current.Session["Latitude"]; }
set { System.Web.HttpContext.Current.Session["Latitude"] = value; }
}
}
A better, more testable version would be:
public class UserInfo
{
private HttpSessionStateWrapper _session;
public UserInfo(HttpSessionStateWrapper session)
(
// throw if null etc
_session = session;
)
public Decimal Latitude
{
get { return _session["Latitude"]; }
set { _session["Latitude"] = value; }
}
}
In the second instance, within a request you just construct a new instance of the HttpSessionStateWrapper (using the current Session) and pass it to the UserInfo instance. When you test, you can just pass in a mock Wrapper.
No matter what, the UserInfo instance shouldn't be shared among sessions and it should write and read directly from the Session. Don't try to prematurely optimize things by keeping local versions of your session values. You aren't saving any time and you're just opening yourself up to bugs.
This happens because you store your user info in a static field. Static instances are shared between all requests, and lives the entire lifetime of your application.
In other words, all your users will get the same UserInfo instance from UserInfo.Session.
To fix this you could:
Serialize the whole class into session. I don't know which other properties you have, but I would guess it would not be too much of an overhead.
Create an instance of UserInfo per request, so that the user always reads from a new instance, which in turn will refresh it's values from Session.