ASP.NET MVC 将信息从控制器传递到视图,无需 ViewData、ViewModel 或 Session

发布于 2024-08-27 17:16:05 字数 708 浏览 11 评论 0原文

我有一个独特的场景,我希望基本控制器获取一些数据并将其存储在列表中。该列表应该可以从我的视图中访问,就像 ViewData 一样。我将在每个页面上使用此列表,并且希望有一个比仅仅将其推入 ViewDataDictionary 更干净的解决方案。

在尝试提出解决方案后,我想我应该创建一个自定义 ViewPage,其中包含一个属性来保存我的列表。我的自定义 ViewPage 将从 System.Web.MVC.ViewPage 继承。但是,我不知道 MVC 在哪里将视图数据从控制器传递到视图。更重要的是,我如何让它将我的列表传递到视图?

感谢您的帮助。

编辑...

抱歉造成混乱。我试图让问题尽可能简单,以避免任何混乱。显然,这不起作用:)

我正在 .net mvc 项目中实现自己的会话管理。当请求传入时,我的基本控制器会检查会话 cookie 是否与 OnActionExecuting 方法中的请求一起发送。如果发送了会话 cookie,我的控制器就会访问数据库并检索用户的会话信息。会话信息(用户 ID 等)被放入 List 对象中并存储在名为“Sess”的属性中。

我希望能够从我的视图中访问 Sess 列表中的元素,如下所示:

那么,如何以及在哪里让我的控制器将 Sess 列表移交给我的视图?

我意识到这不是 .net 中通常实现自定义会话管理的方式。然而,这对于我的项目来说是最简单、最干净的解决方案。

感谢迄今为止提供帮助的所有人!

I have a unique scenario where I want a base controller to grab some data and store it in a list. The list should be accessible from my views just as ViewData is. I will be using this list on every page and would like a cleaner solution than just shoving it in the ViewDataDictionary.

After attempting to come up with a solution, I thought I would create a custom ViewPage with a property to hold my list. My custom ViewPage would inherit from System.Web.MVC.ViewPage. However, I do not know where MVC passes the viewdata from the controller off to the view. More importantly, how do I get it to pass my list down to the view?

Thanks for the help.

EDIT....

Sorry for the confusion. I was trying to keep the question as simple as possible to avoid any confusion. Obviously, that did not work :)

I'm implementing my own session management in an .net mvc project. When a request comes in, my base controller checks to see if a session cookie was sent along with the request in the OnActionExecuting method. If a session cookie was sent, my controller hits the database and retrieves the user's session information. The session information (userid, etc..) is put into a List object and stored in a property called "Sess".

I want to be able to access elements in the Sess list from my views like this:

So, how and where do I get my controller to hand off the Sess list to my views?

I realize that this is not how custom session management is typically implemented in .net. However, this would be the simplest and cleanest solution for my project.

Thanks to everyone who has helped so far!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

柠檬色的秋千 2024-09-03 17:16:05

一般来说,我建议明确说明您的视图可以访问的内容。因此,我建议您将此数据从控制器放入 ViewData 中,然后从视图中将其从 ViewData 中取出。这使得控制器和视图之间的通信线路集中在一处并且简单。

但是,如果您确实想从视图访问会话,则可以。

<%: ViewContext.HttpContext.Session["key"] %>

您可以做的一件事是拥有自己的从 System.Web.Mvc.ViewPage 派生的自定义视图页面类,并更改页面顶部的 Inherits 声明以指向您的视图页面。

<%@ Page ... Inherits="YourNamespace.YourViewPage" %>

您的自定义视图页面可以具有您需要的任何属性。

In general, I'd recommend being explicit about what your views are allowed to access. Thus I'd recommend that you put this data in ViewData from your controller, and then pull it out of ViewData from the view. That keeps the line of communication between your controller and view in one place and simple.

However, if you really want to access the Session from the view, you can.

