开发者

MVC2 find area/controller/action from within custom attribute

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;
            }
        }

        p开发者_StackOverflowublic 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.


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"];
}


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