Ich schreibe eine Webanwendung, mit der ein Benutzer zu mehreren Webseiten auf der Website navigieren kann, um bestimmte Anforderungen zu erfüllen. Alle Informationen, die der Benutzer eingibt, werden in einem von mir erstellten Objekt gespeichert. Das Problem ist, dass ich auf dieses Objekt von jedem Teil der Website aus zugreifen muss und nicht wirklich weiß, wie ich das am besten erreichen kann. Ich weiß, dass eine Lösung darin besteht, Sitzungsvariablen zu verwenden, aber ich weiß nicht, wie ich sie in asp .net MVC verwenden soll. Und wo würde ich eine Sitzungsvariable deklarieren? Gibt es einen anderen Weg?
Ich würde denken, dass Sie darüber nachdenken möchten, ob die Dinge wirklich in einen Sitzungszustand gehören. Dies ist etwas, was ich hin und wieder mache und es ist eine nette, stark typisierte Herangehensweise an das Ganze, aber Sie sollten vorsichtig sein, wenn Sie Dinge in den Sitzungskontext stellen. Nicht alles sollte da sein, nur weil es einem Benutzer gehört.
hängen Sie in global.asax das Ereignis OnSessionStart ein
void OnSessionStart(...)
{
HttpContext.Current.Session.Add("__MySessionObject", new MySessionObject());
}
Überall im Code, wo die Eigenschaft HttpContext.Current! = Null ist, können Sie dieses Objekt abrufen. Ich mache das mit einer Erweiterungsmethode.
public static MySessionObject GetMySessionObject(this HttpContext current)
{
return current != null ? (MySessionObject)current.Session["__MySessionObject"] : null;
}
Auf diese Weise können Sie Code eingeben
void OnLoad(...)
{
var sessionObj = HttpContext.Current.GetMySessionObject();
// do something with 'sessionObj'
}
Die Antwort hier ist richtig, ich hatte jedoch Schwierigkeiten, sie in einer ASP.NET MVC 3-App zu implementieren. Ich wollte auf ein Sitzungsobjekt in einem Controller zugreifen und konnte nicht herausfinden, warum ich immer wieder die Meldung "Instanz wurde nicht auf eine Instanz eines Objektfehlers festgelegt" erhielt. Was mir aufgefallen ist, ist, dass in einem Controller, als ich versuchte, auf die Sitzung zuzugreifen, indem ich Folgendes ausführte, dieser Fehler weiterhin auftrat. Dies liegt daran, dass this.HttpContext Teil des Controller-Objekts ist.
this.Session["blah"]
// or
this.HttpContext.Session["blah"]
Was ich jedoch wollte, war der HttpContext, der Teil des System.Web-Namespace ist, da dies derjenige ist, den die Antwort oben für Global.asax.cs vorschlägt. Also musste ich explizit Folgendes tun:
System.Web.HttpContext.Current.Session["blah"]
das hat mir geholfen, nicht sicher, ob ich etwas getan habe, das nicht M.O. hier in der nähe, aber ich hoffe es hilft jemandem!
Da ich nicht gerne "HTTPContext.Current.Session" über den Ort sehe, verwende ich ein Singleton-Muster, um auf Sitzungsvariablen zuzugreifen. Dadurch erhalten Sie einen einfachen Zugriff auf stark typisierte Datenmengen.
[Serializable]
public sealed class SessionSingleton
{
#region Singleton
private const string SESSION_SINGLETON_NAME = "Singleton_502E69E5-668B-E011-951F-00155DF26207";
private SessionSingleton()
{
}
public static SessionSingleton Current
{
get
{
if ( HttpContext.Current.Session[SESSION_SINGLETON_NAME] == null )
{
HttpContext.Current.Session[SESSION_SINGLETON_NAME] = new SessionSingleton();
}
return HttpContext.Current.Session[SESSION_SINGLETON_NAME] as SessionSingleton;
}
}
#endregion
public string SessionVariable { get; set; }
public string SessionVariable2 { get; set; }
// ...
dann können Sie von überall auf Ihre Daten zugreifen:
SessionSingleton.Current.SessionVariable = "Hello, World!";
Wenn Sie asp.net mvc verwenden, können Sie auf einfache Weise auf die Sitzung zugreifen.
Von einem Controller:
{Controller}.ControllerContext.HttpContext.Session["{name}"]
Aus einer Sicht:
<%=Session["{name}"] %>
Dies ist definitiv nicht der beste Weg, um auf Ihre Sitzungsvariablen zuzugreifen, aber es ist ein direkter Weg. Gehen Sie daher vorsichtig vor (vorzugsweise während des Rapid Prototyping) und verwenden Sie einen Wrapper/Container und OnSessionStart, wenn dies angemessen ist.
HTH
Nun, meiner Meinung nach ..
In Bezug auf # 1 habe ich eine stark typisierte Master-Ansicht, die eine Eigenschaft für den Zugriff auf alle Objekte des Session-Objekts hat
ViewMasterPage<AdminViewModel>
AdminViewModel
{
SomeImportantObjectThatWasInSession ImportantObject
}
AdminViewModel<TModel> : AdminViewModel where TModel : class
{
TModel Content
}
und dann...
ViewPage<AdminViewModel<U>>
Es gibt 3 Möglichkeiten, dies zu tun.
Sie können direkt auf
HttpContext.Current.Session
Du kannst
HttpContextBase
verspottenErstellen Sie eine Erweiterungsmethode für
HttpContextBase
Ich bevorzuge den 3. Weg. Dieser Link ist eine gute Referenz.
Ich weiß zwar nichts über asp.net mvc, aber das ist, was wir auf einer normalen .net-Website tun sollten. Es sollte auch für asp.net mvc funktionieren.
YourSessionClass obj=Session["key"] as YourSessionClass;
if(obj==null){
obj=new YourSessionClass();
Session["key"]=obj;
}
Sie würden dies in eine Methode für den einfachen Zugriff einfügen. HTH
Tolle Antworten von den Jungs, aber ich möchte Sie davor warnen, sich immer auf die Session zu verlassen. Dies ist schnell und einfach zu bewerkstelligen und würde natürlich funktionieren, wäre aber nicht unter allen Umständen großartig.
Zum Beispiel, wenn Sie in ein Szenario geraten, in dem Ihr Hosting die Sitzungsnutzung nicht zulässt, wenn Sie sich in einer Webfarm befinden oder im Beispiel einer freigegebenen SharePoint-Anwendung.
Wenn Sie nach einer anderen Lösung suchen, können Sie ein IOC-Container wie Castle Windsor verwenden, eine Anbieterklasse als Wrapper erstellen und dann eine Instanz Ihrer Klasse mit dem beibehalten je nach Anforderung oder Sitzungslebensstil.
Das IOC würde sicherstellen, dass jedes Mal dieselbe Instanz zurückgegeben wird.
Komplizierter ja, wenn Sie eine einfache Lösung benötigen, verwenden Sie einfach die Sitzung.
Hier sind einige Implementierungsbeispiele aus Interesse.
Mit dieser Methode können Sie eine Anbieterklasse wie folgt erstellen:
public class CustomClassProvider : ICustomClassProvider
{
public CustomClassProvider(CustomClass customClass)
{
CustomClass = customClass;
}
public string CustomClass { get; private set; }
}
Und registriere es so ähnlich wie:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ICustomClassProvider>().UsingFactoryMethod(
() => new CustomClassProvider(new CustomClass())).LifestylePerWebRequest());
}
Ich greife auf Sitzungen zu, indem ich eine Hilfsklasse schreibe, die die verschiedenen Feldnamen und ihre Typen kapselt. Ich hoffe dieses Beispiel hilft:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.SessionState;
namespace dmkp
{
/// <summary>
/// Encapsulates the session state
/// </summary>
public sealed class LoginInfo
{
private HttpSessionState _session;
public LoginInfo(HttpSessionState session)
{
this._session = session;
}
public string Username
{
get { return (this._session["Username"] ?? string.Empty).ToString(); }
set { this._session["Username"] = value; }
}
public string FullName
{
get { return (this._session["FullName"] ?? string.Empty).ToString(); }
set { this._session["FullName"] = value; }
}
public int ID
{
get { return Convert.ToInt32((this._session["UID"] ?? -1)); }
set { this._session["UID"] = value; }
}
public UserAccess AccessLevel
{
get { return (UserAccess)(this._session["AccessLevel"]); }
set { this._session["AccessLevel"] = value; }
}
}
}
Sie können ViewModelBase als Basisklasse für alle Modelle verwenden. Diese Klasse übernimmt das Abrufen von Daten aus der Sitzung
class ViewModelBase
{
public User CurrentUser
{
get { return System.Web.HttpContext.Current.Session["user"] as User };
set
{
System.Web.HttpContext.Current.Session["user"]=value;
}
}
}
Sie können eine Erweiterungsmethode für HttpContextBase schreiben, um mit Sitzungsdaten umzugehen
T FromSession<T>(this HttpContextBase context ,string key,Action<T> getFromSource=null)
{
if(context.Session[key]!=null)
{
return (T) context.Session[key];
}
else if(getFromSource!=null)
{
var value = getFromSource();
context.Session[key]=value;
return value;
}
else
return null;
}
Verwenden Sie dies wie unten im Controller
User userData = HttpContext.FromSession<User>("userdata",()=> { return user object from service/db });
Das zweite Argument ist optional. Es wird verwendet, um Sitzungsdaten für diesen Schlüssel zu füllen, wenn in der Sitzung kein Wert vorhanden ist.