MVC View not displaying validation errors - c#

i've got some validations in my mvc project. However, when i sumbit an empty form or form where some required fields have not been entered, it does not stay within the same form/view and show the errors. I cant see any modal errors (i.e amount is required field)
for example, here are some attributes in my modal
[Required]
[StringLength(1, MinimumLength = 1)]
public string Period { get; set; }
[Required]
[DataType(DataType.DateTime)]
public System.DateTime ModifyDate { get; set; }
Here is my controller
[HttpPost]
public ActionResult StopScheduled([Bind(Prefix = "item")] BillPayModel model)
{
//getUsers();
try
{
if (ModelState.IsValid)
{
//save stuff into db
db.SaveChanges();
}
else
{
ModelState.AddModelError("", "Could not Stop Scheduled Payment");
}
}
catch (FormatException)
{
ModelState.AddModelError("", "Could not Stop Scheduled Payment");
}
return RedirectToAction("StopScheduled");
}
}
here is my view
#if (Model !=null)
{
if (Model.IsSuccess == true)
{
<span><center><font color = "green">Successfully Completed Transaction! </font></center></span>
}
else
{
#Html.ValidationSummary(true, "ERROR! Please make sure you have entered correct details");
}
}
#if (Model ==null)
{
using (Html.BeginForm("BillPay", "BillPay", FormMethod.Post, new {}))
{
#Html.ValidationSummary(true);
<div>#Html.LabelFor(model => model.AccountNumber)</div>
#Html.DropDownList("Accounts", "-- Select User --")
<div>#Html.LabelFor(model => model.PayeeID)</div>
#Html.DropDownList("PayeeID", "-- Select User --")
<div>#Html.LabelFor(model => model.Amount)</div>
<div>#Html.TextBoxFor(model => model.Amount,new {style = "width:150px"})
#Html.ValidationMessageFor(model => model.Amount)
</div>
<div>#Html.LabelFor(model => model.ScheduleDate) (i.e 20/10/2013 10:00)</div>
<div>#Html.TextBoxFor(model => model.ScheduleDate,new {style = "width:250px"})
#Html.ValidationMessageFor(model => model.ScheduleDate)
</div>
<div>#Html.LabelFor(model => model.Period)</div>
<div>#Html.TextBoxFor(model => model.Period,new {style = "width:150px"})
#Html.ValidationMessageFor(model => model.Period)
</div>
<input type="submit" value ="Submit" style="width:8%;height:5%"/>
<input type="reset" value ="reset" style="width:8%;height:5%"/>
}
}
else
{
}

The problem is that you are making a new request with RedirectToAction so the validation of your model set to valid. To solve your problem you need to do like this:
[HttpPost]
public ActionResult StopScheduled([Bind(Prefix = "item")] BillPayModel model)
{
try
{
if (ModelState.IsValid)
{
//save stuff into db
db.SaveChanges();
}
else
{
ModelState.AddModelError("", "Could not Stop Scheduled Payment");
}
}
catch (FormatException)
{
ModelState.AddModelError("", "Could not Stop Scheduled Payment");
}
return View(model);
}
And in the view you should change the Html.ValidationSummary excludePropertyErrors to false, like this:
if (Model.IsSuccess == true)
{
<span><center><font color = "green">Successfully Completed Transaction! </font></center></span>
}
else
{
#Html.ValidationSummary(false, "ERROR! Please make sure you have entered correct details");
}
To show them oneach input you need yoo change your if statement (Model==null).

Related

MVC: DropdownListFor error "cannot convert lambda expression to type 'string' because it is not a delegate type"

