0

全部,

我有一个 MVC _Layout.cshtml 调用:

@Html.Action("GetActionStrip", "Vehicles") 

我还有一个加载一些视图的控制器。

我的问题是我有一个名为GetVehicleDetails的控制器操作,它通过 ID 获取车辆。

行动:

@Html.Action("GetActionStrip", "Vehicles") 

需要首先加载 GetVehicleDetails,因为它需要将车辆 ID 放入会话中。

这不起作用:

@Html.Action("GetActionStrip", "Vehicles") 

在 GetVehicleDetails 之前加载。

@Html.Action("GetActionStrip", "Vehicles") 

需要在多个视图上,这就是我将它放在 _Layout 文件中的原因。

我可以通过放置:

@Html.Action("GetActionStrip", "Vehicles") 

在每个视图上我都需要它,然后它们以正确的顺序加载。即.. 控制器操作 GetVehicleDetails 将车辆 ID 设置为会话,然后:

@Html.Action("GetActionStrip", "Vehicles") 

读取会话值。

有没有人知道我是否可以按照我想要的方式进行操作,或者我是否必须将我的@Html.Action 放在每种违反 DRY 原则的视图上。

谢谢RuSs

保罗,我试图给你写评论,但字数限制杀死了我。这是我的评论:

保罗,

感谢你的信息。我了解您所写的内容,但在我继续并尝试实施类似的事情之前,我只想确保您完全理解该场景。

您的方案是否会满足以下事实:需要会话值的代码是从我的_Layout(可以说是母版页)中的 @Html.Action 调用的,而我需要我的控制器获取操作以接收参数并将此参数设置为会话.

据我了解,_Layouts(母版页)首先加载,因此我的 @Html.Action 将运行并查找会话值。但是,由于此代码位于 _Layout 中,它将首先运行,因此我的控制器上的 GET 尚未从传入参数的操作中设置会话。

注意:我的 _Layout 没有它自己的控制器(不确定这是否重要)

谢谢RuSs

4

2 回答 2

1

关于设计的某些东西从根本上是不正确的。您不应该像这样紧密耦合不同的组件。顺序应该不重要,哪个先出现。

这就是我可能会做你正在寻找的事情的方法。我将创建一个模型绑定类,您可以在需要会话值的控制器操作中接收该类。如果尚未设置,模型将从数据库或任何地方提取会话值,否则它将使用会话值。现在顺序无关紧要。更好的是,您可以使 MySessionObject 成为一个接口,然后您可以在测试用例中模拟它。

    public interface IMySessionObject
    {
        int GetValueX();
    }

    public class MySessionObject : IModelBinder, IMySessionObject
    {
        private HttpContextBase _httpContext;
        private MySessionObject(HttpContextBase httpContext)
        {
            _httpContext = httpContext;
        }

        public int GetValueX()
        {
            if (_httpContext.Session["x"] == null)
            {
                _httpContext.Session["x"] = 54; // Get the value here.
            }
            return (int)_httpContext.Session["x"];
        }

        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var context = controllerContext.HttpContext;
            var obj = new MySessionObject(context);
            return obj;
        }
    }

    public class HomeController : Controller
    {
        public ActionResult Index(IMySessionObject obj)
        {
            ViewBag.X = obj.GetValueX();

            ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

            return View();
        }

        public ActionResult About(IMySessionObject obj)
        {
            ViewBag.Message = "Your app description page.";

            return View();
        }

        public ActionResult Contact(IMySessionObject obj)
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
于 2013-02-12T06:24:10.107 回答
0

谢谢保罗。如果没有 Sitecore CMS 参与,我认为您的答案是正确的。我会投票给你,但仍然不能解决我的问题。这是我的另一篇文章,它更好地解释了它。我不希望您使用 Sitecore。https://stackoverflow.com/questions/14867915/order-of-loading-layout-and-url-driven-action-is-opposite-to-a-standard-non-sit 试图为 Sitecore 找到一种方法 NOT在我的 MVC 代码运行之前以声明方式加载我的 _layout。

于 2013-02-17T03:08:13.557 回答