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.
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.
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.
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.
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.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With