We help IT Professionals succeed at work.

When form action is submitted, the url is incorrect and it can't find the action

lapucca
lapucca asked
on
Hi, I'm using V.S. 2008, C# for this Web page at http://www.labctsi.org/Members/SearchMembers.aspx/Index.  User would select from the Select controls and click the add button and then click the Search button and I get message of

The IControllerFactory 'CtsiMembershipApplication.MyControllerFactory' did not return a controller for a controller named 'SearchMembers'.

The url for this page is "http://www.labctsi.org/SearchMembers.aspx/Search/" which is incorrect becuase it should have been http://www.labctsi.org/Members/SearchMembers.aspx/Search/.  I put in this url and then  I get a different error for HTTP 404.

For the 1st error message is very confusing for me.  For this ASP.NET MVC project, I did copy serveral classes code from another project named, CtsiMembershipApplication" but I don't have MyControllerFactory in my prject.  Actually, I just don't have any Controllerfactory class in my project becuase I did a search for this and found none.  I also did a serach for CtsiMembershipApplication and found nothing either.

How can I correct this so

1.  when my form is submitted it will go to the right Action(Search) in my (one and only one) controller with correct url?

2.  How can I reset the researchInterests variable to null  from the Search Action after it receives it?  (This variable is declared and construted in my Search view)

Thank you.



<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="CtsiSearchMembership.Models"%>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

