1

I'd like to have two methods on my controller with the same name but the only difference being the parameter one takes a parameter of T and the other of List

[HttpPost]
public ActionResult Edit(myType parameter)
{ 
    //snip
}

[HttpPost]
public ActionResult Edit(List<myType> parameter)
{ 
    //snip
}

The framework is throwing an exception so I am guessing this isn't possible.

The current request for action 'Edit' on controller type 'MyController' is ambiguous between the following action methods:

I'm calling these methods from a jQuery ajax call, where data could be T or an array of T.

$.ajax({
    url: url,
    type: "POST",
    contentType: "application/json, charset=utf-8",
    dataType: "json",
    data: JSON.stringify({ parameter: data }),
    success: function () {
        //success
    },
    error: function (e) {
        //error
    }
});
Nathan Koop
  • 24,803
  • 25
  • 90
  • 125
  • Note, similar, but different question here: http://stackoverflow.com/questions/436866/can-you-overload-controller-methods-in-asp-net-mvc – Nathan Koop Jul 20 '12 at 15:45

4 Answers4

0

The key thing here is that you could surely just use overload that takes a List, and even if only passing a single object, you just end up with a list with 1 item in it. All you need to do is pass the data in as a json array.

stevethethread
  • 2,524
  • 2
  • 30
  • 29
0

It seems that is not possible, the framework gets confused about what action you really want to call. But, can you simply maintain one of the actions above? Or each one do diferent things? If so, then your url scheme maybe needs a little revision.

If the two do more or less the same thing, you can add a parameter to specy if you want "mode 1" (single value) or "mode 2" (more values):

[HttpPost]
public ActionResult Edit(List<myType> parameter, bool? multiple)
{ 
    var multipleValues = multiple.GetValueOrDefault(true);
    if (!multipleValues)  ....
}

EDIT

You can use a custom ModelBinder to deserialize the json data.

Binder:

public class MyTypeBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;

        // reset input stream
        request.InputStream.Position = 0;

        // read content
        var jsonString = request.ContentEncoding.GetString(request.BinaryRead((int)request.InputStream.Length));

        var serializer = new JavaScriptSerializer();

        return jsonString.TrimStart().StartsWith("[")
            // array, just parse it
            ? serializer.Deserialize<List<MyType>>(jsonString)
            // single object, add to a list
            : new List<MyType>() { serializer.Deserialize<MyType>(jsonString) };
    }
}

Then, on the action:

public ActionResult Test([ModelBinder(typeof(MyTypeBinder))] List<MyType> type) 
{
   ....
}
Marcelo De Zen
  • 9,439
  • 3
  • 37
  • 50
  • Unfortunately this won't because the ajax call sends in either an array or a single object, if it's always an array this would be fine, but if it's a single object the parameter will be null. – Nathan Koop Jul 20 '12 at 15:58
0

Nathan,

you could try this:

[HttpPost, ActionName("Edit")]
public ActionResult EditMytype(myType parameter)
{ 
    //snip
}

[HttpPost]
public ActionResult Edit(List<myType> parameter)
{ 
    //snip
}

got something similar going in a project

jim tollan
  • 22,305
  • 4
  • 49
  • 63
0
[HttpPost, ActionName("EditType1")]
public ActionResult Edit(myType parameter)
{ 
    //snip
}

[HttpPost, ActionName("EditType2")]
public ActionResult Edit(List<myType> parameter)
{ 
    //snip
}

From the views,

/controllername/edittype1

/controllername/edittype2
VJAI
  • 32,167
  • 23
  • 102
  • 164