MVC Controller Action called from PartialView in _Layout.cshtml - asp.net-mvc

In my _Layout.cshtml I want to include a dropdown list in the site header. I'm not positive of the best way to do this, but I've tried to code it using a PartialView. It seems to be working, but when the form is submitted the page loads with only the dropdownlist.
ViewModel:
namespace XXXX_Web_App.Models
{
public class LanguageListPartial
{
[DataType(DataType.Text)]
[Display(Name = "Language")]
public string Language { get; set; }
}
}
Controller:
[AllowAnonymous]
[ChildActionOnly]
public ActionResult LanguageList()
{
ViewBag.LanguageList = GetLanguageList();
return PartialView("_LanguageListPartial");
}
[AllowAnonymous]
[HttpPost]
public async Task<ActionResult> LanguageList(string language)
{
// Save selection to cookie
HttpCookie cookie = new HttpCookie("UserSettings");
cookie["Language"] = language;
cookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(cookie);
// Save selection to user profile
if (User.Identity.IsAuthenticated)
{
String userId = User.Identity.GetUserId();
ApplicationUser user = await UserManager.FindByIdAsync(userId);
user.Language = language;
await UserManager.UpdateAsync(user);
}
ViewBag.LanguageList = GetLanguageList();
return PartialView("_LanguageListPartial");
}
public List<SelectListItem> GetLanguageList()
{
List<SelectListItem> languages = new List<SelectListItem>();
languages.Add(new SelectListItem { Text = "English", Value = "en-US" });
languages.Add(new SelectListItem { Text = "Français", Value = "fr-CA" });
languages.Add(new SelectListItem { Text = "Português", Value = "pt-BR" });
languages.Add(new SelectListItem { Text = "Español", Value = "es-MX" });
return languages;
}
Partial View:
#model XXXX_Web_App.Models.LanguageListPartial
#Html.DropDownListFor(
x => x.Language,
new SelectList(ViewBag.LanguageList, "Value", "Text"),
new { #class = "form-control toggle", onchange = "this.form.submit();"
})
_Layout.cshtml:
#using Westwind.Globalization;
#using Westwind.Globalization.Resources;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryUI")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
<script src="/Scripts/jquery.cookie.js"></script>
</head>
<body>
<div style="">
<div class="header container">
... nav menu ...
</div>
<form action="/Account/LanguageList" method="post" >
#{Html.RenderAction("LanguageList", "Account");}
</form>
<div class="container">
<div class="row">
<div class="col-md-12">
#RenderBody()
</div>
</div>
</div>
<footer class="container">
<hr />
<p>© #DateTime.Now.Year</p>
</footer>
</div>
</body>
</html>
The desired logic is:
Every site/page visit
Anonymous user - load selection from cookie. Default to English. (not done yet)
Authenticated user - load selection from user profile (not done yet)
On selection
Anonymous user - save selection to cookie
Authenticated user - save selection to cookie and update user profile
Like I said, this seems to be working except that when a selection is made the Controller action gets called and when the page reloads the only thing on the page is the dropdown list.
How do I return the View in this situation?
One other question, I would like the text in the dropdown list items to include the culture specific decorations, but they are displaying literally like Français instead. I don't see how I can use Html.Encode() in this situation. It's probably being caused by the way I am adding the items in GetLanguageList(). How do I avoid this?
EDIT
To clarify, my excerpt from _Layout.cshtml above is just that - an excerpt. My _Layout.cshtml contains what you might expect of it - a header with logo and subtitle, navigation menu, and RenderBody() code. The page displays properly on the Partial View's GET Controller Action, but when I make a selection from the dropdown list the POST Controller Action only the dropdown list is displayed on the page - nothing else. _Layout.cshtml is gone and so are the contents of whatever page I am on.

When you submit the form the /Account/LanguageList action is called. It returns with only a partial view:
return PartialView("_LanguageListPartial");
When you return just this, your _layout file is not called.
So what you want is to return another view. Unless you specify it, all your views will contain your _layout.cshtml file. And that already contains the partial view.
So create a new view and return that when you post to the form.