I have the following problem.
I have a table which is called Users and I have another table called Department.
Now I want, that in the UI, when a user is going to create himself as user with the user form, that he get's on the department field a dropdown list all Department titles which are available from Department table. Reason for that: Department table will be used for other operations and should not be linked with the Userdata. So the Userdata should only contain the department name from the table, and that is enough.
My Controller looks like this:
public ActionResult UserCreate()
{
ViewBag.AppDataDepartment = new SelectList(database.department, "department_title", "department_title");
return View();
}
[HttpPost]
public ActionResult UserCreate(Users user)
{
if (user.UserID == "" || user.UserID == null)
{
ModelState.AddModelError(string.Empty, "UserID cannot be blank");
}
try
{
if (ModelState.IsValid)
{
List<string> results = database.Database.SqlQuery<String>(string.Format("SELECT UserID FROM USERS WHERE UserID = '{0}'", user.UID)).ToList();
bool _userExistsInTable = (results.Count > 0);
Users _user = null;
if (_userExistsInTable)
{
_user = database.Users.Where(p => p.UserID == user.UserID).FirstOrDefault();
if (_user != null)
{
if(_user.active == true)
{
ModelState.AddModelError(string.Empty, "USER already exists!");
}
else
{
database.Entry(_user).Entity.active = true;
database.Entry(_user).Entity.Last_Modified = System.DateTime.Now;
database.Entry(_user).State = EntityState.Modified;
database.SaveChanges();
return RedirectToAction("Index");
}
}
}
else
{
_user = new Users();
_user.UserID = user.UserID;
_user.lastname = user.lastname;
_user.firstname = user.firstname;
_user.mail = user.mail;
_user.department = user.department;
_user.user_image = user.user_image;
_user.image_path = user.image_path;
if (ModelState.IsValid)
{
_user.active = true;
_user.Last_Modified = System.DateTime.Now;
database.Users.Add(_user);
database.SaveChanges();
ViewBag.AppDataDepartment = new SelectList(database.department, "department_title", "department_title");
return RedirectToAction("Index");
}
}
}
}
catch (Exception ex)
{
//return base.ShowError(ex);
}
return View(user);
}
That is my HTML section:
<div class="row">
#Html.LabelFor(model => model.UserID, "UserID", new { #class = "col-sm-2 control-label" })
<div class="col-md-4">
#Html.TextBoxFor(model => model.UserID, new { #class = "col-md-4 control-label form-control", #id = "inputEmail3" })
</div>
#Html.LabelFor(model => model.department, "Department", new { #class = "col-sm-2 control-label" })
<div class="col-md-4">
#Html.DropDownList(model => model.department, (SelectList) ViewBag.AppDataDepartment, htmlAttributes: new { #class = "form-control" })
</div>
</div>
And Finally my department class from the table:
[Table("department")]
public partial class department
{
[Key]
public int departmentid { get; set; }
[Required]
public string department_title { get; set; }
public string subdepartment { get; set; }
}
But I can not compile, because I get the Error:
Error CS1660 Cannot convert lambda expression to type 'string' because
it is not a delegate type BTKPI
Why does this not work? How can I fix that?
I have already looked at this SolutionProposal, but this didn't helped, because the model, Linq and Data.Entity is already referenced.
It needs to be DropDownListFor(), not DropDownList()
#Html.DropDownListFor(m => m.department, (SelectList)ViewBag.AppDataDepartment, new { #class = "form-control" })
If you were to use DropDownList(), then it would be
#Html.DropDownList("department", (SelectList)ViewBag.AppDataDepartment, new { #class = "form-control" })
However there are numerous other issues with your code which you should address.
Your controller should be UserController and the method Create()
so that the url will be ../User/Create, not User/UserCreate
Your editing data, so you should be using a view model (do not use
data models when editing data) - refer What is ViewModel in
MVC?,
and the view model should contain a property
IEnumerable<SelectListItem> DepartmentList - a typical example is
shown in this
question/answer.
Your Users table should be storing the ID of the Department,
not its name, and there should be a FK relationship to the
Departments table.
Your view model property for UserID should have a [Required]
attribute and the view should include #Html.ValidationMesageFor(m
=> m.UserID) so that you get bothe client and server side validation (ditto for the DepartmentID property). You should also
consider a RemoteAttribute applied to the UserID property so
that you get client side validation - refer How to: Implement
Remote Validation in ASP.NET
MVC
And finally, almost nothing is you POST method is making much sense. You calling the database twice in order to check if the user already exists. You checking ModelState.IsValid multiple times. Your user_image and image_path properties suggest you need to upload an image, but nowhere do you save it. You assign ViewBag.AppDataDepartment and then immediately redirect to the Index() method. Your code should look something like (ignoring the file upload issue)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(UserVM model)
{
// Return early
if (!ModelState.IsValid)
{
// You will enter this automatically of UserID is null
model.DepartmentList = ... // assign the SelectList
return View(model);
}
// One database call to check if the user exists
User user = database.Users.Where(p => p.UserID == model.UserID).FirstOrDefault();
if (user != null && !user.active)
{
user.active = true;
// Save and redirect
}
else if (user != null)
{
ModelState.AddModelError(string.Empty, "USER already exists!");
model.DepartmentList = ... // assign the SelectList
return View(model);
}
user = new User
{
UserID = model.UserID,
lastname = model.lastname,
.... // set other properties of User
Last_Modified = System.DateTime.Now
}
// Save and redirect
}
Although its unclear why an existing user who has been archived would need to navigate to a Create() method (and be presented a form to fill out a whole lot of details they have already entered previously). You should have a separate method for activating previously archived users.

