4

On MVC3, is there a way to decorate a ViewModel property in order to get the DefaultModelBinder to use a different name for it in the request?

For example, suppose you have the following view model:

public class SomeModel 
{
  public string Direction {get;set;}
}

But the parameter coming in is Dir from an external source (such as some third-party component, for example).

I know a custom model binder could handle that, but I assume there must be a way to decorate the property, similar to the way action parameters can use Bind(Prefix="...") in order to define that mapping.

Pablo Romeo
  • 11,298
  • 2
  • 30
  • 58
  • Does [this answer](http://stackoverflow.com/a/4316327/172196) help? – Jason Berkan Apr 11 '13 at 16:52
  • 1
    Well, that's the thing. I know a custom binder can do the job, but it seems a bit like overkill for a simple alias. – Pablo Romeo Apr 11 '13 at 16:56
  • Is there a reason you aren't creating a new Model and Method for a call from a 3rd party? – Erik Philips Apr 11 '13 at 18:22
  • I could, but I don't like having to name my property "Dir" just because that's what extJS wants. I thought there might be a way to decorate the viewmodel to help the default model binder find the value, without having to manually code a custom binder. Now, it could be very well possible that the answer to this question is just simply "NO". – Pablo Romeo Apr 11 '13 at 18:27
  • 1
    I just found this: http://stackoverflow.com/q/8507699/1373170 which is basically asking the same thing, and it seems that the answer is most likely "No, write a custom binder or rename the properties" – Pablo Romeo Apr 11 '13 at 18:48
  • If it's asking the same thing, this question is a duplicate – Liam Sep 19 '16 at 15:08

3 Answers3

3

You could always create another Property:

public class SomeModel 
{
  public string Direction {get;set;}
  public string Dir
  {
    get { return this.Direction; }
    set { this.Direction = value; }
  }
}

I'd also mention that the ViewModel used in a view (cshtml/vbhtml) does not have to be the same ViewModel used on the Post Method.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • 1
    Correct, but that's more of a workaround than a solution, isn't it? – Pablo Romeo Apr 11 '13 at 18:13
  • Is rewriting a new Model Binder a workaround or a solution? I would argue they are both solutions. You could use the ModelBinderAttribute as suggested [here](http://blog.maartenballiauw.be/post/2008/09/01/Using-the-ASPNET-MVC-ModelBinder-attribute.aspx), but my personal take is that then EVERY call needs to use it, and the model doesn't represent what it's actually doing. Doesn't seem very maintainable to require programmers to remember to do some attribute in a parameter to bind correctly. – Erik Philips Apr 11 '13 at 18:17
  • Well, writing a new binder would be a solution to a similar question, but that's why in mine I was actually asking if there's already something in MVC3 that could allow decorating a ViewModel to manage that mapping, precisely without a custom binder. Since it seems like a relatively common scenario that one might face. I'm not saying a mandatory attribute, just one for a special case where you desire to use a more user-friendly name (in my case it's extJS that is sending a Dir param to represent sorting direction). I agree, specifying the binder on every action wouldn't be a good idea at all. – Pablo Romeo Apr 11 '13 at 18:24
2

OK, so after more research looking at similar questions and seeing the feedback here as well, it seems that the answer to my question is basically "NO".

There is no out-of-the-box way, so either custom binders must be used or or the properties should be renamed.

A similar question with a more detailed answer can be found here: How to bind URL parameters to model properties with different names

Community
  • 1
  • 1
Pablo Romeo
  • 11,298
  • 2
  • 30
  • 58
0

I was able to accomplish this in ASP.NET MVC Core using the FromForm attribute.

public class DataTableOrder
{
    public int Column { get; set; }

    [FromForm(Name = "Dir")]
    public string Direction { get; set; }
}

Documentation: https://docs.asp.net/en/latest/mvc/models/model-binding.html#customize-model-binding-behavior-with-attributes

However, depending if you do a GET or a POST, you might want to use [FromQuery] instead of [FromForm] I suppose.

Fred
  • 12,086
  • 7
  • 60
  • 83