Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 3 : Is there a way to get a controller's string Name from its Type?

With the UrlHelper in MVC3, you can build a URL for a controller and an action using strings:

@Url.Action("Index", "Somewhere")

Which will route a request to SomewhereController.Index().

What I would like to do, is get a URL to a controller and action, but passing the Type for the controller:

@Url.Action("Index", typeof(SomewhereController))

Is there a way to do this?


Edit / Clarification:

I realize the convention for the Controllers is that the controller name routes to a class named {Name}Controller so I could just remove 'Controller' from the end of my Type.Name. I guess I was assuming that there was a way to override this convention with some custom routing. Though the more I look at it, I'm not sure that is possible...

Maybe MVC3 can only ever route to classes named "*Controller"? I'm combing through the MVC3 source looking for "Controller" hard coded somewhere, but haven't found the answer yet... But if it is possible to route "Somewhere" to the class SomewhereFoo instead of SomewhereController, then just removing "Controller" from the class name would be incorrect.

If someone can give me evidence for or against "Controller" being hard-coded into MVC3 somewhere, then I would feel more comfortable with the "Just remove Controller from the name" approach.

like image 719
CodingWithSpike Avatar asked Nov 24 '11 04:11

CodingWithSpike


People also ask

How do you reference a controller model?

In Solution Explorer, right-click the Controllers folder and then click Add, then Controller. In the Add Scaffold dialog box, click MVC 5 Controller with views, using Entity Framework, and then click Add. Select Movie (MvcMovie. Models) for the Model class.

How can I see details in MVC?

Open your MVC project in Visual Studio. Add a view model for products. Add a new controller with an action that handles displaying the product detail page.

What is Actionresult () in MVC?

An action result is what a controller action returns in response to a browser request. The ASP.NET MVC framework supports several types of action results including: ViewResult - Represents HTML and markup. EmptyResult - Represents no result.

How can we pass the data from controller to view in MVC?

The other way of passing the data from Controller to View can be by passing an object of the model class to the View. Erase the code of ViewData and pass the object of model class in return view. Import the binding object of model class at the top of Index View and access the properties by @Model.


1 Answers

There is no existing extension for this but you could write your own, modeled on the ActionLink from MvcFutures. I suggest a generic method used like @Url.Action<SomewhereController>( c => c.Index )

public static UrlHelperExtensions
{
    public static string Action<TController>( this UrlHelper helper,  Expression<Action<T>> action ) where TController : Controller
    {
        var routeValues = GetRouteValuesFromExpression( action ); 
        return helper.Action( routeValues["action"], routeValues );
    }

    // copied from MvcFutures
    // http://aspnet.codeplex.com/SourceControl/changeset/view/72551#266392
    private static RouteValueDictionary GetRouteValuesFromExpression<TController>(Expression<Action<TController>> action) where TController : Controller
    {
        if (action == null) {
            throw new ArgumentNullException("action");
        }

        MethodCallExpression call = action.Body as MethodCallExpression;
        if (call == null) {
            throw new ArgumentException(MvcResources.ExpressionHelper_MustBeMethodCall, "action");
        }

        string controllerName = typeof(TController).Name;
        if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) {
            throw new ArgumentException(MvcResources.ExpressionHelper_TargetMustEndInController, "action");
        }
        controllerName = controllerName.Substring(0, controllerName.Length - "Controller".Length);
        if (controllerName.Length == 0) {
            throw new ArgumentException(MvcResources.ExpressionHelper_CannotRouteToController, "action");
        }

        // TODO: How do we know that this method is even web callable?
        //      For now, we just let the call itself throw an exception.

        var rvd = new RouteValueDictionary();
        rvd.Add("Controller", controllerName);
        rvd.Add("Action", call.Method.Name);
        AddParameterValuesFromExpressionToDictionary(rvd, call);
        return rvd;
    }
}
like image 145
tvanfosson Avatar answered Oct 06 '22 08:10

tvanfosson