How to correct the route that results from running a Controller Action?

Below is a very simple MVC triplet, implemented to try the things out.
It seems to work except the URL I get after changing a Status code to say 500 and hitting Submit button is Error/StatusCode, not Error/StatusCode/500. How can I change it?
I appreciate it is a simple question, but I could not find correct key words to google out the answer.
Model
public class ErrorModel
{
[DisplayName("Status Code")]
public string StatusCode { get; set; }
public ErrorModel(string statusCode)
{
HttpStatusCode code;
if (! Enum.TryParse(statusCode, out code))
{
code = HttpStatusCode.NotFound;
}
StatusCode = ((int)code).ToString();
}
public ErrorModel(HttpStatusCode statusCode = HttpStatusCode.OK)
{
StatusCode = ((int)statusCode).ToString();
}
}
View
#using WebApplication1.Models
#model WebApplication1.Models.ExcelModel
#using (Html.BeginForm("StatusCode", "Error", FormMethod.Post))
{
<p>
<div class="editor-label">
#Html.LabelFor(model => model.StatusCode)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.StatusCode, null, "id")
</div>
<input type="submit" value="Submit" />
</p>
}
Controller
public class ErrorController : Controller
{
static readonly List<HttpStatusCode> ErrorCodes = new List<HttpStatusCode>(){
HttpStatusCode.Unauthorized, HttpStatusCode.Forbidden, HttpStatusCode.NotFound, HttpStatusCode.InternalServerError};
public ActionResult StatusCode(string id)
{
ViewBag.Message = "";
if ((id == null) || (ErrorController.AreEqual(HttpStatusCode.OK, id)))
{
return View("StatusCode", new ErrorModel(HttpStatusCode.OK));
}
foreach (HttpStatusCode errorCode in ErrorCodes)
{
if (ErrorController.AreEqual(errorCode, id))
{
return View("HttpError", new ErrorModel(errorCode));
}
}
ViewBag.Message = "Exception " + id
+ #" is not supported, see https://msdn.microsoft.com/en-us/library/system.net.httpstatuscode(v=vs.110).aspx for further details";
return View("HttpError", new ErrorModel(HttpStatusCode.InternalServerError));
}
static private bool AreEqual(HttpStatusCode httpCode, string statusCode)
{
return (statusCode == ((int)httpCode).ToString());
}
}
You are using POST method to submit the form. That will not include the form element values in the url, but in the request body.
If you want your form field values to be part of the URL, Change the form method to GET. When using GET,if a form is posted, the data sent to the server is appended to the URL as query string values.
#using (Html.BeginForm("StatusCode", "Error", FormMethod.Get))
{
<div class="editor-label">
#Html.LabelFor(model => model.StatusCode)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.StatusCode, null, "id")
</div>
<input type="submit" value="Submit" />
}
Now when user submits the form, browser will issue a GET request to the Error/StatusCode url with the form data appended to the url.
/Home/StatusCode?id=500
Dynamically changing the action's url could be a solution and the code below shows a simplest way to do that.
<script>
$(document).ready(function() {
$('form').submit(function(){
this.action = this.action + '/' + $('#StatusCode').val();
})
});
</script>

Data lost after POST ASP.NET MVC 4

