MVC克隆控制器上下文

时间:2016-03-18 15:42:07

标签: c# asp.net-mvc asp.net-mvc-3

我在实现ControllerContext的可克隆版本时遇到了一些问题。我需要这个,因为我试图将其缓存并稍后在我的系统的一部分中访问它,该系统无法访问此信息,我无法将其作为参数传递。这就是我所取得的成就:

public class ControllerContextClonable : ControllerContext, ICloneable
{
    public object Clone()
    {
        var cloneContext = (ControllerContext)MemberwiseClone();

        return cloneContext;
    }

    public static List<ControllerContextClonable> ToList( ControllerContextClonable context )
    {
        return new List<ControllerContextClonable>{ context };
    }
}

问题是:当我缓存它时,我有ControllerContext但我需要将ControllerContextClonable对象传递给我的缓存方法。如何将ControllerContext转换为ControllerContextClonable?这就是我试图传递它和缓存方法的方式:

//If i try to call my method with the safe convertion i get a null object
CacheMethods.SetContextCache( context as ControllerContextClonable );

public static void SetContextCache( ControllerContextClonable context, string cacheKey = "SiteContext" )
{
    CacheList<ControllerContextClonable>.RemoveCache( cacheKey );
    CacheList<ControllerContextClonable>.Add( new List<ControllerContextClonable> { context } );
    CacheList<ControllerContextClonable>.CacheIt( cacheKey );
}

public static ControllerContextClonable GetCachedContext( string cacheKey = "SiteContext" )
{
    CacheList<ControllerContextClonable>.LoadCached( cacheKey );

    if( CacheList<ControllerContextClonable>.LoadCached( cacheKey ) )
    {
        return CacheList<ControllerContextClonable>.DataList.FirstOrDefault();
    }

    return null;
}

如何正确地将正在执行的ControllerContext转换为我的ControllerContextClonable类以用于缓存?另外,如果我做错了,任何人都可以指出正确的方法吗?

修改

我将解释我的解决方法:我正在创建一个模板解析系统,它将使用标记系统解析模板,在此标记中,用户将提供ViewModel类和他希望使用的模板View

我将使用this代码实例化此ViewModel来执行此操作。这段代码不允许我将controllercontext作为参数传递,我试图修改它以接受参数,但它会给我Common language runtime detected an invalid program错误。

现在出现问题,在这种情况下我有一个ViewModel需要使用我的ViewBag获取Filter上保存的信息。我能想到的唯一解决方案是缓存上下文并访问它,但我在转换部分失败了。我可以用其他方式解决这个问题吗?我需要的是访问我的Context构造函数调用的一些方法中的ViewModel

这是ViewModel

public class LanguageTestViewModel
{
    //Properties

    public LanguageTestViewModel() { Initialize( "", "", 0 ); }

    public LanguageTestViewModel( string where, string order, int take ) { Initialize( where, order, take ); }

    private void Initialize( string where, string order, int take )
    {
        var Context = CacheMethods.GetCachedContext();
        var EList   = HelperMethods.CreateSelectListItem( "SELECT A STATE", Context );
        var States  = CacheMethods.GetStatesForm( Context );

        //Do stuff
    }
}

编辑2

我必须更改我的存储方法,因为我使用的是HttpRuntime.Cache,这是一个共享存储,我可以根据用户,设备,位置改变存储上下文信息,等。说我需要per-user存储上的这些信息。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我有一个解决方案。克隆控制器实例,然后您就可以访问对象。注意我正在使用实现HomeController的{​​{1}}。这个例子是最简单的解决方案。但它的确有效。例如

IControllerContextClonable

输出。 ControllerContext实例很好地保湿。

enter image description here

using System.Collections.Generic; using System.Web.Mvc; namespace WebApplication1.Controllers { public class HomeController : Controller, IControllerContextClonable { public ActionResult Index() { var controller = (HomeController) this.MemberwiseClone(); var list = ToList(controller); return View(); } public List<IControllerContextClonable> ToList(IControllerContextClonable context) { return new List<IControllerContextClonable> { context}; } } public interface IControllerContextClonable { List<IControllerContextClonable> ToList(IControllerContextClonable context); } } 方法将具有以下签名。请注意,参数类型为SetContextCache。这种IControllerContextClonable方法将接受任何实现SetContextCache

的类型
IControllerContextClonable

然后,您可以传递实现IControllerContextClonable的类型(类)的任何实例,如下所示。这是有效的,因为public static void SetContextCache(IControllerContextClonable context, string cacheKey = "SiteContext" ) { CacheList<IControllerContextClonable>.RemoveCache( cacheKey ); CacheList<IControllerContextClonable>.Add( new List<IControllerContextClonable> { context} ); CacheList<IControllerContextClonable>.CacheIt( cacheKey ); } 实现了IControllerContextClonable。您可以访问该对象,并可以根据需要对其进行操作。

e.g。

HomeController