Related

PartialView redirects rather than inserts

I have a form and a partial view on my razor page, the idea being that if I change the dropdownlist, the Controller does some work and sets a ViewBag.ShowAlert (bool) that triggers the partial view to be displayed.
While this works, instead of just showing the code within the partial view, the partial view shows as a new view rather than on the same view.
Any idea why?
The view looks like this
#using (Html.BeginForm("AlterVote", "ChangeVoteType"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h1>New voting preference</h1>
<hr />
<p>Please select the type of vote you wish to change to #Html.DropDownListFor(model=>model.SelectedType, ViewBag.myList as SelectList, "Voting type", new { onchange = "this.form.submit();"})</p>
<div id="partialDiv">
#if (ViewBag.ShowAlert)
{
#Html.Partial("VotingChange")
}
</div>
</div>
}
The controller handling the HttpPost is this
[HttpPost]
public PartialViewResult AlterVote(Dropdown dropType)
{
ChangeBoilerPlate(dropType.SelectedType);
dropType.CurrentType = VoteTypeNames[(int)HomeController.VoterModel.CurrentVoteType];
return PartialView("VotingChange", dropType);
}
I'm guessing that this is down to the initial view being a form, so the partial gets confused as to where to insert the view.
If I understand correctly, by the partial view shows as a new view you mean it comes with a html tag, body and the full layout again. To solve this, you need to set up the layout to null inside your partial view, like so:
#model YourNamespace.Dropdown
#{
Layout = null;
}
<!-- partial view html below -->
<div>
</div>
The div tag is just to illustrate.
While this might solve your problem, you might want to load the partial view without reloading the whole page again. This is possible using ajax, like so:
Main View
#using (Html.BeginForm("AlterVote", "ChangeVoteType"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h1>New voting preference</h1>
<hr />
<p>Please select the type of vote you wish to change to #Html.DropDownListFor(model=>model.SelectedType, ViewBag.myList as SelectList, "Voting type", new { id = "vote"})</p>
<div id="partialDiv">
</div>
</div>
}
<script type="text/javascript">
$(document).ready(function () {
$('#vote').change(function() {
var selectedType = $(this).val();
$.post('yourserver/YourController/AlterVote', { "SelectedType": selectedType })
.done(function (data) {
$('#partialDiv').html(data);
})
.fail(function () {
console.log('Whoops, something went wrong!!!');
});
});
});
</script>
So I just added a javascript to listen to that same change event on your dropdrown, but instead of submitting the form, I just use ajax to load the partial view html without reloading the entire page.
Just fix the URL and remember to set up layout to null in your partial view. Also, you might want this javascript in a separate file, thus loading it with bundles.

What is the MVC equivalent of Find Control?

In ASP.NET web forms it is possible to modify page controls from the master page. For example, on a page "/Sample" I could set TextBox1 as readonly by doing the following.
//Site.master.cs
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Path.ToUpper().Contains("/SAMPLE"))
{
TextBox TB = MainContent.FindControl("TextBox1") as TextBox;
TB.ReadOnly = true;
}
}
The question is... Is there an equivalent way to do this in an MVC application that uses a SiteLayout?
Background: We have purchased an MVC application and have access to modify the
source code. We need to customize the behaviors on some of the pages. It
will only be used by a few dozen people so a performance hit won't really be noticeable. If this was a Web Forms
application we would use the above method. However this application
is written with MVC and it is making our web form programmer (me) confused on how best to proceed. Customizing numerous pages is going to be a headache when
we have to patch the software. Having all the changes in one central location
would be easier to manage going forward. How can you have one place where you can customize other pages programmatically in MVC?
There is no MVC equivalent for FindControl, since views are built in a single operation, where ASP.NET controls are built up and modified over several different events. You don't need to find the control, you specify all of its attributes as it is built.
The rough equivalent to an ASP.NET control (at least in this context) is an HTML helper. HTML helpers are implemented as static extension methods, which allows them to be shared between views and perform some actions as the view is loaded.
using System.Web.Mvc;
using System.Web.Mvc.Html;
public static class MyExtensions
{
public static MvcHtmlString TextBox1(this HtmlHelper helper, string name)
{
if (helper.ViewContext.HttpContext.Request.Path.ToUpper().Contains("/SAMPLE"))
{
return InputExtensions.TextBox(helper, name, null, new { #readonly = "readonly" });
}
return InputExtensions.TextBox(helper, name);
}
}
Usage
~/Views/Shared/_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title - My ASP.NET MVC Application</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">#Html.ActionLink("your logo here", "Index", "Home")</p>
</div>
<div class="float-right">
<section id="login">
#Html.Partial("_LoginPartial")
</section>
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
#RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
#* Render custom HTML Helper *#
#Html.TextBox1("test")
#RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
<p>© #DateTime.Now.Year - My ASP.NET MVC Application</p>
</div>
</div>
</footer>
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
</body>
</html>
Note that it is also possible to put the logic directly in the view, but then you cannot reuse logic in other views and it makes your view look cluttered.
As for reading the data back out of a textbox, you need to put it within a <form> tag so it can be posted to a controller action method, which is the rough equivalent of a submit button click event. Unlike ASP.NET, MVC supports multiple <form> tags so you don't have to mix your logic for different actions on the page.
Your question is very broad. But generally, if you want to provide read only rendering for your controls in your razor views based on some conditions, you can try the below approach.
You should add a IsReadOnly property to your view model and use that to render the control the way you wanted.
public class CreateCustomerVM
{
public bool IsReadOnly {set;get;}
//Other properties goes here
public string Email { set; get; }
public string Name { set; get; }
}
In your Action method set the IsReadOnly propery value based on your condition.
public ActionResult Index()
{
var vm=new CreateCustomerVM();
//Set the value based on your condition
vm.IsReadOnly=true;
return View(vm);
}
And in your view , you use the IsReadOnly property to determine whether you want to display a readonly control or not.
#model YourNameSpaceGoesHere.CreateCustomerVM
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Email)
if(Model.IsReadOnly)
{
#Html.TextBoxFor(m => m.Name, new { #readonly = "readonly" })
}
else
{
#Html.TextBoxFor(m => m.Name)
}
<input type="submit"/>
}

MVC4 Post form null value

