用于会话持久性的变量包装器

时间:2011-09-07 15:35:07

标签: c# .net asp.net session-variables

我很确定我前段时间看到了很好的东西(可能在企业库中,不确定),但我现在不能谷歌 - 通用变量包装器通过将其存储在会话中来使其持久化。用法如下:

Persistent< string > Name {get;set;}

// reguest 1.

Name = "A"; // in fact storing to session.. maybe Name.Value = "A" is necessary, not sure if implicit cast can be done here

// reguest 2.

return Name; // returns string "A", implicit conversion

当然,我会在问之前自己实现它,但我不能想到任何好的(一致的和快速的)方法来确定变量的会话密钥(如何确保,我每次都会得到相同的名称,但是对于年龄不同,你知道..)

感谢名单, 罗马

4 个答案:

答案 0 :(得分:2)

如果您要创建自定义会话包装器,我建议使用表达式来确保您的魔术字符串不会过时。

 public int SomeProperty
 {
     get { return GetValueFor(x => x.SomeProperty); }
     set { SetValueFor(x => x.SomeProperty, value); }
 }

 protected T GetValueFor<T>(Expression<Func<ThisClass, T>> propertySelector)
 {
     string propertyName = // Get Value from expression.. to loo long to post here

     return (T)_session[propertyName];
 }

 protected SetValueFor<T>(Expression<Func<ThisClass, T>> propertySelector, object value)
 {
     string propertyName = // Get value from expression

     _session[propertyName] = value;
 }

这样,所有属性都只是以强类型方式映射到会话对象上,如果你重构,你不必担心魔术字符串。

答案 1 :(得分:1)

这些方面的东西:

private int CustomerID
{
    get
    {
        if( Session["CustomerID"] != null )
            return Convert.ToInt32( Session["CustomerID"] );
        else
            return 0;
    }
    set { Session["CustomerID"] = value; }
}

修改

替代方案可能是这样的:

public class Persist<T>
{
    private string ObjectName;

    public Persist( string Name )
    {
        ObjectName = Name;
    }

    public T Get()
    {
        return (T)(HttpContext.Current.Session[ObjectName]); 
    }

    public void Set(T value)
    {
        HttpContext.Current.Session[ObjectName] = value;
    }
}

这显示为一个简单的Singleton类。

public class SV
{
    private static readonly SV instance = new SV( );

    public Persist<DateTime> FiscalDate;
    public Persist<decimal> Revenue;

    private SV( )
    {
        FiscalDate = new Persist<DateTime>( "FiscalDate" );
        Revenue = new Persist<decimal>( "Revenue" );
    }

   public static SV Instance
   {
      get 
      {
         return instance; 
      }
   }
}

不幸的是,用法有点罗嗦。

protected void Page_Load( object sender, EventArgs e )
{
    if( !Page.IsPostBack )
    {
        SV.Instance.Revenue.Set( 1234567890M );
        SV.Instance.FiscalDate.Set( new DateTime( 2011, 3, 15 ) );
    }
}

protected void Button1_Click( object sender, EventArgs e )
{
    DateTime when = SV.Instance.FiscalDate.Get( );
    decimal amount = SV.Instance.Revenue.Get( );
}

答案 2 :(得分:0)

感谢jim31415,我将会话包装成如下,

internal class SessionHelper {
    private void Set<T>(string key, T value) {
        HttpContext.Current.Session[key] = value;
    }
    private T Get<T>(string key) {
        return (T)HttpContext.Current.Session[key];
    }

    public int MemberID {
        get { return Get<int>("SK_MemberID"); }
        set { Set<int>("SK_MemberID", value); }
    }
    public string MemberAccount {
        get { return Get<string>("SK_MemberAccount"); }
        set { Set<string>("SK_MemberAccount", value); }
    }
    public string MemberDisplayName {
        get { return Get<string>("SK_MemberDisplayName"); }
        set { Set<string>("SK_MemberDisplayName", value); }
    }
    public string MemberGuid {
        get { return Get<string>("SK_MemberGuid"); }
        set { Set<string>("SK_MemberGuid", value); }
    }
}

使用this thread,可以使用static关键字声明帮助程序类。

答案 3 :(得分:-1)

我想你能做到的一种方法是:

public class Persistent<T>
{
    private readonly string _sessionKey;
    private static readonly bool _valueType;

    static Persistent()
    {
        _valueType = typeof(T).IsValueType;
    }

    public Persistent(T value = default(T))
    {
        _sessionKey = Guid.NewGuid().ToString();
        SetValue(value);
    }

    private void SetValue(T value)
    {
        var item = (_valueType)
          ? new PersistentWrapper { Value = value }
          : (object)value;

        HttpContext.Current.Session[_sessionKey] = item;
    }

    private T GetValue()
    {
        object item = HttpContext.Current.Session[_sessionKey];
        if (item != null)
        {
            if (_valueType) return ((PersistentWrapper)item).Value;

            return (T)item;
        }

        return default(T);
    }

    [Serializable]
    private class PersistentWrapper
    {
        public T Value { get; set; }
    }

    public static implicit operator T(Persistent<T> value)
    {
        if (value == null) return default(T);
        return value.GetValue();
    }

    public static implicit operator Persistent<T>(T value)
    {
        return new Persistent<T>(value);
    }
}

可以用作:

public class Person
{
    public Persistent<string> Name { get; set; }
    public Persistent<int> Age { get; set; }
}

使用方法:

var person = new Person();
person.Name = "Matt";
person.Age = 27;

虽然对我来说只是感觉很脏......