I've been working around on form submission and I ran into something I can't figure out. I know this issue has been posted many times but I can't seem to work things out.
MODEL:
public class IndexModel
{
public string techNo { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
}
CONTROLLER:
public ActionResult Index(IndexModel _oTechModel)
{
//some codes on pulling data from the database
return View("Index", _oTechModel);
}
[HttpPost]
public ActionResult ProcessTechnician(FormCollection form, string SubmitButton)
{
IndexModel _oTechModel = new IndexModel();
switch (SubmitButton)
{
case "save": //add new technician
{
}
break;
case "update": //update technician details
{
try
{
if (isValid(form["techNo"].ToUpper(), "technician") == false) { /*do nothing*/}
else
{
_GTechnician.TECHNICIAN_NO = form["techNo"].ToUpper();
_GTechnician.FIRSTNAME = form["lastName"].ToUpper(); //form is empty here
_GTechnician.LASTNAME = form["firstName"].ToUpper(); //form is empty here
_GTechnicianFacade.updateTechnician(_GTechnician, _GAppSetting.ConnectionString);
}
}
catch (Exception ex) { throw ex; }
}
break;
case "search": //search technician
{
try
{
if (isValid(form["techNo"].ToUpper(), "technician") == false) { /*do nothing*/}
else
{
//some codes here
_oTechModel.techNo = form["techNo"].ToUpper();
_oTechModel.firstName = fNameStr;
_oTechModel.lastName = lNameStr;
_oTechModel.setEnable = true;
}
}
catch (Exception ex) { throw ex; }
}
break;
case "delete":
{
}
break;
}
return RedirectToAction("Index", _oTechModel);
}
VIEW:
#model Maintenance_.Models.IndexModel
#using (Html.BeginForm("ProcessTechnician", "Home", FormMethod.Post))
{
<td>Technician No :</td>
#Html.TextBoxFor(m => m.techNo)
<button type="submit" name="SubmitButton" value="search"></button>
<td>First Name :</td>
#Html.TextBoxFor(m => m.firstName, new { #class = "form-control", style = "width:380px;" })
<td>Last Name :</td>
#Html.TextBoxFor(m => m.lastName, new { #class = "form-control", style = "width:380px;" })
<button name="SubmitButton" value="delete" type="submit">Delete</button>
<button name="SubmitButton" value="update" type="submit">Update</button>
<button name="SubmitButton" value="save" type="submit">Save</button>
}
When I hit the search button it submits the form and displays the firstname and lastname of the technician on the textbox but when I change the values of the textboxes right after I hit the update button it clears the textbox and the data has lost. What am I doing wrong?
Your first line in the post method is
IndexModel _oTechModel = new IndexModel();
You then redirect to the index page with this 'empty' model. (in the case Update statement you are not assigning any values to _otechModel)
you need to change couple of things.
First change parameter
FormCollection form
to
IndexModel _oTechModel
as you have passed IndexModel from the form so it will be automatically binded to the parameter _oTechModel.
Next remove the line.
IndexModel _oTechModel = new IndexModel();
Then change
RedirectToAction("Index", _oTechModel);
it should be. Look at the Documentation
RedirectToAction("Index", new {_oTechModel= _oTechModel});

AddModelError Not Being Passed Back to Controller

I am using the asp.net Razor with C#. I am trying to verify that a value entered is a currency but I can't seem to do it correctly.
This is in my PaymentModel:
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:F2}", ApplyFormatInEditMode = true)]
[Display(Name = "Payment Amount:")]
public decimal Amount { get; set; }
This is my Prepayment view:
#model SuburbanCustPortal.Models.PaymentModel.PrePayment
#{
ViewBag.Title = "Make a payment!";
}
<script>
$(function(){
$("#AccountId").change(function(){
var val=$(this).val();
$("#currentBalance").load("#Url.Action("GetMyValue","Payment")", { custid : val });
document.forms[0].Amount.focus();
});
});
</script>
<h2>Make a Payment</h2>
#using (Html.BeginForm("SendPayment", "Payment", FormMethod.Post))
{
#Html.ValidationSummary(true, "Please correct the errors and try again.")
<div>
<fieldset>
<legend>Please enter the amount of the payment below:</legend>
<div class="editor-label">
Please select an account.
</div>
#Html.DropDownListFor(x => x.AccountId, (IEnumerable<SelectListItem>)ViewBag.Accounts)
<div class="editor-label">
#Html.LabelFor(m => m.AccountBalance)
</div>
<div class="editor-field">
<label class="sizedCustomerDataLeftLabel" id="currentBalance">#Html.DisplayFor(model => model.AccountBalance) </label>
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Amount)
</div>
<div class="editor-field focus">
#Html.TextBoxFor(m => m.Amount, new { #class = "makePaymentText" })
#Html.ValidationMessageFor(m => m.Amount)
</div>
<p>
<input id="btn" class="makePaymentInput" type="submit" value="Pay Now" onclick="DisableSubmitButton()"/>
</p>
</fieldset>
</div>
}
This is my Prepayment ActionResult:
[Authorize]
public ActionResult PrePayment(PaymentModel.PrePayment model)
{
var list = new List<SelectListItem>();
var custs = _client.RequestCustomersForAccount(User.Identity.Name);
foreach (var customerData in custs)
{
var acctno = customerData.Branch + customerData.AccountNumber;
var acctnoname = string.Format(" {0} - {1} ", acctno, customerData.Name);
// msg += string.Format("*** {0} - {1} ***{2}", customerData.AccountId, acctnoname, Environment.NewLine);
list.Add(new SelectListItem() { Text = acctnoname, Value = customerData.AccountId });
}
if (custs.Length > 0)
{
model.AccountBalance = String.Format("{0:C}", Decimal.Parse(custs[0].TotalBalance));
}
ViewBag.Accounts = list;
return View(model);
}
The post of the view calls SendPayment and this was my check at the begining of the view:
if (model.Amount == 0)
{
ModelState.AddModelError("Amount", "Invalid amount.");
return RedirectToAction("PrePayment", model);
}
I can't seem to get the PrePayment to get my error back that I sent from AddModelError. I changed it to:
if (model.Amount == 0)
{
ModelState.AddModelError("Amount", "Invalid amount.");
return View("PrePayment", model);
}
But it never calls the controller and the screen errors out since it doesn't have the data it is expecting.
How do I redirect back to the calling view with the errors?
==== ADDITIONAL INFO ====
Here is my PrePayment View:
[Authorize]
public ActionResult PrePayment(PaymentModel.PrePayment model)
{
var list = new List<SelectListItem>();
var custs = _client.RequestCustomersForAccount(User.Identity.Name);
foreach (var customerData in custs)
{
var acctno = customerData.Branch + customerData.AccountNumber;
var acctnoname = string.Format(" {0} - {1} ", acctno, customerData.Name);
// msg += string.Format("*** {0} - {1} ***{2}", customerData.AccountId, acctnoname, Environment.NewLine);
list.Add(new SelectListItem() { Text = acctnoname, Value = customerData.AccountId });
}
if (custs.Length > 0)
{
var amt =String.Format("{0:C}", Decimal.Parse(custs[0].TotalBalance));
model.AccountBalance = amt;
decimal namt;
if (decimal.TryParse(amt.Replace(",",string.Empty).Replace("$", string.Empty), out namt))
{
model.Amount = namt;
}
}
ViewBag.Accounts = list;
return View(model);
}
There are several issues needs to be addressed.
1. return View("PrePayment", model);
This will not call the controller, as the function name suggests, it only passing your object to the specified "View"(.cshtml file)
2. return RedirectToAction("PrePayment", model);
You will not persist modelstate data, because you are doing a redirect.
Suggested workflow which will solve your issue. At least it solved mine.
1. Get the form to post to "PrePayment" instead of SendPayment and you will create a new method with the following signature and have all you validation logic in the method
[Authorize]
[HttpPost]
public ActionResult PrePayment(PaymentModel.PrePayment model)
2. If everything goes well then redirect to the success/send payment page depending on your requirement
3. If somehow you need to pass model object onto the next action. Use TempData like following. This will temporarily persist the data till the next action. Then it get disposed:
TempData["payment"]=model;
May be you should add a data annotation to your property and use ModelState.IsValid property to validate it
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:F2}", ApplyFormatInEditMode = true)]
[Display(Name = "Payment Amount:")]
[Range(0.01, Double.MaxValue)]
public decimal Amount { get; set; }
In your POST method, check whether the validation is passed, if not send the model back to the view.
[HttpPost]
public ActionResult SendPayment(PrePayment model)
{
if(ModelState.IsValid)
{
//do the fun stuff
}
return View(model);
}

