.NET MVC:如何为每个用户实现不同的页面外观?

发布于 2024-08-17 10:14:52 字数 1158 浏览 3 评论 0原文

我在这里没有想法了。也许你可以建议我使用什么模式或方法。

用户应该能够登录并更改其个人资料的外观。 与个性化的区别(据我所知)是个性化布局仅对编辑(他/她自己)可见。 我想,皮肤之间的区别在于皮肤是预定义的,但用户应该能够自己更改设置。

我需要能够向访问作者页面的每个人显示自定义布局。

好的解决方案是将布局信息保存在数据库表中。我想它也应该被缓存以减轻数据库的负载并在 CSS 中使用。

谢谢

编辑:

好的,我现在已经做了一些研究。想出了这样的主意。

在视图中从数据库获取 userId(Guid 类型)并将其设置为 ViewData: ViewData["userId"] = profile.userId;

该视图使用以下名为“Profile.Master”的 MasterPage 并链接到动态 CSS 文件:

    <link href="<%= Url.Action("Style", "Profile", 
        ViewData["userId"]) %>" rel="stylesheet" type="text/css" />
</head>

在 ProfileController 中从数据库获取 CSS 数据并将其返回到动态 CSS 视图:

public ActionResult Style(Guid userId)
{
    var styles = (from s in Db.UserStyleSet.OfType<UserStyle>()
                  where s.aspnet_Users.UserId == userId
                  select s);

    return View("Style", styles);
}

问题是 UserId 永远不会传递给动态 CSS 视图。 CSS 链接:

参数字典包含“Project.Controllers.ProfileController”中方法“System.Web.Mvc.ActionResult Style(System.Guid)”的不可空类型“System.Guid”的参数“userId”的空条目。

欢迎任何建议,谢谢。

I am running out of ideas here. Maybe you can advice me what pattern or method(s) to use.

User should be able to log in and change the appearance only for his/her profile.
The difference (AFAIK) with personalization is that personalized layout are seen only for the editor (him-/herself).
The difference between skinning, I guess, is that Skins are predefined but users should be able to change the settings themselves.

