MVC2 从自定义属性中查找区域/控制器/操作

发布于 2024-10-11 00:34:52 字数 1940 浏览 1 评论 0原文

我在两个单独的页面上使用部分视图,部分视图使用元数据以模型上的属性形式获取显示名称(执行元数据的标准方法)。

我需要根据页面使显示名称上下文敏感。

为此,我扩展了 System.ComponentModel.DisplayNameAttribute 并传入一个区域/控制器/操作/资源文件/资源​​字符串数组,以便我可以根据上下文选择正确的资源字符串。

我的问题是如何从以下内容中获取区域/控制器/操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonInterfaces.Helpers;

namespace CommonInterfaces.ComponentModel
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class ContextSensitiveDisplayName : System.ComponentModel.DisplayNameAttribute
    {
        public class Context
        {
            public string Area { get; set; }
            public string Controller { get; set; }
            public string Action { get; set; }
            public Type ResourceType { get; set; }
            public string ResourceKey { get; set; }

            public Context(string area, string controller, string action, Type resourceType, string resourceKey)
            {
                this.Area = area;
                this.Controller = controller;
                this.Action = action;
                this.ResourceType = resourceType;
                this.ResourceKey = resourceKey;
            }
        }

        public ContextSensitiveDisplayName(params Context[] contexts)
        {
            /* Its these values that I need */
            string currentArea = ""; 
            string currentController = "";
            string currentAction = "";

            Context selectedContext = 
                contexts.FirstOrDefault(m => 
                    (m.Area == currentArea) && 
                    (m.Controller == currentController) && 
                    (m.Action == currentAction)
                );

            this.DisplayNameValue = ""; // Use the selectContext to retrieve string from resource file.
        }
    }
}

对此的任何帮助将不胜感激。

I am using a partial view on two separate pages and the partial view uses Metadata to get the display names in the form of attributes on the Model (the standard way of doing Metadata).

I need to make the display name context sensitive depending on the page.

To this end I am extending the System.ComponentModel.DisplayNameAttribute and am passing in an array of area/controller/action/resourcefile/resourcestring so that I can pick the correct resource string depending on the context.

My problem is how do I get the area/controller/action from within the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonInterfaces.Helpers;

namespace CommonInterfaces.ComponentModel
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class ContextSensitiveDisplayName : System.ComponentModel.DisplayNameAttribute
    {
        public class Context
        {
            public string Area { get; set; }
            public string Controller { get; set; }
            public string Action { get; set; }
            public Type ResourceType { get; set; }
            public string ResourceKey { get; set; }

            public Context(string area, string controller, string action, Type resourceType, string resourceKey)
            {
                this.Area = area;
                this.Controller = controller;
                this.Action = action;
                this.ResourceType = resourceType;
                this.ResourceKey = resourceKey;
            }
        }

        public ContextSensitiveDisplayName(params Context[] contexts)
        {
            /* Its these values that I need */
            string currentArea = ""; 
            string currentController = "";
            string currentAction = "";

            Context selectedContext = 
                contexts.FirstOrDefault(m => 
                    (m.Area == currentArea) && 
                    (m.Controller == currentController) && 
                    (m.Action == currentAction)
                );

            this.DisplayNameValue = ""; // Use the selectContext to retrieve string from resource file.
        }
    }
}

Any help with this would be greatly appreciated.

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

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

发布评论

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

评论(3

仅冇旳回忆 2024-10-18 00:34:52

这有点令人讨厌,但应该有效:

if(HttpContext.Current != null && HttpContext.Current.Handler is System.Web.Mvc.MvcHandler) 
{
    var handler = HttpContext.Current.Handler as System.Web.Mvc.MvcHandler;
    var controller = handler.RequestContext.RouteData.Values["controller"];
    var action = handler.RequestContext.RouteData.Values["action"];
}

It is a bit nasty but should work:

if(HttpContext.Current != null && HttpContext.Current.Handler is System.Web.Mvc.MvcHandler) 
{
    var handler = HttpContext.Current.Handler as System.Web.Mvc.MvcHandler;
    var controller = handler.RequestContext.RouteData.Values["controller"];
    var action = handler.RequestContext.RouteData.Values["action"];
}
秉烛思 2024-10-18 00:34:52

我最后用的是这个。

var routingValues = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current)).Values;
  string currentArea = (string)routingValues["area"] ?? string.Empty;
  string currentController = (string)routingValues["controller"] ?? string.Empty;
  string currentAction = (string)routingValues["action"] ?? string.Empty;

在我将其标记为正确答案之前,我将尝试一下 Jakub Konecki 的答案 - 他在空检查等方面看起来更加稳健。我很快就会解决这个问题。

I used this in the end.

var routingValues = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current)).Values;
  string currentArea = (string)routingValues["area"] ?? string.Empty;
  string currentController = (string)routingValues["controller"] ?? string.Empty;
  string currentAction = (string)routingValues["action"] ?? string.Empty;

I'm going to try out Jakub Konecki's answer before I mark on as the correct one - his looks a little more robust with the null checks and all. I'll get round to this soon.

把回忆走一遍 2024-10-18 00:34:52

你不知道。属性实例不是在知道路由的上下文中创建的。您不能在属性中执行此操作。

此信息也不会通过 DefaultModelBinder 传递给元数据提供程序,因此编写自定义元数据提供程序不会有任何帮助,除非您还编写自定义模型绑定程序。恕我直言,这工作量太大了。

我建议使用不同的视图模型。

You don't. Attribute instances aren't created in a context which knows the route. You can't do this in an attribute.

Nor is this information passed to the metadata provider by DefaultModelBinder, so writing a custom metadata provider won't help unless you also write a custom model binder. Which is too much work IMHO.

I'd suggest using different view models.

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