<script type="text/javascript">
    $(document).ready(function() {
        var selectBox;
        var selectedText;
        var researchInterestFullName;
        var addToHiddenField;
        var selectedResearchInterestCount;
        selectedResearchInterestCount = 0;
        var professionalOrganizationCount;
        professionalOrganizationCount = 0;

        var interestIds = new Array();

        $('#level2ResearchInterests').hide();
        $('#level3ResearchInterests').hide();
        $('#level4ResearchInterests').hide();


        $("#level1ResearchInterests").change(function() {

            $.getJSON("/Membership.aspx/GetChildResearchInterests/" + $(this).val(), function(json) {
                var options = '';
                for (var i = 0; i < json.length; i++) {
                    options += '<option value="' + json[i].Id + '">' + json[i].Name + '</option>';
                }
                $("#level2ResearchInterests").html(options);
                $("#level3ResearchInterests").html('');
                $("#level4ResearchInterests").html('');
                if (json.length > 0) {
                    $('#level1ResearchInterests').animate({ width: 170 }, 'fast', function() {
                        $('#level2ResearchInterests').css('width', '340px');
                        $('#level2ResearchInterests').fadeIn('fast');
                    });
                }
                else {
                    $('#level2ResearchInterests').fadeOut('fast');
                }
                $('#level3ResearchInterests').fadeOut('fast');
                $('#level4ResearchInterests').fadeOut('fast');
            })
        })

        $("#level2ResearchInterests").change(function() {

            $.getJSON("/Membership.aspx/GetChildResearchInterests/" + $(this).val(), function(json) {
                var options = '';
                for (var i = 0; i < json.length; i++) {
                    options += '<option value="' + json[i].Id + '">' + json[i].Name + '</option>';
                }
                $("#level3ResearchInterests").html(options);
                $("#level4ResearchInterests").html('');
                $('#level2ResearchInterests').fadeIn('fast');
                if (json.length > 0) {
                    $('#level2ResearchInterests').animate({ width: 170 }, 'fast', function() {
                        $('#level3ResearchInterests').css('width', '340px');
                        $('#level3ResearchInterests').fadeIn('fast');
                    });
                }
                else {
                    $('#level3ResearchInterests').fadeOut('fast');
                }
                $('#level4ResearchInterests').fadeOut('fast');
            })
        })

        $("#level3ResearchInterests").change(function() {

            $.getJSON("/Membership.aspx/GetChildResearchInterests/" + $(this).val(), function(json) {
                var options = '';
                for (var i = 0; i < json.length; i++) {
                    options += '<option value="' + json[i].Id + '">' + json[i].Name + '</option>';
                }
                $("#level4ResearchInterests").html(options);
                $('#level2ResearchInterests').fadeIn('fast');
                $('#level3ResearchInterests').fadeIn('fast');
                if (json.length > 0) {
                    $('#level3ResearchInterests').animate({ width: 170 }, 'fast', function() {
                        $('#level4ResearchInterests').fadeIn('fast');
                    });
                }
                else {
                    $('#level4ResearchInterests').fadeOut('fast');
                }
            })
        })


        //Finally reset all the research interests
        var resetResearchInterestSelection = function() {
            $("#level2ResearchInterests").hide();
            $("#level3ResearchInterests").hide();
            $("#level4ResearchInterests").hide();
            $("#level2ResearchInterests").html('');
            $("#level3ResearchInterests").html('');
            $("#level4ResearchInterests").html('');
            $('#level1ResearchInterests').attr('selectedIndex', '-1');
            $('#level1ResearchInterests').animate({ width: 340 }, 'fast');
        };



        $("#addResearchInterest").click(function() {

            if ($('#level1ResearchInterests').val() == null) return; //Nothing has been selected, so return

            //Clear out the table which shows the selected research interests if necessary.
            if (selectedResearchInterestCount == 0) { $('table#selectedResearchInterests tbody tr').remove(); };
            var selectedId;
            researchInterestFullName = '';
            addToHiddenField = 1;
            //Start from level 4 research interests, we basically only store the id of the selected Id of the lowest level Research Interest, as its parents can be inferred.
            if ($('#level4ResearchInterests').val() != null) {
                if (addToHiddenField == 1) $("#researchInterests").val($("#researchInterests").val() + $('#level4ResearchInterests').val() + ',');
                addToHiddenField = 0;
                selectBox = document.getElementById("level4ResearchInterests");
                selectedText = selectBox.options[selectBox.selectedIndex].text;
                researchInterestFullName = ">" + selectedText;
                selectedId = $('#level4ResearchInterests').val();
            };
            if ($('#level3ResearchInterests').val() != null) {
                if (addToHiddenField == 1) $("#researchInterests").val($("#researchInterests").val() + $('#level3ResearchInterests').val() + ',');
                addToHiddenField = 0;
                selectBox = document.getElementById("level3ResearchInterests");
                selectedText = selectBox.options[selectBox.selectedIndex].text;
                researchInterestFullName = ">" + selectedText + researchInterestFullName;
            };
            if ($('#level2ResearchInterests').val() != null) {
                if (addToHiddenField == 1) $("#researchInterests").val($("#researchInterests").val() + $('#level2ResearchInterests').val() + ',');
                addToHiddenField = 0;
                selectBox = document.getElementById("level2ResearchInterests");
                selectedText = selectBox.options[selectBox.selectedIndex].text;
                researchInterestFullName = ">" + selectedText + researchInterestFullName;
            };
            if ($('#level1ResearchInterests').val() != null) {
                if (addToHiddenField == 1) $("#researchInterests").val($("#researchInterests").val() + $('#level1ResearchInterests').val() + ',');
                addToHiddenField = 0;
                selectBox = document.getElementById("level1ResearchInterests");
                selectedText = selectBox.options[selectBox.selectedIndex].text;
                researchInterestFullName = selectedText + researchInterestFullName;
                selectedResearchInterestCount++;
                $('<tr><td>' + selectedResearchInterestCount + '</td><td>' + researchInterestFullName + '</td></tr>').appendTo('#selectedResearchInterests tbody').animate({ backgroundColor: 'yellow' }, 500).animate({ backgroundColor: 'white' }, 500, resetResearchInterestSelection);
                //Apply the classes in order to get striping
                $('#selectedResearchInterests tbody tr:odd').removeClass('even').addClass('odd');
                $('#selectedResearchInterests tbody tr:even').removeClass('odd').addClass('even');
            };
            alert("Selected ids are : " + $("#researchInterests").val());
            return false;
        })


        $('#level1ResearchInterests').css('width', '340px');




    })
</script>