I need to be able to display the customized layout to everyone who visit author`s page.

The good solution would be to keep the layout info in a DB table. Also it should be cached I guess to take load off the DB and used in CSS.

Thanks

Edit:

OK I have done some research now. Came up with this kind of idea.

In a View get a userId (Guid type) from a DB and set it to the ViewData:
ViewData["userId"] = profile.userId;

That View uses the following MasterPage called 'Profile.Master' and links to the dynamic CSS file:

    <link href="<%= Url.Action("Style", "Profile", 
        ViewData["userId"]) %>" rel="stylesheet" type="text/css" />
</head>

In the ProfileController get the CSS data from DB and return it to the dynamic CSS View:

public ActionResult Style(Guid userId)
{
    var styles = (from s in Db.UserStyleSet.OfType<UserStyle>()
                  where s.aspnet_Users.UserId == userId
                  select s);

    return View("Style", styles);
}

The problem is that the UserId is never passed to the dynamic CSS link:

The parameters dictionary contains a null entry for parameter 'userId' of non-nullable type 'System.Guid' for method 'System.Web.Mvc.ActionResult Style(System.Guid)' in 'Project.Controllers.ProfileController'.

Any advice is welcome, thank you.

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

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

发布评论

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

评论(4

我也只是我 2024-08-24 10:14:52

您可以在 Rob Conery 开发的 Kona 项目中找到非常简洁的布局自定义功能。当您运行您可以在此处找到的源代码时,您将看到布局管理 UI允许您更改屏幕上每个组件的位置。

使用的方法如下:

  1. 渲染页面时,我们的自定义视图引擎检查应显示哪个母版页(这样我们就可以根据当前设置切换主题)

     public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) {
        ViewEngineResult 结果 = null;
        var request =controllerContext.RequestContext;
        if (controllerContext.Controller.GetType().BaseType == typeof(KonaController)) {
            var orchardController = controllerContext.Controller 作为 KonaController;
            字符串模板= orchardController.ThemeName;
    
  2. 视图引擎使用母版页并呈现定义的视图通过使用路由表解决的特定控制器操作。例如,我们输入指向 Home Controller、Index 方法的站点的主 url。此方法返回由视图引擎呈现的 Index.aspx 视图。

  3. 当视图引擎呈现 Index.aspx 页面时,它会启动类似的辅助方法

    <%this.RenderWidgets("sidebar1"); %>。

此方法真正负责呈现 aspx 页面中每个 div 的特定小部件。这样,如果您的用户更改小部件的布局,它们将正确显示在屏幕上。

        public static void RenderWidgets(this ViewPage pg,  Kona.Infrastructure.Page page, bool useEditor, string zone) {
        if (page != null) {
            foreach (IWidget widget in page.Widgets.Where(x => x.Zone.Equals(zone, StringComparison.InvariantCultureIgnoreCase))) {

                string viewName = useEditor ? widget.EditorName : widget.ViewName;


                if (widget.ViewName != null) {
                    if (widget.IsTyped) {
                        var typedWidget = widget as Widget<IList<Product>>;
                        pg.Html.RenderPartial(viewName, typedWidget);
                    } else {
                        pg.Html.RenderPartial(viewName, widget);
                    }
                } else if (!string.IsNullOrEmpty(widget.Title)) {
                    pg.Html.RenderPartial("TitleAndText", widget);

                } else {
                    pg.Html.RenderPartial("TextOnly", widget);
                }
            }
        }
    }

用户如何能够更改布局? Kona 有非常简洁的 JavaScript,它与 Ajax 一起使用,用户只需将小部件从一个面板拖放到另一个面板即可重新排序布局。

Very neat layout customization features you can find in Kona project developed by Rob Conery. When you run source code which you can find here, you will see layout management UI which allows you to change the position of each component on the screen.

The approach used there is as follows:

  1. When page is rendered our customized view engine check which master page should present (this way we are able to switch themes based on current settings)

        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) {
        ViewEngineResult result = null;
        var request = controllerContext.RequestContext;
        if (controllerContext.Controller.GetType().BaseType == typeof(KonaController)) {
            var orchardController = controllerContext.Controller as KonaController;
            string template = orchardController.ThemeName;
    
  2. View engine uses master page and renders view which was defined by specific controller action resolved using route tables. For instance, we typed main url of the site which pointed to Home Controller, Index method. This method returned Index.aspx view which was rendered by View engine.

  3. While view engine is rendering the Index.aspx page it launches helper methods like

    <%this.RenderWidgets("sidebar1"); %>.

This method is truely responsible for rendering specific widdgets per each div in the aspx page. This way, if your user changes the layout of the widgets they will be correctly presented on the screen.

        public static void RenderWidgets(this ViewPage pg,  Kona.Infrastructure.Page page, bool useEditor, string zone) {
        if (page != null) {
            foreach (IWidget widget in page.Widgets.Where(x => x.Zone.Equals(zone, StringComparison.InvariantCultureIgnoreCase))) {

                string viewName = useEditor ? widget.EditorName : widget.ViewName;


                if (widget.ViewName != null) {
                    if (widget.IsTyped) {
                        var typedWidget = widget as Widget<IList<Product>>;
                        pg.Html.RenderPartial(viewName, typedWidget);
                    } else {
                        pg.Html.RenderPartial(viewName, widget);
                    }
                } else if (!string.IsNullOrEmpty(widget.Title)) {
                    pg.Html.RenderPartial("TitleAndText", widget);

                } else {
                    pg.Html.RenderPartial("TextOnly", widget);
                }
            }
        }
    }

How user is able to change the layout? Kona has very neat javascript which is used together with Ajax and user simply drag&drop widgets from one panel to another to reorder the layout.

余生共白头 2024-08-24 10:14:52

您可以使用 CMS 框架。请参阅此问题获取建议

You could use a CMS framework. See this question for suggestions

最偏执的依靠 2024-08-24 10:14:52

您可以动态构建 CSS 文件并将 CSS 名称保存在用户的数据库条目中。

You could dynamically build a CSS file and save the css name in the user's db entry.

蹲在坟头点根烟 2024-08-24 10:14:52

您需要多少定制?一次将整个 css 存储在数据库中 1 种样式似乎有点矫枉过正,您确定您的用户真的需要/想要这种级别的自定义吗?

提供主题列表,允许用户选择他们想要的主题,然后将该信息与用户配置文件一起存储,这样当您检索配置文件详细信息时,您也检索主题,这不是更简单吗?然后,该信息可用于选择适当的母版并传递到视图以呈现正确的样式表。

如果您确实希望允许极端自定义到个人样式级别,我将使用默认 css,然后当用户自定义其布局时,复制默认值并根据需要进行更改,为用户创建自定义 css。每次用户更新其个人资料布局时,只需使用更改更新 css 文件即可。要绕过 css 缓存,请记录每次更改的递增版本号,并将其附加到 css 的 url 末尾,例如

How much customisation do you need? Storing an entire css in the database 1 style at a time seems a little overkill, are you sure your users really need / want that level of customisation?

Wouldn't it be simpler to present a list of themes, allow the user to select the one they want and then store that information with the user profile so that when you retrieve the profile details you also retrieve the theme. This information can then be used to select the appropriate master as well as passed to the view to render the correct stylesheet(s).

If you really want to allow extreme customisation down to the individual style level, I would use a default css and then when the user customises their layout, copy the default and alter as necessary, creating a custom css for the user. Each time the user updates their profile layout, simply update the css file with the changes. To get around css caching, record an incrementing version number for each change and append that to the end of the url for the css e.g. <link rel="stylesheet" href="user001.css?v=2>.

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