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.
Related
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 searched a lot and spend 3 days only for searching and trying different technique (on stackoverflow etc) but I find no solution for implementing checkboxlist in asp.net mvc. And at last I am posting my problem to stackoverflow;
So, my model looks like this;
Many to Many relationship of my model(1 category may contain many projects and a project may belongs to many categories)
My controller;
[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd()
{
return View();
}
My view;
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Add New Project</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ProjectHeading)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectHeading)
#Html.ValidationMessageFor(model => model.ProjectHeading)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProjecctUrl)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjecctUrl)
#Html.ValidationMessageFor(model => model.ProjecctUrl)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProjectLongDescription)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectLongDescription)
#Html.ValidationMessageFor(model => model.ProjectLongDescription)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PromoFront)
</div>
#Html.EditorFor(model => model.PromoFront)
#Html.ValidationMessageFor(model => model.PromoFront)
<div class="editor-label">
#Html.LabelFor(model => model.ProjectThubmnail)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectThubmnail)
#Html.ValidationMessageFor(model => model.ProjectThubmnail)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProjectImage)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectImage)
#Html.ValidationMessageFor(model => model.ProjectImage)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CategoryId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CategoryId)
#Html.ValidationMessageFor(model => model.CategoryId)
</div>
<p>
<input type="submit" value="Create" class="submit" />
</p>
So, my question is How do I display checkboxlist for categories in my view?
How do I get selected values from that checkboxlist?
You need to have an object that will have a list of all categories, for example, you could do this:
[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd()
{
// Get all categories and pass it into the View
ViewBag.Categories = db.ListAllCategories();
return View();
}
in the top of your View
#model Database.Project
#{
// retrieve the list of Categories
List<Database.Category> categories = ViewBag.Categories;
}
and then replace this
<div class="editor-label">
#Html.LabelFor(model => model.CategoryId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CategoryId)
#Html.ValidationMessageFor(model => model.CategoryId)
</div>
for this
<div class="editor-label">
<label for="categories">Categories</label>
</div>
<div class="editor-field">
#foreach(var c in categories) {
<label class="checkbox">
<input type="checkbox" name="categories" value="#c.CategoryId"> #c.CategoryName
</label>
}
</div>
back in your Controller
[HttpPost]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd(Database.Project model, int[] categories)
{
if(ModelState.IsValid) {
// fill up categories
db.InsertAndSaveProject(model, categories);
}
...
return redirectToView("ProjectAdd");
}
Answer suggested by #balexandre above works great. However, I used following HTML Extension for CheckBoxList.
1. CheckboxList in ASP.net MVC4
2. Source Code:HTML Extension Helper method (Github)
The Major advantage of using this helper method is clean code and better readability. E.g.
#Html.CheckBoxListFor(model => model.SelectedItems, Model.AllItems)
this is my controller:
public ActionResult Create() {
Number newNumber = new Number();
return View(newNumber);
}
and View :
#model PhoneBook.Models.Number
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="../../Scripts/jQuery.AddNewNumber.js" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Contact.Id)
<fieldset>
<legend>Number</legend>
<div class="TargetElements">
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNumber)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumber)
#Html.ValidationMessageFor(model => model.PhoneNumber)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.NumberKind)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.NumberKind.Title, NumberKinds)
</div>
</div>
<p>
<input class="AddNew" value="Add New" type="button" /></p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
By press AddNew button (use jQuery AddNewNumber.js) new input+DropDown Added to form in client side. But there is a problem in retrieve values, When I have one entry element(include input+DropDown) I can retrieve values like the following in post of my controller:
[HttpPost]
public ActionResult Create(Number NewNumber, FormCollection collection) {
db.Numbers.Add(NewNumber);
db.SaveChanges();
return RedirectToAction("Index")
}
But when there is multi-entry how can I retrieve values and add them to DataBase?
Use by the name of element like this:
string[] PhoneNumbers = collection.GetValues("PhoneNumber");
You want all of your input elements to have the same name. Then in your POST action method, the parameter would be List. Here is an example:
Model Binding to a List of objects
Here is my table schema:
Here is my controller:
public ActionResult Register()
{
return View();
}
[HttpPost]
public ActionResult Register(FormCollection formValues)
{
return View();
}
And here is my Register view:
#model LocalizationWebsite.Models.SiteUser
#{
ViewBag.Title = "Localization | Create Account";
}
<h2>Create Your Account</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.Username)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Username)
#Html.ValidationMessageFor(model => model.Username)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.EditorFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AvatarPath)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AvatarPath)
#Html.ValidationMessageFor(model => model.AvatarPath)
</div>
<p>
<input type="submit" value="Create" />
</p>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
How do you suggest I check if the same password was written in both fields? If possible, I'd like to do this automatically as the user is typing in.
Thank you for the help.
You could decorate your view model properties with the [Compare] validation attribute to ensure that two propery values are matching.
If you want to do it from scratch, I would suggest using a little JQuery or javascript. This will give you control over how to do it "automatically."
But, if you can use the [Compare] attribute on the ViewModel, then this post from Scott Gu will allow you to use client-side validation via the DataAnnotations.
Use the CompareAttribute. Good article: http://davidhayden.com/blog/dave/archive/2011/01/01/CompareAttributeASPNETMVC3.aspx
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