I have a MVC web application with a logout form like this:
#using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { area = "", id = "logoutForm" }))
{
#Html.AntiForgeryToken()
Log off
}
The problem is that if I have navigated to one of the areas and I click the LogOut button the action does not work.
Does anyone know how to make the above code work with the default area?
Thanks
Gerry
Got it:
#using (Html.BeginForm("LogOff", "Account", new { area = "" }, FormMethod.Post, new { id = "logoutForm" }))
This works!!!!!
Related
I have a partial view that has an Ajax.BeginForm, it renders after clicking on a link, it was working before but I changed it and now its not working, this is what it looks like now:
#using (Ajax.BeginForm(
"AddTimeSeriesData",
"Employees1Controller",
new routevalues { },
new AjaxOptions { UpdateTargetId = domElementId, InsertionMode = InsertionMode.ReplaceWith },
new { id = "ajax_form" }
)
)
{
is my declaration wrong? Isn't this a valid overload?
when I had the following it worked:
#using (Ajax.BeginForm(
new AjaxOptions { UpdateTargetId = domElementId, InsertionMode = InsertionMode.ReplaceWith }
)
)
{
AddTimeSeriesData should be your Action Method on your controller Employees1Controller.
Make sure your contoller name correct, I guess it should be Employees1 and not Employees1Controller.
Since you are doing nothing on parameter three (new routevalues) remove it.
Hope fully it will work for you.
After Using the Ajax.ActionLink As
#Ajax.ActionLink("Edit", "AddEdit", new { #id = id, #recId = item.EncyclopediaID }, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "listForm" }, new { #class = "edit_icon", #title = "edit this item" })
And When Controller Go to AddEdit Page There i have Uploaded the File and want to show the Ckeditor.
So i use
#using (Html.BeginForm("AddEdit", "Encyclopedia", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
/////////other code//////////////////
#Html.EditorFor(model => model.Description,"CKEditor")
}
Now if i use to show the #Html.ActionLink instead of #Ajax.Actionlink Ckeditor Shows perfectly and in Ajax call it showed like a textarea.
Please Help.
this happens because resource files required for ckeditor to work correctly (eg: css , javascript) cannot be downloaded with an ajax call.
try referencing the required resource files in layout view page and try again.
Edit :
maybe you have placed integration code in document.ready function, thus after ajax request completed and you markup changed, the new markup (eg:your new input element) is not configured as ckeditor input.so try calling ckeditor integration code after ajax success.
I have looked at many of the solutions on offer on this site and others for my problem but none of them seem to work perfectly for my solution.
On my Layout page I have a login area on the top of the screen. This is always present unless a user is logged in. This login form has a ValidationSummary on it and every time I post back using another form on the site the validation for this login form is being triggered.
I'm almost certain that this is down to how I call this login page from my Layout page. It is not a partial view that is in a Shared folder, it is in an Area in my project. On my Layout page I call the login form like this:
#Html.Action("LogOn", "Account", new { area = "Store" })
The logon page contains the following:
#model Project.ViewModels.LogOn_ViewModel
#{
Layout = null;
}
#using (Ajax.BeginForm("LogOn", "Account", new { #area = "Store" }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "LoginContainer", LoadingElementId = "actionLoaderImage" }, new { id="LogonForm" }))
{
#Html.AntiForgeryToken()
<div class="loginArea">
<div class="notRegistered">
<h4>Not registered yet?</h4>
Register now<br/>
#Html.ActionLink("Register", "Index", "SignUp", new { area = "Store" }, new { #class = "greenButton" })
</div> <!-- /notRegistered -->
<div class="loginForm">
<div class="formFields">
<label class="inline">#Html.LabelFor(m => m.UserName)</label>
#Html.TextBoxFor(m => m.UserName)
<label class="inline">#Html.LabelFor(m => m.Password)</label>
#Html.PasswordFor(m => m.Password)
<input type="submit" name="LogIn" value="Log in" class="blueButton" />
<img id="actionLoaderImage" src="#Url.Content("~/Content/web/images/loader.gif")" alt="icon" style="margin-right:15px; display:none;" />
#Html.ValidationSummary()
</div>
</div> <!-- /loginForm -->
</div> <!-- /loginArea -->
}
The login controller is standard stuff:
// GET: /Account/Logon
public ActionResult LogOn()
{
// if logged in show logged in view
if (User.Identity.IsAuthenticated)
return View("LoggedIn");
return View();
}
// POST: /Account/Logon
[HttpPost]
public ActionResult LogOn(LogOn_ViewModel model)
{
if (ModelState.IsValid)
{
if (SecurityService.Login(model.UserName, model.Password, model.RememberMe))
{
return View("LoggedIn");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
return PartialView(model);
}
I suspect that what is happening here is that Html.Action is 'posting' the login form if a post is occurring elsewhere on the page. This makes sense as the layout page itself would be posted as part of a form post action.
I tried implementing the custom Validator examples from some other SO questions and blogs (http://blogs.imeta.co.uk/MBest/archive/2010/01/19/833.aspx) but I found that using those examples would not display the validation summary with client side validation which is not much use to me.
The solution I am looking for would need to allow both client and server side validations to appear for the correct form. Does anyone have an example of something like this using MVC? I'd like to avoid manually looking after the client side validation using jquery if possible and just to use the framework to handle the work for me.
Thanks for your suggestions,
Rich
After playing around with this issue for longer than I care to admit, the answer as always was simple once you know how!
The solution to this issue for anyone else who comes up against it is to rename your action so your POST action is a different name to your GET action. This way, when the Layout page is posted back and triggers the PartialView to also be posted back there is only a GET action for your PartialView so the ValidationSummary will not be triggered.
Based on my example above I have altered the form to postback to another action for my login partial view and this has solved this issue for me.
In my Layout page the link to the partial in the store area remains the same:
#Html.Action("LogOn", "Account", new { area = "Store" })
The logon form action is then altered to point to a new action - not called the same name as the GET action:
#using (Ajax.BeginForm("ConfirmLogon", "Account", new { #area = "Store" }, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "LoginContainer", LoadingElementId = "actionLoaderImage" }, new { id="LogonForm" }))
{
....
}
Then I just renamed my controller action so that it has a different action name for the POST action so that when the layout page is called using a post and the partial is loaded up with a POST action that it doesn't call my logon POST action:
// POST: /Account/ConfirmLogon
[HttpPost]
public ActionResult ConfirmLogon(LogOn_ViewModel model)
{
if (ModelState.IsValid)
{
if (SecurityService.Login(model.UserName, model.Password, model.RememberMe))
{
return PartialView("LoggedIn");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
return PartialView("Logon",model);
}
Hopefully this will help some others out with this issue. Seems so obvious now but drove me nutty :D
I have an .Net MVC 3 web application that has the following structure
root
Views
Account
LoginPage.aspx
Controllers
AccountController
Areas
Course
Index.aspx
Imagine I am currently at the Index.aspx page in the Course area, and I would have a button that would forward me to the LoginPage.aspx
In a ASP.Net MVC I would call http://localhost/Account/Login that it would lead me to the correct page. If I just write it down on the browser it works!
But I would like to use the HTML Helper ActionLink, so I tried:
<%: Html.ActionLink("Log on", "Login", "Account", routeValues: null, htmlAttributes: new { id = "logonLink", data_dialog_title = "Logon" })%>
It get the relative path: http://localhost/Course/Account/Login
I tried also:
<%: Html.ActionLink("Log on", "Login", "../Account", routeValues: null, htmlAttributes: new { id = "loginLink", data_dialog_title = "Login" })%>
I got the error message: Cannot use a leading .. to exit above the top directory.
I also tried the relative path:
<%: Html.ActionLink("Log on", "Login", "~/Account", routeValues: null, htmlAttributes: new { id = "loginLink", data_dialog_title = "Login" })%>
And it lead me to:
http://localhost/Course/~/Account/Login
I would really appreciate how to find a solution for this problem.
Try this:
<%: Html.ActionLink("Log on", "Login", "Account", new { area = "" } , new { id = "logonLink", data_dialog_title = "Logon" })%>
The key is the area = "" bit. When using Url.Action or Html.ActionLink with areas, if you don't specify the area route value, MVC will only look for a match in the current area.
It get's even more important when using partial views/templates, since they can be rendered in Views in different areas.
So if using areas, get into the habit of always specifying the area route value, unless using Url.RouteUrl or Html.RouteLink.
I would like to show an AJAX loading icon during an ActionResult request that can take a few seconds to process.
What is the best approach to accomplished this?
I only want to display the icon after the built it validation passes (I am using MVC3, EF Code First, so the validation is automatically put on the page).
There may be further validation/exceptions during the ActionResult, in which case a message is displayed to the user, and I'd then want the loading icon to disappear again.
Define your link as an Ajax action link and specify the ID of a spinning GIF somewhere on your page.
<div id="result"></div>
<img id="spinner" src="../content/ajaxspinner.gif" style="display: none;">
#Ajax.ActionLink("Link Text", "ActionName", "ControllerName", null, new AjaxOptions{UpdateTargetId = "result", LoadingElementId = "spinner"}, null)
or if it is a form:
#using(Ajax.BeginForm("Action", "Controller", null, new AjaxOptions{UpdateTargetId = "result", LoadingElementId = "spinner"}, null))
{
#Html.TextBox("Data")<br/>
<input type="submit" value="Submit" />
}
Put the image in a div tag like this:
<div id="busydiv" style="display:none;"><img src="busything.gif" /></div>
and then create your link like this:
#Ajax.ActionLink("Link Text", "ActionName", "ControllerName", null, new AjaxOptions { LoadingElementDuration = 1000, LoadingElementId = "busyDiv", HttpMethod = "Post", UpdateTargetId = "targetDiv", OnFailure = "PostFailure", OnSuccess = "PostSuccess", OnComplete = "PostOnComplete" }, null)
or in a form do this:
#using (Ajax.BeginForm("TestAjax", new AjaxOptions { LoadingElementDuration=1000, LoadingElementId="dave", HttpMethod = "Post", UpdateTargetId = "targetDiv", OnFailure = "PostFailure", OnSuccess = "PostSuccess", OnComplete = "PostOnComplete" }))
Obviously omitting those AjaxOptions that you don't need, as per the documentation here: http://msdn.microsoft.com/en-us/library/system.web.mvc.ajax.ajaxoptions.aspx
Just my two cents:
The solution posted by Chris is valid and will work BUT you must add a reference to the two javascript libraries below. Please note that the order matters:
<script src="~/scripts/jquery-1.8.0.js"></script>
<script src="~/scripts/jquery.unobtrusive-ajax.js"></script>
When you create an MVC application pre-loaded with bundling and all these nu-get packages this will probably not be a problem for you but if you were like me and created an empty ASP.NET MVC application you might run into issues.