<%: ViewContext.HttpContext.Session["key"] %>

One thing you could do is have your own custom view page class that derives from System.Web.Mvc.ViewPage and change the Inherits declaration at the top of the page to point to your view page.

<%@ Page ... Inherits="YourNamespace.YourViewPage" %>

Your custom view page could have whatever properties you need.

香橙ぽ 2024-09-03 17:16:05

问题不清楚:要回答部分问题,您可以使用基本 ViewModel 上的属性。您需要在基本 ViewModel 的构造函数中设置该属性。如果需要将任何值传递给它以执行其正在执行的任何工作,则实例对象需要显式调用基本 ViewModel 的构造函数...此构造函数调用都是普通的 C#,因此网络上有很多示例。

我同意,如果这是针对菜单的,则 RenderAction 似乎是实现该功能的更简单的方法。我尝试了菜单的基本 ViewModel 方法,然后切换到在专门负责导航的控制器上使用 RenderAction。

ASP.NET MVC 站点缺乏动态导航示例令人惊讶,因为这似乎是一个基本要求。

Question not clear: To answer part of it, you can use a property on a base ViewModel. You need to set that property in the constructor of the base ViewModel. Your instance objects need to call the constructor of the base ViewModel explicitly if any values need to be passed down to it for whatever work it is doing... This constructor calling is all normal C# so there are plenty of examples on the web.

I agree that if this is for menus, RenderAction does seem like a much easier way to implement the functionality. I tried the base ViewModel method for menus and then switched to using RenderAction on a controller that is specifically responsible for navigation.

The lack of dynamic navigation examples for ASP.NET MVC sites is surprising as it seems like such a basic requirement.

与之呼应 2024-09-03 17:16:05

你必须更好地描述你的问题。

而且,除了操作过滤器或 Controller.OnActionExecuted 覆盖之外,您可以使用 Html.RenderAction

You have to describe your problem better.

And, well, except action filter or Controller.OnActionExecuted override, you can use Html.RenderAction.

时光礼记 2024-09-03 17:16:05

为什么不想使用ViewData?难道只是因为您不想在每个操作中都有一行代码将一些数据放入 ViewDataDictionary 中?

您可以使用操作过滤器并在每个操作执行之前放置该数据,例如

public class AddSomeDataToViewDataAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //filterContext.Controller.ViewData.Add("SomeConstant")(data);
    }
}

然后,您只需将此属性放入每个控制器或基本控制器中即可。

编辑:
您可以创建几个扩展方法,例如

public static void Add<T>(this IDictionary<string, object> dictionary, T anObject)
{
    var key = typeof(T).Name;
    dictionary.Add(key, anObject);
}

public static T Get<T>(this IDictionary<string, object> dictionary)
{
    var key = typeof(T).Name;
    return (T)dictionary[key];
}

然后添加如下数据:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    //filterContext.Controller.ViewData.Add<YourListType>(data);
}

在视图中,您将获得如下数据:

ViewData.Get<YourListType>();

问候。

Why don't you want to use ViewData? Is it just because you don't want to have a line of code in every single action that puts some data in the ViewDataDictionary?

You can use an action filter and put that data before each action executes, like for example

public class AddSomeDataToViewDataAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //filterContext.Controller.ViewData.Add("SomeConstant")(data);
    }
}

Then, you just put this attribute in every Controller or in a base controller.

Edit:
You can make a couple of extension methods like

public static void Add<T>(this IDictionary<string, object> dictionary, T anObject)
{
    var key = typeof(T).Name;
    dictionary.Add(key, anObject);
}

public static T Get<T>(this IDictionary<string, object> dictionary)
{
    var key = typeof(T).Name;
    return (T)dictionary[key];
}

Then you add the data like this:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    //filterContext.Controller.ViewData.Add<YourListType>(data);
}

And in the View, you get the data like this:

ViewData.Get<YourListType>();

Regards.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文