I have a grid when the client click on Edit for one like a form is open. the User can Edit only some values (let the user to edit only the Shipping date for the current order) but when I send the Form the values of the non editable field are NULL on Post
When I display :
#Html.Display(model => model.Rep)
or :
#Html.TextBoxFor(model => model.ClientName, new { disabled = "disabled", #readonly = "readonly" })
the Values are displayed correctly but when I submit the form the Value are Null.
the View :
#model Models.Orders
#{
Layout = null;
}
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="~/Content/pure-release-0.5.0/pure-min.css" rel="stylesheet" />
</head>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<body>
<form class="pure-form">
<fieldset>
<legend>A Stacked Form</legend>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-3" aria-disabled="true" aria-readonly="true">
<label for="first-name">#Html.LabelFor(model => model.Rep)</label>
#Html.Display(model => model.Rep)
</div>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-3" aria-readonly="true">
<label for="first-name">#Html.LabelFor(model => model.ClientName)</label>
#Html.TextBoxFor(model => model.ClientName, new { disabled = "disabled", #readonly = "readonly" })
</div>
</div>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
</form>
</body>
}
</html>
<script type="text/javascript">
$(document).ready(function () {
$(".Titre").click(function () {
$(this).next('.Contenu').slideToggle("slow");
});
$("#Model").prop('disabled', true);
});
</script>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}^
The model :
public class Orders
{
public int ID { get; set; }
public string Rep { get; set; }
public string ClientName { get; set; }
}
Controller :
When the User click on Edit on the Grid:
public ActionResult Edit(int id = 0)
{
Orders order = db.Orders.Find(id);
if (order == null)
{
return HttpNotFound();
}
return View(order);
}
On post:
[HttpPost]
public ActionResult Edit(Orders order)
{
if (ModelState.IsValid)
{
db.Entry(order).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(order);
}
When I debug I find theat the Values on order are NULL
I Thought that the problem was the waay that I sent data from my grid to the form but i change the easyui to Use GridMVC and still have the problem.
I used : in View TextBoxFor for readOnly + disabled as attribut but same problem
I tried :
in the Model : [ReadOnly(true)]
+ in the View : #Html.EditorFor(model => model.Rep) but I was able to edit Rep That I want to block
I tried to make the EditorFor readonly with Javascript but I was able to edit
Can you help me please, I tried all what I found but there is something missing in my code
Thanks
This is by design. Readonly values are not submitted to server (at least by modern browsers).
If you want to submit this value you can create a hidden field instead of a textbox:
#Html.HiddenFor(model => model.ClientName)
This will effectively submit your value to server
I ran into the same issue. Trying to short cut with the MVC CRUD template. I like what #PaulTaylor suggested:
Attribute [Bind(Exclude=“”)] fails to prevent over-posting
The problem is because you are using 2 forms: one nested to the other. You have to remove the second and add the css class to the first. The Html.BeginForm() will create another form.
You can try something like this:
#using (Html.BeginForm("Edit","controllerName",null,FormMethod.Post,{#class="pure-form"}))
{
#Html.ValidationSummary(true)
<body>
#Html.HiddenFor(model => model.ID)
<fieldset>
<legend>A Stacked Form</legend>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-3" aria-disabled="true" aria-readonly="true">
<label for="first-name">#Html.LabelFor(model => model.Rep)</label>
#Html.Display(model => model.Rep)
</div>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-3" aria-readonly="true">
<label for="first-name">#Html.LabelFor(model => model.ClientName)</label>
#Html.TextBoxFor(model => model.ClientName, new { disabled = "disabled", #readonly = "readonly" })
</div>
</div>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
</body>
}
Your text box is disabled. The inputs with disabled attribute set do not get submitted with the form. You can verify this by using network tab of Chrome dev tool or your favorite browser. If you want the text boxes disabled, use just readonly and not the disabled. So, your text box should be as below:
#Html.TextBoxFor(model => model.ClientName, new {#readonly = "readonly" })
Afterwards, you can use jQuery and CSS to make them look like disabled by graying them out if you like but do not use disabled if you want the values to come through.

When I submit the partial view by either keeping the textbox filled/empty, in both cases full view is loading. How can I call Ajax to post it?

I have Area in MVC3 as mentioned below.
Model
public class AdminModule
{
[Display(Name = "MyName")]
[Required(ErrorMessage = "MyName is missing")]
public String MyName { get; set; }
}
I have Partial View with following code.
#model _1.Areas.Admin.Models.AdminModule
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "myForm" }))
{
#Html.LabelFor(i => i.MyName)
#Html.TextBoxFor(i => i.MyName)
#Html.ValidationMessageFor(i => i.MyName)
<p id="getDateTimeString">
</p>
<input type="submit" value="Click here" id="btn" />
}
View
#model _1.Areas.Admin.Models.AdminModule
#{
ViewBag.Title = "Index";
Layout = "~/Areas/Admin/Views/Shared/_LayoutPage1.cshtml";
}
<h2>
Index</h2>
<script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript">
</script>
<script type="text/javascript" src="/scripts/jquery.unobtrusive-ajax.js">
</script>
<div id="myForm">
#Html.Partial("_PartialPage1", Model)
</div>
Layout
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
</head>
<body>
<div>
#RenderBody()
</div>
</body>
</html>
Controller Actions
[HttpPost]
public ActionResult Index(AdminModule model)
{
return PartialView(model);
}
[HttpGet]
public ActionResult Index()
{
AdminModule model = new AdminModule();
model.MyName = "My Name";
return View(model);
}
Confusion
When I submit first time.
I get output like below
and form show like this. Question is - Why is index word coming two times?
When I click second time, form appearance remains same and output shows like below.
Question - Why is Jquery coming so many times ?
You could use an Ajax.BeginForm instead of a regular form. But first you should decide which section of your page you want to be updated after the AJAX call.
Let's suppose the following scenario: if the AJAX call is successful you want to update some section of your DOM with some result and if the AJAX fails you want to update the form and display the error message instead.
To implement this you could start by placing the form inside a partial (_MyForm.cshtml):
#model _1.Models.HomeModels
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "myForm" }))
{
#Html.LabelFor(i => i.MyName)
#Html.TextBoxFor(i => i.MyName)
#Html.ValidationMessageFor(i => i.MyName)
<input type="submit" value="Click here" id="btn" />
}
#if (Model.SomeResultProperty != null)
{
<div>#Model.SomeResultProperty</div>
}
and then you could have your main view reference this partial:
#model _1.Models.HomeModels
<div id="myForm">
#Html.Partial("_MyForm", Model)
</div>
The next step is to update your controller action that will handle the AJAX call:
[HttpPost]
public ActionResult Index(HomeModels model)
{
if (ModelState.IsValid)
{
// validation succeeded => we could set the result property
// on the model to be displayed:
model.SomeResultProperty = "this is the result";
}
return PartialView("_MyForm", model);
}
and finally you need to include the jquery.unobtrusive-ajax.js script to your page in order for the Ajax.BeginForm helper to work:
<script type="text/javascript" src="#Url.Content("~/scripts/jquery.unobtrusive-ajax.js")"></script>
Use Ajax.BeginForm instead.
Did you reference validation scripts in your page?