Register button does not respond

Basic problem: We are currently busy developing a C# MVC3 web application, and after writing a CustomMembershipProvider and a custom RegisterModel, our Register form does not seem to be working. this error is pretty frustrating.
Here's what happens: Form is displayed, with register button at the bottom:
<input type="submit" value="Register" />
However, when you click the register-button, nothing happens.
Here's the HttpPost method:
[HttpPost]
public ActionResult Register(RegisterModel model, string returnUrl)
{
if (ModelState.IsValid)
{
// Attempt to register the user
MembershipCreateStatus createStatus = ((CustomMembershipProvider)Membership.Provider).CreateUser(model);
if (createStatus == MembershipCreateStatus.Success)
{
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("","Something went wrong");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Any thoughts? Any help would be greatly appreciated.
edit: for your "viewing" amusement - here's the complete view
#model PMES.Models.RegisterModel
#{
ViewBag.Title = "Register";
}
<h2>Create a New Account</h2>
<p>
Use the form below to create a new account.
</p>
<p>
Passwords are required to be a minimum of
#Membership.MinRequiredPasswordLength characters in length.
</p>
<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, "Account creation was unsuccessful. Please correct the errors and try again.")
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
#Html.LabelFor(m => m.Email)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Email)
#Html.ValidationMessageFor(m => m.Email)
</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.LabelFor(m => m.ConfirmPassword)
</div>
<div class="editor-field">
#Html.PasswordFor(m => m.ConfirmPassword)
#Html.ValidationMessageFor(m => m.ConfirmPassword)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Name)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Name)
#Html.ValidationMessageFor(m => m.Name)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.FirstName)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.FirstName)
#Html.ValidationMessageFor(m => m.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Mobile)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Mobile)
#Html.ValidationMessageFor(m => m.Mobile)
</div>
<p>
<input type="submit" value="Register" />
</p>
</fieldset>
</div>
}
For even more viewing pleasure:
namespace PMES.Controllers
{
public class AccountController : Controller
{
private IUserRepository userRepository;
//
// GET: /Account/LogOn
public AccountController()
{
ProjectManagementContext context = new ProjectManagementContext();
this.userRepository = new UserRepository(context);
}
/*public AccountController(IUserRepository userRepository)
{
this.userRepository = userRepository;
}*/
public ActionResult LogOn()
{
return View();
}
//
// POST: /Account/LogOn
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.Email, model.Password))
{
FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/LogOff
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index", "Home");
}
//
// GET: /Account/Register
public ActionResult Register()
{
return View();
}
//
// POST: /Account/Register
[HttpPost]
public ActionResult Register(RegisterModel model, string returnUrl)
{
if (ModelState.IsValid)
{
// Attempt to register the user
MembershipCreateStatus createStatus = ((CustomMembershipProvider)Membership.Provider).CreateUser(model);
if (createStatus == MembershipCreateStatus.Success)
{
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("","Something went wrong");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/ChangePassword
[Authorize]
public ActionResult ChangePassword()
{
return View();
}
//
// POST: /Account/ChangePassword
[Authorize]
[HttpPost]
public ActionResult ChangePassword(ChangePasswordModel model)
{
if (ModelState.IsValid)
{
// ChangePassword will throw an exception rather
// than return false in certain failure scenarios.
bool changePasswordSucceeded;
try
{
MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
}
catch (Exception)
{
changePasswordSucceeded = false;
}
if (changePasswordSucceeded)
{
return RedirectToAction("ChangePasswordSuccess");
}
else
{
ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/ChangePasswordSuccess
public ActionResult ChangePasswordSuccess()
{
return View();
}
public JsonResult checkEmail(String email)
{
var result = Membership.FindUsersByEmail(email).Count == 0;
return Json(result, JsonRequestBehavior.AllowGet);
}
#region Status Codes
private static string ErrorCodeToString(MembershipCreateStatus createStatus)
{
// See http://go.microsoft.com/fwlink/?LinkID=177550 for
// a full list of status codes.
switch (createStatus)
{
case MembershipCreateStatus.DuplicateUserName:
return "User name already exists. Please enter a different user name.";
case MembershipCreateStatus.DuplicateEmail:
return "A user name for that e-mail address already exists. Please enter a different e-mail address.";
case MembershipCreateStatus.InvalidPassword:
return "The password provided is invalid. Please enter a valid password value.";
case MembershipCreateStatus.InvalidEmail:
return "The e-mail address provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidAnswer:
return "The password retrieval answer provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidQuestion:
return "The password retrieval question provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidUserName:
return "The user name provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.ProviderError:
return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
case MembershipCreateStatus.UserRejected:
return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
default:
return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
}
}
#endregion
}
}
Depending on how you have everything setup you might have to explicity tell the form where to post (in your view):
Change this:
Html.BeginForm()
to:
Html.BeginForm("Register", "YourController")
Have you changed your routes from the default settings? It may not be hitting the controller due to a routing issue?
Also, use the inspect element feature of firebug or chrome dev tools and make sure that the form action="/Account/Register" and that it is not doing something weird when it is building the form.
Sometimes weird things happen and it doesn't build the form correctly.
Also you can use the Network tab in chrome dev tools to see what gets posted to the server when you hit the submit button and you can see the server response.

Categories

Resources