<form action="/SearchMembers.aspx/Search/" method="post">
    <input type="hidden" name="ResearchInterests" id="researchInterests" value=""/>

    <fieldset>
        <h1>Search CTSI Members</h1>
        <br class="clear" />
        <label>Areas of Research Interest</label>
        <select id="level1ResearchInterests" name="Level1ResearchInterests" size="5" tabindex="1">
            <% foreach (ResearchInterest researchInterest in ViewData["Level1ResearchInterests"] as IList<ResearchInterest>) { %>
                <option value="<%=researchInterest.Id%>"><%=researchInterest.Name%></option>
            <% } %>
        </select>
        <select id="level2ResearchInterests" name="Level2ResearchInterests" size="5">
        </select>
        <select id="level3ResearchInterests" name="Level3ResearchInterests" size="5">
        </select>
        <select id="level4ResearchInterests" name="Level4ResearchInterests" size="5">
        </select><br /><br />
        <div class="buttonWrapper">
            <input type="button" id="addResearchInterest" value="Add Research Interest to my search criteria(s)" />
        </div>
        <br />
        
        <table id='selectedResearchInterests' class="expandingTable">
           <thead>
                <tr>
                    <th></th>
                    <th>My selected Research Interest</th>
                </tr>
            </thead>
            <tbody>
                <tr class="odd">
                    <td></td>
                    <td>No Research Interests selected yet.</td>
                </tr>
            </tbody>
        </table>   
    </fieldset>
    
    
    <div class="buttonWrapper">
        <input type="submit" id="searchMembers" value="Search" tabindex="2" />
    </div>
</form>
</asp:Content>


using System;

using System.Web.Mvc;
using CtsiSearchMembership.Models;

namespace CtsiSearchMembership.Controllers
{
    public class SearchMembersController : Controller
    {
        public IResearchInterestRepository ResearchInterestRepository { get; set; }
        
        public SearchMembersController()
        {
            var researchInterestRepository = new ResearchInterestRepository();
            ResearchInterestRepository = researchInterestRepository;
        }
        //
        // GET: /SearchMembers/

        public ActionResult Index()
        {
            ViewData["Level1ResearchInterests"] = ResearchInterestRepository.FindByParentResearchInterestId(0);

            return View("Search");
        }

        public JsonResult GetChildResearchInterests(long id)
        {
            var result = new JsonResult { Data = ResearchInterestRepository.FindByParentResearchInterestId(id) };
            return result;
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ViewResult Search(string researchInterestsString)
        {
            var interestIds = researchInterestsString;
            //var interestIds = Request.Form["researchInterests"].ToString().Trim();
            if (interestIds[interestIds.Length - 1] == ',')
                interestIds = interestIds.Remove(interestIds.Length - 1);
            ViewData["Members"] = ResearchInterestRepository.FindMembersByInterestIds(interestIds);
            researchInterestsString = string.Empty;
            ViewData["Level1ResearchInterests"] = ResearchInterestRepository.FindByParentResearchInterestId(0);
            return View("List");
        }
    }
}

Open in new window

Comment
Watch Question

Author

Commented:
Also, when I try to run this in Debug mode in my local PC it would start up with url of some port, and then error message that "The incoming request does not match any route.".  In my Global.asax file I specify the default rout for /SearchMembers/Index/ but why isn't it using that?

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}.aspx/{action}/{id}",                           // URL with parameters
                new { controller = "SearchMembers", action = "Index", id = "" }  // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }
This is a routing issue.

Firstly I'd change your html form declaration to use Html.BeginForm Html.EndForm helpers.

i.e. <form action="/SearchMembers.aspx/Search/" method="post">
should be <% Html.BeginForm("Search","SearchMembers"); %>

Then at least your form should have the correct route.

The second thing that looks strange is that you are getting an error which includes "'CtsiMembershipApplication.MyControllerFactory". Do you have your own controller factory or are you using the default ASP.NET MVC controller factory?

Author

Commented:
No, I didn't create any ControllerFactory.  However, the application where I copied most of the code from does have its own controllerfactory and the message is referencing the names correctly.  Below is the Global.asax.cs from that project.
I will start by modifying the html form to Html.BeginForm and hopefully that would work.  Thank you.
namespace CtsiMembershipApplication
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            BootStrapper.Start();
            ControllerBuilder.Current.SetControllerFactory(typeof(MyControllerFactory));
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

Open in new window

I'd also remove the custom controller factory. Unless you know of a reason why you need it.

Author

Commented:
Which custom controllerfactory are you referring to?  Looking at my code, do you see where I have this specified or where in my code can I find this specification.  I did a search for it and found nothing.  Thanks.
Here's what I mean

ControllerBuilder.Current.SetControllerFactory(typeof(MyControllerFactory));

Author

Commented:
I have a Members folder and not on the local pc.  I used the ResolveUrl and it worked on both. Thanks.