I am making an Ajax call to a Controller Action using .get
but the parameter is always null when the Controller Action fired. The trigger is a .on(change)
event in a jQuery script contained in my _Layout.cshtml
. I posted this question earlier, but the thread got trashed with unrelated chatter. Can someone help me troubleshoot why this is happening? Here is the code:
Partial View: ~/Views/Shared/_LanguageListPartial.cshtml
@Html.DropDownListFor(
x => x.SelectedLanguage,
Model.Languages,
new { @class = "form-control" }
)
_Layout.cshtml
<form action="/Account/ListPartial" method="post"
class="navbar-form navbar-right nopadding" role="" style="margin: 8px 0;">
@{Html.RenderAction("LanguageListPartial", "Account");}
</form>
<div id="test"></div>
GET: /Account/LanguageListPartial
[AllowAnonymous]
[ChildActionOnly]
public ActionResult LanguageListPartial()
{
// Retrieve user's language preference. Default = en-US
string SelectedLanguage = GetLanguage();
var model = new LanguageListPartialViewModel();
model.Languages = GetLanguageList();
model.SelectedLanguage = SelectedLanguage;
return PartialView("_LanguageListPartial", model);
}
GET: /Account/TestPartial (Test Action for .on(change) event)
[AllowAnonymous]
public ActionResult TestPartial(string SelectedLanguage)
{
// Set Language selection in cookie and user profile
SetLanguage("SelectedLanguage");
var model = new LanguageListPartialViewModel();
// Create List<SelectedItemList> of Languages
model.Languages = GetLanguageList();
// Set user's Language preference for dropdown
model.SelectedLanguage = SelectedLanguage;
return View(model);
}
I haven't been able to completely debug the above code, but the dropdown renders as expected:
<form method="post" action="/Account/ListPartial">
<select name="SelectedLanguage" id="SelectedLanguage">
<option value="en-US">English</option>
<option value="fr-CA">Francais</option>
<option value="pt-BR">Portugues</option>
<option value="es-MX">Espanol</option>
</select>
</form>
<div id="test"></div>
At the bottom of _Layout.cshtml I have this jQuery:
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryUI")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
<script type="text/javascript">
$(document).ready(function () {
$(function () {
$('#SelectedLanguage').on('change', function () {
var a = $(this).val();
$('#test').load("/Account/TestPartial/" + a);
return false;
});
});
});
</script>
</body>
</html>
The problem is that $(this).val() == null no matter what I try. I don't see anything wrong with any of this code and hoped a sharper eye than mine might see what is wrong. I've tried IE, Firefox and Chrome. All give the same result. I've tried moving the block into the PartialView, but then the Controller Action doesn't even get fired.
Am I violating some rule of structure with the placement of the jQuery? I have other jQuery scripts in various pages and they all work, though this is the only one I've tried in a Layout.
One other really weird thing is that for some reason this script doesn't show up in Firefox for debugging. I don't think I've ever had that problem before, but it just don't show up under Scripts. Although, it's definitely getting executed since when I make a change in the dropdown the Controller Action is being called.
EDIT #1
Viewing in Fiddler, I see that the jQuery is actually working:
GET http://localhost:59655/Account/TestPartial/pt-BR HTTP/1.1
X-Requested-With: XMLHttpRequest
Accept: text/html, */*; q=0.01
Referer: http://localhost:59655/Account/Login?ReturnUrl=%2F
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
Host: localhost:59655
DNT: 1
Connection: Keep-Alive
Cookie: __RequestVerificationToken=8mK4-p6MrZCx6Iw6dvdad70QvjenwUbW6S0uxxpW7LxkAWn7wzLXompOz59o9Oq2GEt2A7sHvYZXKMOOJqnXGuCshKyHQsNFCJ62rhf2YIA1
Even though pt-BR
is being passed to the Controller Action TestPartial, SelectedLanguage
is null.
So at this point I feel that _Layout.cshtml coding is correct (including the jQuery). The Partial View code works and renders good HTML. The problem is with TestPartial() but I don't have any ideas as to why it's wrong. :S
EDIT #2
I found an interesting article by a guy who was having this same problem with ASP.NET MVC. He indicates that this problem happened to him when the Controller Action parameter was named the same as one of the model members. My parameter was named the same as the related model property, but renaming it made no difference. The article just suggests to me that there may be some really obscure reason why this is happening.
EDIT #3
As per the suggestion by @Rune, I changed the parameter id
so it is now TestPartial(string id)
. This didn't make any difference as id
is still null when called by the jQuery script. I have other Controller Actions that have varying parameter names other than id
and they work as I would expect. When I configure a route as suggested by @Rune I get an error message saying that TestPartial.cshtml could not be found and showing all of the locations that were checked.