ASP MVC Action parameters all strings vs explicit type

asp.net-mvc

A colleague and I were developing an ASP.NET MVC project and during this we created a new action method to handle one of our views. I initially started created the action like so:

public ActionResult Index(int id, int numberOfAssessments, int age)
{
    // do stuff
}

However when I started writing we had a little discussion:

Him:"Why am I making these ints, they should all be strings"

Me: "Well they are ints so it makes more sense to make them strongly typed and so stop potential errors later in the code block".

Him: "Back what if we wanted to change the id to a alpha-numeric representation. We know have to change this signature everywhere where if it was a string it would already handle this".

Me: "It's not a string now and we don't have any plans for making it a string at this moment though".

We didn't really decide explicitly what to do but it did get me thinking.

Question:

Should parameters to Action methods be all strings if that is going to make it more flexible in the future, or should they be specific to their type so that we can leverage MVC binding and error handling? What is the best or accepted practice in these situations.

Are there too many considerations to take in for any definitive answer?

Best Answer

You're actually asking two different questions here.

  1. Should MVC parameters all be strings?

    Of course they shouldn't. The fact that you may want to change the type later is an absurd argument; somewhere, somehow, some component is going to be depending on that ID being a specific type, and it's not going to be any easier or less risky in the future to change a bunch of casts and type checks than it is going to be to change the type of a parameter.

    If the designers of ASP.NET MVC didn't want you to use strong-typed parameters (or the more sophisticated equivalent, model binding with strong-typed properties) then they wouldn't have written a ton of code to support exactly that scenario. Strong typing is one of the main reasons to use a framework like MVC, instead of legacy frameworks where you had to screw with Request.QueryString and so on.

    If you miss the good old days of Request.Form and Request.QueryString and don't think you'll ever need to overload any of your action methods, then by all means turn all your parameters into strings for nostalgia. If you still have some measure of sanity left, you'll leverage the extensive validation that's built into MVC for your convenience and use the correct types.

  2. Should IDs be strings?

    This is a much more difficult question to answer because very often it depends on the ID.

    A lot of the time you may have different developers and/or different teams working on the same product or feature. Often there will be domain model code and/or APIs written before anyone has any clue about how or where it's going to be stored. Other times you'll be working in a DDD/BDD style and want to express the fact that it really doesn't matter what type it is because there's no validation associated with it.

    You see, web APIs lend themselves very well to the string-as-ID model, because no matter what the underlying type turns out to be, the error handling is trivially simple: Try to convert to the expected type, and if conversion fails, then return a 404. An invalid ID is functionally the same as a missing resource.

    The above doesn't work if you allow the client to specify its own IDs for new resources, but then again, if you're going to allow the client to specify its own IDs, you really should make the ID a string instead of imposing arbitrary and probably undocumented restrictions on the client. Non-string IDs are usually non-strings specifically because they need to be auto-generated, e.g. an integer sequence, a GUID, a BSON Object ID, etc. If your ID isn't auto-generated, a string is typically the best choice for your underlying data model because it allows for the most human-readable IDs.

    I prefer to use string IDs in my API and/or view models because it saves me having to worry about what the database guys are doing and/or potentially have to face a type change. But that is merely personal preference from my own experience and certainly not a hard and fast rule about MVC; there are certain frameworks/products that have real trouble with string IDs (RavenDB, I'm lookin' at you) so it's not a decision you should make lightly, not unless you can understand and predict the consequences.

So there is some merit to the argument about making the ID a string - but not to making all of the parameters strings for no real reason. That's just weird and I'd take a hot steaming dump on it if I ever saw it in a code review.

Related Topic