首先,您可能需要考虑使用 Cache 而不是 Application 字典,特别是因为您的缓存数据将在某个时候过期。看看这个问题
另外,请考虑控制器方法是否仅由视图使用,因为 MVC 将公开控制器中的所有公共方法。如果您不希望使用 URL 自由访问此方法,请设置[NonAction]
属性。
关于您的错误,修复它的一种快速方法是通过System.Web.HttpContext.Current
控制器的 CachedSlides 属性的实现来访问 Application 对象。
您还可以在视图中创建 SliderController 的新实例时设置 ControllerContext。这样,控制器中的 HttpContext 在访问 CachedSlides 属性时不会返回 null:
@{
var sliderController = new LevEl.Controllers.Admin.SliderController();
sliderController.ControllerContext = new ControllerContext(ViewContext.RequestContext, sliderController);
var sliderModel = sliderController.GetSlides();
}
如果拥有一个可以处理所有这些视图的基本控制器类对您来说是有意义的,那么获取控制器会更干净。您只需要将ViewContext.Controller
实例转换为该基本控制器类:
var sliderController = ViewContext.Controller as BaseSlideController;
var sliderModel = sliderController.GetSlides();
但是,所有这些方法都需要您将那段代码添加到每个视图中。您可以考虑为所有需要访问 Slide 集合的视图创建一个基类:
public abstract class SlidesEnabledView<T> : WebViewPage<T>
{
private IEnumerable<Slide> _slides;
protected IEnumerable<Slide> Slides
{
get
{
if(_slides == null)
{
var sliderController = ViewContext.Controller as BaseSlideController;
_slides = sliderController.GetSlides();
}
return _slides;
}
}
}
然后您将@inherits 标签添加到您的视图中,因此它们继承自我们刚刚创建的基类(使用@inherits 时,您不能同时使用@model,因此在@inherits 中您将绑定通用基类视图类型是具体的模型类型)。这将允许您使用在基本SlidesEnabledView
视图类中定义的属性。假设 SlidesEnabledView 的命名空间是 Level.ViewClasses.Admin,这看起来像:
@inherits Level.ViewClasses.Admin.SlidesEnabledView<SomeViewModelClass>
Number of Slides: @Slides.Count()
最后,如果您通过您的站点使用 DI 并且您已经配置了一个 DependencyResolver,那么您可以考虑将获取幻灯片的逻辑移动到它自己的类和接口中,例如ISlidesProvider
and CachedSlideProvider
。然后,您可以在抽象视图类中使用属性注入来获取将在 Slides 属性中使用的 ISlidesProvider 实例:
public interface ISlidesProvider
{
IEnumerable<Slide> GetSlides();
}
public class CachedSlideProvider : ISlidesProvider
{
//you will need a constructor that takes the "Context" object, which will be injected into this class
public IEnumerable<Slide> GetSlides()
{
if (CachedSlides == null)
CachedSlides = Context.Slides.OrderBy(p => p.SortOrder).ToArray();
return CachedSlides;
}
private IEnumerable<Slide> CachedSlides
{
get { return System.Web.HttpRuntime.Cache[SlidesCacheKey] as IEnumerable<Slide>; }
set { System.Web.HttpRuntime.Cache[SlidesCacheKey] = value; }
}
}
public abstract class SlidesEnabledView<T> : WebViewPage<T>
{
private IEnumerable<Slide> _slides;
protected IEnumerable<Slide> Slides
{
get
{
if(_slides == null)
{
_slides = this.SlidesProvider.GetSlides();
}
return _slides;
}
}
//This property will be set by your DI container
//You have configured ISlidesProvider to be resolved as CachedSlidesProvider in the DI container
//You have also implemented and registered an MVC DependencyResolver that uses your DI container
//For example, using Microsoft Unity you could set this attribute
[Dependency]
public ISlidesProvider SlidesProvider { get; set; }
}
当您使用无参数构造函数创建控制器实例时,您可能没有在您的站点上使用 DI。因此,仅用于解决此特定问题,此 DI 选项可能有点矫枉过正。