Hi can someone tell me the problem with this please, and how to fix it.
I'm trying to update part of the page using ajax, I'm using the basic code that comes with a new mvc project.
The logon page has this:
<span id="error"/>
#using (Ajax.BeginForm("LogOn", "Account", new AjaxOptions { UpdateTargetId="error"})) {
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
#Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.UserName)
#Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(m => m.Password)
#Html.ValidationMessageFor(m => m.Password)
</div>
<div class="editor-label">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
<p>
<input type="submit" value="Log On" />
</p>
</fieldset>
</div>
}
and the controller like so:
[HttpPost]
public string LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
Redirect(returnUrl);
}
else
{
RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
return "The user name or password provided is incorrect.";
}
Basically what I have done is embeded the login form into a modal popup.
if the entered user credentials fail I want the error to be displayed inside the modal popup, not go off to another page.
The above code is just creating a blank page with the text "The user name or password provided is incorrect."...I need it to be displayed in the modal dialog (jQuery).
Well, the most obvious question is, do you have the scripts added to the page you're trying to do this in? Second, if you're posting to HTTPS (you are, right?), your scripts also have to be HTTPS or you'll get a security error.
This post helped me:
http://weblogs.asp.net/owscott/archive/2010/11/17/mvc-3-ajax-redirecting-instead-of-updating-div.aspx
Related
I'm trying to use some features of MVC. In practice I made this view:
#using (Html.BeginForm("ResetPasswordToken", "Account", FormMethod.Post, new { rt = #Request.QueryString["rt"] })))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "Reset Password non riuscito")
<div class="container above-footer login-form">
<div class="col-md-6" align="center" style=" margin-left:25%; margin-top:100px; margin-bottom:100px;">
<div class="editor-label">
#Html.LabelFor(m => m.ResetToken)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.ResetToken, new { #Value = #Request.QueryString["rt"] })
#Html.ValidationMessageFor(m => m.ResetToken)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.NewPassword)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.NewPassword)
#Html.ValidationMessageFor(m => m.NewPassword)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.ConfirmPassword)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.ConfirmPassword)
#Html.ValidationMessageFor(m => m.ConfirmPassword)
</div>
<p>
<input type="submit" value="Change Password" />
</p>
</div>
</div>
The view is used to reset a password and i want to call the method ResetPasswordToken in AccountController when i click on "Change Password".
The AccountController is so structured, but it doesn't go to the method when i click on button:
[HttpPost]
public ActionResult ResetPasswordToken()
{
return View();
}
[HttpPost]
public ActionResult ResetPasswordToken(RecoverPasswordModel model)
{
if (ModelState.IsValid)
{
if (WebSecurity.ResetPassword(model.ResetToken, model.NewPassword))
{
return RedirectToAction("PasswordResetSuccess");
}
else
{
ModelState.AddModelError("", "The password reset token is invalid.");
}
}
return View(model);
}
Please someone can help me?
Thank you very much and good holidays
Roberto
You have two action with same name and same httppost attibute. Mark first action (without parameter) as httpget
Ok. It missing [AllowAnonymus]. Great and thank you. Now one question. What is the best method to pass the value of the tokens in the URL to the controller without use # Html.TextBoxFor (m => m.ResetToken, new { #Value = #Request.QueryString["rt"] }). I want to hidden this value to user.
Im very new to MVC and messing around. This has been driving me crazy all day, i have been reading around and it seems that i may have some fundamental errors in the structure of my code. But i am struggling to see what they are exactly. As far as i can see i am not even using a child action?
The error is being thrown on the return RedirectToAction line.
I have a registration form that i am displaying in a modal. This modal will be available to see on many pages - so i created an action that returns a partial view.
[AllowAnonymous]
public ActionResult RegisterPartial()
{
return PartialView(new RegisterModel());
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult RegisterPartial(RegisterModel model)
{
if (ModelState.IsValid)
{
//do stuff
return RedirectToAction("Data", "Settings", new { id = model.UserName });
}
// If we got this far, something failed, show form again
return PartialView(model);
}
This is called from my home page at the moment - but will be called from many pages eventually.
<div class="modal fade" id="signUpModal">
#Html.Action("RegisterPartial", "Account")
</div>
SignUp
And here is the partial view itself
#model Prog.Models.RegisterModel
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">Signup</h4>
</div>
#using (Html.BeginForm())
{
<fieldset>
<div class="modal-body">
<p class="message-info">
</p>
#Html.ValidationSummary()
#Html.AntiForgeryToken()
<ol>
<li>
#Html.LabelFor(m => m.UserName)
#Html.TextBoxFor(m => m.UserName, new { #maxlength = "13" })
#Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
#Html.LabelFor(m => m.email)
#Html.TextBoxFor(m => m.email)
#Html.ValidationMessageFor(m => m.email)
</li>
<li>
#Html.LabelFor(m => m.Password)
#Html.PasswordFor(m => m.Password)
</li>
<li>
#Html.LabelFor(m => m.ConfirmPassword)
#Html.PasswordFor(m => m.ConfirmPassword)
</li>
#Html.ValidationMessageFor(m => m.ConfirmPassword)
</ol>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</fieldset>
}
</div></div>
Any help would be most appreciated! Thanks in advance :)
Turns out it was because i didnt fill out the html begin form statement correctly.
#using (Html.BeginForm("RegisterPartial", "Account", FormMethod.Post , new { #class = "form-horizontal" }))
this works now.
The problem is your POST action is returning PartialView if modelstate is invalid. So the partial view will show as entire page instead of model. So you can go with ajax forms. There is Ajax Helper available for MVC.
Include below script in your page.
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
Your view will be
#using (Ajax.BeginForm("RegisterPartial", "Account", new AjaxOptions() {
OnSuccess = "successCallback"})
{
}
<script>
function successCallback(response)
{
var username='#Model.UserName';
if(response)
{
windows.href.location='/Settings/Data/'+username;
}
}
</script>
Your action will be
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public JsonResultRegisterPartial(RegisterModel model)
{
if (ModelState.IsValid)
{
//do stuff
return Json(new {Success=true });
}
return Json(new {Success=false});
}
It might be helpful.
I've got a controller in MVC5 for an apply form. There is a GET to return the view and a POST to take the form data from the application and process it:-
public ActionResult Apply(string jobReference)
{
Apply form = new Apply();
Session[Settings.JOBREFERENCE] = jobReference;
return View(form);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Apply(Apply form)
{
if (ModelState.IsValid)
{
}
}
When I press the to submit the form, it calls the GET controller instead of the the POST controller, despite it having [HttpPost] on the latter.
If I actively renamed the HTTPPost controller and navigate to it, I see a Server Error, with a message saying it cannot be found. Submitting the form causes the page to crash.
Form Code
#model Salt.Models.Apply
<div class='applyForRoleExt popupBox'>
<img src="/img/closePopup.png" alt="close" />
<div class="innerContainer">
#using (Html.BeginForm("Apply", "Form", FormMethod.Post, new { enctype = "multipart/form-data", #id = "ApplyForm" }))
{
#Html.AntiForgeryToken()
<h6>Apply for this role</h6>
#*<div class="haveAccount">
<span>Have an account? Apply quickly by logging in now</span>
Login to my account
</div>*#
<div class="leftCol">
<label>Name<span>*</span></label>
<div class="inputBox">
#Html.TextBoxFor(m => m.Name)
</div>
<label>Email Address<span>*</span></label>
<div class="inputBox">
#Html.TextBoxFor(m => m.EmailAddress)
</div>
<label>Telephone Number<span>*</span></label>
<div class="inputBox">
#Html.TextBoxFor(m => m.TelephoneNumber)
</div>
<label>Portfolio Link<span>*</span></label>
<div class="inputBox">
#Html.TextBoxFor(m => m.PortfolioLink)
</div>
</div>
<div class="rightCol">
<label>CV Upload</label>
<div class="inputBox">
#Html.TextBoxFor(m => m.CV, new { #type = "file" })
</div>
<label>Covering Note</label>
<div class="inputArea">
#Html.TextAreaFor(m => m.CoveringNote)
</div>
</div>
<div class="actions">
<p class="terms">By submitting this form you consent to Salt Recruitment processing your personal data in accordance with our privacy policy and agree to future contact material.</p>
<!--<button class="submit">Apply Now</button>-->
<input type="submit" name="submit" value="Apply Now" />
</div>
}
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$.validator.unobtrusive.parse("#ApplyForm");
});
</script>
Thanks,
Mike.
It's been fixed. It took a second pair of eyes but a rule in the web.config was removing the trailing slash from the form post URL and it was defaulting to loading the GET. No idea why that would cause the problem but it did.
I have just been testing the login function on my website. Recently the login has been working fine, but now I keep on recieving the error
Login failed for user 'Dolapo'.
This session has been assigned a tracing ID of 'e25c9fb4-3ec4-4ce1-9f7f-c01988c856a7'. Provide this tracing ID to customer support when you need assistance.`
On the line
var user = await UserManager.FindAsync(model.UserName, model.Password);`
However I'm trying to login with the user Ben instead of Dolapo.
Any help would be grateful.
Login Method
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.UserName, model.Password);
if (user != null)
{
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Login Page
#model BiteWebsite.Models.LoginViewModel
#{
ViewBag.Title = "Log in";
}
<!-- This is the login page it allows the use to logon on the website using their username and email to check their existence -->
<h2>#ViewBag.Title.</h2>
<div class="row">
<div class="col-md-8">
<section id="loginForm">
#using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(m => m.UserName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.UserName, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.UserName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Password, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Password)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<!--This checkbox is used to allow the system to remember the user when they login-->
<div class="checkbox">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Log in" class="btn btn-default" />
</div>
</div>
<p>
<!-- A link is provided to the registration page if the user doesn't have an account -->
#Html.ActionLink("Register", "Register") if you don't have a account.
</p>
}
</section>
</div>
</div>
I checked the connection string to the database and the password was incorrect
Do verify the username and password in the connection string to make sure it matches the credentials of the database.
I have a controller with 2 actions: 1 for displaying a form and 2nd for processing the submitted form. Smth like this:
public ActionResult Create()
{
TestModel model = new TestModel() { Value1 = "aaa" };
return View(model);
}
[HttpPost]
public ActionResult Create(TestModel model)
{
model.Value2 = "bbb";
return View(model);
}
As you can see I pre-populate Value1 with "aaa" so it appears on the form - this part works fine. However, when I submit the form I would like to fill other properties of the model object and re-display the form using the same view.
The problem is that on submit the form still displays the original model object and not the updated one i.e. only Value1 is populated with "aaa" and Value2 is empty.
The view I use is the Auto-generated one by scaffolding option:
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>TestModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Value1)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Value1)
#Html.ValidationMessageFor(model => model.Value1)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Value2)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Value2)
#Html.ValidationMessageFor(model => model.Value2)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
You have to call ModelState.Clear() so the result will be the expected. MVC does assumptions when POSTed data is sent back to the client. But beware, clearing it manually might cause undesired results ...
You can read more about here: Asp.net MVC ModelState.Clear and http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx