Is there someone who could shed a light on why ambiguous methods are not allowed in ASP.Net MVC?
I updated my question just to clarify it (using Carson63000 example from his answer), the question itself remains the same.
So, lets say we have the following action
/article/list/sport
which calls
public ActionResult List(string category) { }
and want to be able to have the following action as well:
/article/list/sport/20110904
which we would like to call accompanying method
public ActionResult List(string category, DateTime date) { }
Currently the framework throws an AmbiguousMatchException
since it found two methods called List. That's the only reason for throwing the exception, that more than one method with was found that matches the actions name.
After the framework has figured out what method to use and decided that it is not ambigious, it will then try to map the supplied data from the request to the parameters of the method. Why not do this the other way around? First get all applicable methods, and then try to find the best fit by mapping parameters.
If ambiguous methods where allowed, I think the following is still possible to do.
Given that /article/list/sport
uses the route /{controller}/{action}/{category}
and that /article/list/sport/20110903
uses the route /{controller}/{action}/{category}/{date}
it would then still be possible to map data for url /article/list/sport?date=20110903
since it will match the route for just category, but can still map the data for method public ActionResult List(string category, DateTime date) { }
.
At the moment I fail to see the reason for not allowing ambiguous methods from a design perspective. The only thing I can think of myself is that it will slow down the framework too much, and therefor the current solution is the more logical one. Or am I missing another point here?
-
Because inputs are not typed and are optionalDaniel Little– Daniel Little2011年09月14日 03:37:17 +00:00Commented Sep 14, 2011 at 3:37
-
Also you can still do overloading through the use of action filters.Daniel Little– Daniel Little2011年09月14日 03:38:16 +00:00Commented Sep 14, 2011 at 3:38
-
Maybe it has something to do with reflection performance?Fred– Fred2016年04月25日 13:31:00 +00:00Commented Apr 25, 2016 at 13:31
2 Answers 2
If I understand your question correctly, I would say it is because you generally don't have explicit control over the parameters passed to an action.
Remember that the model binding will, by default, take them from a number of different places, including ones that are outside your control, like querystring.
It sounds like you're thinking that you should be able to have something like this:
/article/list/sport
Which calls ArticleController.List(string category);
And also:
/article/list/sport/20110901
Which calls ArticleController.List(string category, DateTime date);
But what happens when someone types the URL /article/list/sport?date=20110902
?
It just sounds like a recipe for unpredictable behaviour, and in return, what real benefit would you get from this sort of action overloading?
-
Well.. your example would throw the
AmbigiousMatchException
, so for the date one to work, you need either to change the name ofArticleController.List
that takes two arguments, or drop the first one, and make the date nullable (DateTime? date
) in the second one. Also, forarticle/list/sport/20110901
to work, you need to register a seperate route,{controller}/{action}/{category}/{date}
. The Urlarticle/list/sport?date=20110902
would still work, as it matches the route{controller}/{action}/{category}
(which I assume is defined because of/article/list/sport
(continued)Major Byte– Major Byte2011年09月01日 08:48:18 +00:00Commented Sep 1, 2011 at 8:48 -
(continued) So the parameter mapping from the request to the action is working fine as long as your actions are named differently. With your example in mind, ASP.Net MVC throws the
AmbigiousMatchException
as soon as it finds more than one method in the targeted controller that matches the action name. I'm trying to understand why this was chosen instead of returning a list of methods, and try to find the one that fits the best, based on the methods parameter names and the requeststring parameters + route information defined. (continue)Major Byte– Major Byte2011年09月01日 08:58:38 +00:00Commented Sep 1, 2011 at 8:58 -
(continue) Because querystring parameters are mapped on name to the method.
/article/list/sport?param1=xyz¶m2=abc&date=20110902
still invokes `ArticleController.List(string category, DateTime date) in the current implementation of ASP.Net MVC 3. Sorry for these long comments, hoped it clarified a little better what the situation is and what I'm looking for in an answer.Major Byte– Major Byte2011年09月01日 09:00:52 +00:00Commented Sep 1, 2011 at 9:00
As for getting a list of applicable methods for resolving an action, I don't see any problem with that, it is quite easily doable, as it turned out. Resolving the parameters for each method is also manageable, the only problem that seems to exist is determining the best fit.
But still it should be possible to choose one method over another some way and if there would be some sort of tie, throw the AmbiguousMethodException.
-
This doesn't answer your question. This answer is just another comment.Kristofer Hoch– Kristofer Hoch2011年09月13日 20:46:02 +00:00Commented Sep 13, 2011 at 20:46
-
In my mind it made sense for an answer, but you could be right....Major Byte– Major Byte2011年09月13日 21:03:01 +00:00Commented Sep 13, 2011 at 21:03