ASP.NET MVC Ajax.BeginForm doesn't work

<script src="../../Scripts/MicrosoftAjax.debug.js" type="text/javascript"></script>
<script type="text/javascript">
function loginOK()
{
var item = document.getElementById('statusLabel');
item.innerHTML = "OK";
document.getElementById('LoadImg').style.visibility = 'hidden';
}
function process()
{
var lab = document.getElementById('statusLabel');
lab.innerHTML = 'Checking...';
lab.style.color = 'Black';
document.getElementById('LoadImg').style.visibility = 'visible';
}
function fail()
{
var lab = document.getElementById('statusLabel');
lab.innerHTML = 'Login is being used';
lab.style.color = 'Red';
document.getElementById('LoadImg').style.visibility = 'hidden';
}
</script>
<div style="width:30%; float:left;">
<label for="Login">Login:</label>
<%= Html.TextBoxFor(model=>model.Login) %>
<%= Html.ValidationMessageFor(model=>model.Login) %>
<img id="LoadImg" alt="" src="../../Content/Images/ajax-loader.gif" style="visibility:hidden;"/>
<br />
<label id="statusLabel" />
<br />
<%=Ajax.ActionLink("CheckLogin","CheckLoginAvailability", "Account",
new AjaxOptions { UpdateTargetId = "statusLabel", OnBegin = "process", OnFailure = "fail", OnSuccess="loginOK"})%>
</div>
and, in the AccountController:
[AcceptVerbs(HttpVerbs.Post)]
public void CheckLoginAvailability(string login)
{
//do some job
}
And, FireBug says that /Account/CheckLoginAvailability is not found. Also, after callback that ActionLink is hidden. Why ?
You are talking about Ajax.BeginForm in your question but this is nowhere to be seen in the markup you provided. There are a couple of issues that I can see with your code:
Your action method doesn't return an ActionResult. Yeah I know, you will say that this is possible, right, but that's against any good practices, conventions and rendering your controllers unit-test friendly.
You are using Microsoft Ajax which will mix markup and javascript which IMHO is bad for multiple reasons: increasing bandwidth which of course leads to decreased performance, incapacity to externalize javascript into separate files in order to cache them by client browsers, having to write things like document.getElementById, innerHTML, style.color, style.visibility, etc... which is not guaranteed to work cross browser.
Here's what I would suggest you to improve this. While this doesn't answer your question, take it as an alternative approach.
As always the first thing to deal with is to define a model which in your case might look something like this:
public class LoginViewModel
{
public string Login { get; set; }
}
Of course you might wish to add other fields such as Password, but this is out of scope for the moment. The next step is to write a controller dealing with this model (in parallel you should be already setting a unit-test for the future controller to prepare the ground):
public class HomeController : Controller
{
public ActionResult Index()
{
// Simply return the Login form
return View(new LoginViewModel());
}
[HttpPost]
public ActionResult Index(LoginViewModel model)
{
// Deal with the actual authentication, etc...
throw new NotImplementedException();
}
[HttpPost]
public ActionResult CheckLoginAvailability(LoginViewModel model)
{
// TODO: query your datasource to determine whether
// model.Login is taken
// For this purpose we will suppose that it is taken
bool isLoginTaken = true;
// return a JSON object containing the result
return Json(new { IsLoginTaken = isLoginTaken });
}
}
The last part is to paint the screen:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<SomeNs.Models.LoginViewModel>" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Login</title>
<!-- Use a separate CSS to avoid mixing markup with styling -->
<link rel="stylesheet" type="text/css" href="<%: Url.Content("~/content/site.css") %>" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<!-- Always use HTML helpers when dealing with Urls -->
<script type="text/javascript" src="<%: Url.Content("~/scripts/login.js") %>"></script>
</head>
<body>
<% using (Html.BeginForm()) { %>
<%: Html.LabelFor(x => x.Login) %>:
<%: Html.TextBoxFor(x => x.Login) %>
<%: Html.ValidationMessageFor(x => x.Login) %>
<br/>
<!-- Always use HTML helpers when dealing with Urls -->
<img id="loadImg" alt="" src="<%: Url.Content("~/content/images/ajax-loader.gif") %>" style="display:none;" />
<br />
<div id="statusLabel"></div>
<br />
<!-- Give this link an id so that we can easily identify it from javascript -->
<%: Html.ActionLink("CheckLogin", "CheckLoginAvailability", "Home", null, new { id = "checkLogin" })%>
<input type="submit" value="Login" />
<% } %>
</body>
</html>
And the last part is to unobtrusively attach our javascript (using jQuery of course) in the login.js file:
// When the DOM is ready
$(function () {
// Attach a click handler to the checkLogin link
$('a#checkLogin').click(function () {
// When this link is clicked send an AJAX POST request
// to the address this link is pointing to
$.ajax({
type: 'POST',
url: this.href,
// Pass as parameter in the POST body the login
// entered by the user
data: { login: $('#Login').val() },
beforeSend: function () {
// show the spinner image before sending any AJAX request
// to inform the user of an ongoing activity
$('#loadImg').show();
},
complete: function () {
// hide the spinner image when the AJAX request completes
// no matter if it succeeded or not
$('#loadImg').hide();
},
success: function (result) {
// if the AJAX request succeeds
// query the IsLoginTaken property
// of the resulting JSON object
if (result.IsLoginTaken) {
// Show the status label with red if the login is taken
$('#statusLabel').html('Login is being used').css('color', 'red');
} else {
// Show the status label in black if the login is not taken
$('#statusLabel').html('OK').css('color', 'black');
}
}
});
return false;
});
});
As #SLaks says actions can return void but, I think the action signature is such that it is required to return an action result and you can return EmptyResult if you don't want to return anything.
see this http://www.asp.net/mvc/tutorials/asp-net-mvc-controller-overview-cs
try changing your AccountController to
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CheckLoginAvailability(string login)
{
//do some job
return new EmptyResult();
}

Resources