1

I have two Actions in my controller with different names but when I try to send data to the second, I get an error saying:

The current request for action 'Index' on controller type 'HouseholdController' is ambiguous between the following action methods: System.Web.Mvc.ActionResult Find(Int32) on type WhatWorks.Controllers.HouseholdController System.Web.Mvc.ActionResult Index(Int32) on type WhatWorks.Controllers.HouseholdController

Every other question on this that I've found has been to do with the Actions having the same name. I can't work out where I'm going wrong although there may be a better way to accomplish what I'm trying...

Controller Code

public ActionResult Index(int page = 1)
{
    int pagesize = 10;
    var model = GetDisplay().OrderBy(i => i.familyId);
    return View(model.ToPagedList(page, pagesize));
}

//
// GET: /HouseholdSearch/

public ActionResult Search()
{
    return PartialView("Find");
}

[HttpParamAction]
public ActionResult Find(int Id)
{
    var model = GetDisplay().TakeWhile(m => m.familyId == Id);
    return View("Index", model);
}

Partial View "Find"

@using BootstrapSupport
@model WhatWorks.ViewModels.HouseholdListViewModel

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset class="form-horizontal">
        @Html.LabelFor(model => model.familyId, new { @class = "control-label" })
    <div class="controls">
        @Html.TextBoxFor(model => model.familyId, new { @class = "input-mini" })
        @Html.ValidationMessageFor(model => model.familyId, null, new { @class = "help-inline" })
    </div>
    <div>
        <button type="submit" name="Find" class="btn ">Search</button>
    </div>
    </fieldset>
}

HTTPParamAction Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Reflection;

public class HttpParamActionAttribute : ActionNameSelectorAttribute
{
    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
            return true;

        var request = controllerContext.RequestContext.HttpContext.Request;
        return request[methodInfo.Name] != null;
    }
}
Simon Martin
  • 4,203
  • 7
  • 56
  • 93
melkisadek
  • 1,043
  • 1
  • 14
  • 33
  • What is your HttpParamAction attribute code? I think that's the issue -- I assume that's an ActionNameSelectorAttribute, and it's responding that "Index" is a valid name for that action. – Jacob Mattison Oct 02 '13 at 17:35
  • Have you defined any custom routes? – zimdanen Oct 02 '13 at 18:44
  • @JacobM I've added the code above. It is [from here...](http://stackoverflow.com/questions/16479946) – melkisadek Oct 02 '13 at 18:47
  • @zimdanen No custom routes are defined. The [HTTPPost] attribute as suggested by p.s.w.g is working insofar as it hits the correct action but it just loops around the Find action when it should go to the Index view. – melkisadek Oct 02 '13 at 18:53
  • Perhaps because the button has `name="Find"`, that's causing the line in the HttpParamActionAttribute that says `return request[methodInfo.Name] != null` to return true. That is, request["Find"] isn't null, so the Find method reports that it is a match. – Jacob Mattison Oct 02 '13 at 18:54
  • I've realised I was over-complicating a simple process. I've added an answer. Thanks for the pointers... – melkisadek Oct 02 '13 at 19:18

2 Answers2

2

Try adding an [AcceptVerbs(HttpVerbs.Post)] or [HttpPost] attribute to your find method:

[HttpParamAction]
[HttpPost]
public ActionResult Find(int Id)
{
    var model = GetDisplay().TakeWhile(m => m.familyId == Id);
    return View("Index", model);
}
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • Thanks, this worked but I'm getting another error which is probably related. I'll work on it and post a new question if needed. – melkisadek Oct 02 '13 at 18:06
  • The new error is due to the call to the "Index" view coming straight back to the Find Action. I can't work out why this is happening when the Actions have unique names. – melkisadek Oct 02 '13 at 18:54
1

I've amended the BeginForm to explicitly reference the Find action and this is working without any extra attributes.

I think I was just expecting a more complicated solution!

@using (Html.BeginForm("Find", "Household"))
melkisadek
  • 1,043
  • 1
  • 14
  • 33