2

I keep running into scenarios where I would like to provide a slightly more intuitive or "well-formed" parameter name for action methods, but with the default behavior, this is turning out to be quite painful. For example, suppose that I have an action parameter like GetWidget(int id). If I want it to be GetWidget(int widgetId), I have to add a new route. It gets worse when you use a library like jqGrid which uses awful names for its querystring parameters: GetWidgets(int? nodeid, int? n_level). Instead, I'd like to have GetWidgets(int? parentId, int? level) or something similar.

So, is there something simple that I'm overlooking? It seems like it should be a very simple thing to tell MVC that my "parentId" parameter should be bound to the value of "nodeid" in the request. I thought about writing a custom action filter to do this, but it seems so obvious that I can't believe it's not supported out of the box.

3 Answers 3

8

As per Rony's answer use a custom model binder. Here is an example:

public class BindToAliasAttribute : CustomModelBinderAttribute
{
    private readonly string parameterAlias;

    public BindToAliasAttribute(string parameterAlias)
    {
        this.parameterAlias = parameterAlias;
    }

    public override IModelBinder GetBinder()
    {
        return new ParameterWithAliasModelBinder(parameterAlias);
    }
}

public class ParameterWithAliasModelBinder : IModelBinder
{
    private readonly string parameterAlias;

    public ParameterWithAliasModelBinder(string parameterAlias)
    {
        this.parameterAlias = parameterAlias;
    }

    object IModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        return controllerContext.RouteData.Values[parameterAlias];
    }
}

public class UserController : Controller
{
    [HttpGet]
    public ActionResult Show( [BindToAlias("id")] string username)
    {
        ...
    }
}
Sign up to request clarification or add additional context in comments.

Comments

3

If you use named parameters on the URL, you can specify a specific name for the parameter into your controller method, like so:

http://mydomain.com/mycontroller/getwidget?parentid=1&level=2

...and you won't have to match routes on the parameters.

2 Comments

The problem is that it's a 3rd part library that's generating the query string parameters, and it uses ugly names (like n_level). I could edit the source, but I'd like to avoid that.
I agree with Robert...if you have no special Route defined, then the ugly param names will be appended as querystring params after the question mark. The only thing you are sacrificing is the "pretty" URL. But, how "pretty" can a URL be with names like "n_level" anyway?
1

use you own custom model binder which implements IModelBinder

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.