Submit button doesn't submit out of a sudden in ASP.NET MVC when creating a new user when it worked previously. It did not show any invalid input or valid input. I'm not sure where the problem went wrong. Any suggestion would be helpful.This problem has been happening twice and the solution that I have done so far is recreating a new project which I think is not practical.
Here is my code to review.
Admincontroller.cs
[HttpPost]
public IActionResult CreateUser(Users usr)
{
// TODO: L09 Task 5 - Write secure code to insert TravelUser into database
if (!ModelState.IsValid)
{
ViewData["Message"] = "Invalid Input";
ViewData["MsgType"] = "warning";
return View("CreateUser");
}
else
{
string insert = #"INSERT INTO WBUsers(UserId, UserPw,FullName, Email, UserRole,Dob,ContactNo,usr.Billing_Address)
VALUES('{0}', HASHBYTES('SHA1','{1}'),'{2}','{3}','{4}','{5}',{6},'{7}')";
// TODO: L10 Task 2a - Provide the SQL statement to reset member"
if (DBUtl.ExecSQL(insert, usr.UserId, usr.UserPw, usr.FullName, usr.Email, usr.UserRole, usr.Dob, usr.ContactNo, usr.Billing_Address) == 1)
{
string template = #"Hi {0},<br/><br/>
Welcome to Ecommerce!
Your userid is <b>{1}</b> and password is <b>{2}</b>. Please change your password upon login.
<br/><br/>Adminstrator";
string title = "Account Sign Up";
string message = String.Format(template, usr.FullName, usr.UserId, usr.UserPw);
string result = "";
bool outcome = false;
// TODO: L10 Task 2b - Call EmailUtl.SendEmail to send email
// Uncomment the following line with you are done
outcome = EmailUtl.SendEmail(usr.Email, title, message, out result);
if (outcome)
{
ViewData["Message"] = "Account Has Been Created";
ViewData["MsgType"] = "success";
}
else
{
ViewData["Message"] = result;
ViewData["MsgType"] = "warning";
}
}
else
{
ViewData["Message"] = DBUtl.DB_Message;
ViewData["MsgType"] = "danger";
}
return View("CreateUser");
}
}
CreateUser.cshtml
#model SignUp2.Models.Users;
<link href="~/lib/dtpicker/css/tempusdominus-bootstrap-4.min.css" rel="stylesheet" />
<script src="~/lib/dtpicker/js/tempusdominus-bootstrap-4.min.js"></script>
<link href="~/lib/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
<script language="javascript">
$(document).ready(function () {
// DateA
$('#JSDateA')
.datetimepicker({ format: 'YYYY-MM-DD' });
});
</script>
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="~/lib/styles/createform.css">
</head>
<body>
<div class="center">
<form asp-controller="Admin" asp-action="CreateUser" method="post">
<h3>Registration Form</h3>
<div class="form-group row">
<label class="control-label col-sm-3" asp-for="UserId">Username:<span style="color:red;">*</span></label>
<div class="col-sm-5">
<input asp-for="UserId" placeholder="User ID" class="form-control" />
</div>
<div class="col-sm-3">
<span asp-validation-for="UserId" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label class="control-label col-sm-3" asp-for="FullName">Full Name:<span style="color:red;">*</span> </label>
<div class="col-sm-5">
<input asp-for="FullName" placeholder="Full Name" class="form-control" />
</div>
<div class="col-sm-3">
<span asp-validation-for="FullName" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label class="control-label col-sm-3" asp-for="Email">Email:<span style="color:red;">*</span> </label>
<div class="col-sm-5">
<input asp-for="Email" placeholder="Email" class="form-control" />
</div>
<div class="col-sm-3">
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label class="control-label col-sm-3" asp-for="UserPw">Password:<span style="color:red;">*</span> </label>
<div class="col-sm-5">
<input asp-for="UserPw" placeholder="Password" class="form-control" />
</div>
<div class="col-sm-3">
<span asp-validation-for="UserPw" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label class="control-label col-sm-3" asp-for="Dob">Birth Date:<span style="color:red;">*</span></label>
<div class="col-sm-5">
<input asp-for="Dob" asp-format="{0:yyyy-MM-dd}"
class="form-control" placeholder="YYYY-MM-DD" />
</div>
<span asp-validation-for="Dob" class="text-danger"></span>
</div>
<div class="form-group row">
<label class="control-label col-sm-3" asp-for="ContactNo">Contact Number:<span style="color:red;">*</span></label>
<div class="col-sm-5">
<input asp-for="ContactNo" class="form-control" placeholder="Contact Number" />
</div>
<div class="col-sm-3">
<span asp-validation-for="ContactNo" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label class="control-label col-sm-3" asp-for="Billing_Address">Billing Address:<span style="color:red;">*</span> </label>
<div class="col-sm-5">
<input asp-for="Billing_Address" class="form-control" placeholder="Billing Address" />
</div>
<div class="col-sm-3">
<span asp-validation-for="Billing_Address" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label class="control-label col-sm-3">User Role:<span style="color:red;">*</span> </label>
<div class="col-sm-6">
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" id="rb1"
asp-for="UserRole" value="user" checked />
<label class="form-check-label" for="rb1">User</label>
</div>
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" id="rb2"
asp-for="UserRole" value="admin" />
<label class="form-check-label" for="rb2">Admin</label>
</div>
</div>
</div>
<div class="form-group row">
<div class="offset-sm-3 col-sm-6">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</div>
#if (ViewData["Message"] != null)
{
<div class="form-group row">
<div class="offset-sm-2 col-sm-6">
<div class="alert alert-#ViewData["MsgType"]">
#Html.Raw(ViewData["Message"])
</div>
</div>
</div>
}
</form>
</div>
</body>
Related
This is the html code for the main page with the popup
<div class="box">
<a class="button" href="#divOne">
<img src="~/images/usericon.png" alt="user" width="30" height="30" />
</a>
</div>
<div class="overlay" id="divOne">
<div class="wrapper">
<div id="container">
<div class="btn" id="btn-1" data-showbutton="1">Login</div>
<div data-button="1">
×
<div class="content">
<div class="container text-active">
#* load page content here*#
<form id="login">
<label>Username</label>
<input type="text" placeholder="Username" />
<label>Password</label>
<input type="text" placeholder="Password" />
</form>
</div>
</div>
<button>Login</button>
</div>
<div class="btn" id="btn-2" data-showbutton="2">Register</div>
<div id="is-hidden" data-button="2">
×
<div class="content">
<div class="container">
<div class="container text-active">
#* load page content here*#
<form id="register">
<label>Username</label>
<input type="text" placeholder="Username" />
<label>Password</label>
<input type="text" placeholder="Password" />
<label>Confirm Password</label>
<input type="text" placeholder="Confirm Password" />
</form>
</div>
</div>
</div>
<button>Register</button>
</div>
</div>
</div>
</div>
This is the page content I want to display inside the popup
#model Store.Models.CustomerModel
#{
ViewData["Title"] = "Register";
}
#* this part is what I need*#
<div class="row">
<div class="col-md-4">
<form asp-action="Register">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CustomerEmail" class="control-label"></label>
<input asp-for="CustomerEmail" class="form-control" />
<span asp-validation-for="CustomerEmail" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CustomerPassword" class="control-label"></label>
<input asp-for="CustomerPassword" class="form-control" />
<span asp-validation-for="CustomerPassword" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
#* this part is what I need*#
I've tried in including the model and pasting the code and it works, but I want to have that separation between the main page and the login and register form.
This is how it looks, if it is even needed
Move the duplicated code to a partial, with its #model set to CustomerModel:
#model CustomerModel
<div class="row">
<div class="col-md-4">
<form asp-action="Register">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CustomerEmail" class="control-label"></label>
<input asp-for="CustomerEmail" class="form-control" />
<span asp-validation-for="CustomerEmail" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CustomerPassword" class="control-label"></label>
<input asp-for="CustomerPassword" class="form-control" />
<span asp-validation-for="CustomerPassword" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
In the main page, you need to add a CustomerModel property e.g.
public CustomerModel Customer { get; set; }
and then pass it to the partial, which you can do using a partial tag helper:
<div class="overlay" id="divOne">
<div class="wrapper">
<div id="container">
<div class="btn" id="btn-1" data-showbutton="1">Login</div>
<div data-button="1">
×
<div class="content">
<div class="container text-active">
#* load page content here*#
<partial name="_RegisterForm" for="Customer" />
#* load page content here*#
</div>
</div>
</div>
<button>Register</button>
</div>
</div>
</div>
In the Customer page, you include the partial again, but you don't need to specify a model via the for attribute in the partial because the host page's model will be passed by default:
#page
#model WebApplication4.Pages.CustomerModel
#{
ViewData["Title"] = "Register";
}
#* this part is what I need*#
<partial name="_RegisterForm" />
#* this part is what I need*#
I have this file upload form
#model FileUploadViewModel
#{
ViewData["Title"] = "Index";
}
<h4>Start Uploading Files Here</h4>
<hr />
#if (ViewBag.Message != null)
{
<div class="alert alert-success alert-dismissible" style="margin-top:20px">
#ViewBag.Message
</div>
}
<form enctype="multipart/form-data" asp-controller="files" asp-action="UploadToFileSystem" method="post">
<div class="form-group row">
<label asp-for="Name" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input asp-for="Name" class="form-control" placeholder="name" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="Author" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input asp-for="Author" class="form-control" placeholder="Author" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="Genre" class="col-sm-2 col-form-label"> </label>
<div class="col-sm-10">
<select asp-for="Genre" class="custom-select mr-sm-2" asp-items="Html.GetEnumSelectList<Genres>()" ></select>
</div>
</div>
<div class="form-group row">
<label asp-for="Description" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input asp-for="Description" class="form-control" placeholder="Description" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
</div>
<div class="form-group row " >
<label asp-for="PublishedOn" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input type="date" asp-for="PublishedOn" class="form-control" placeholder="Publishing Date" />
<span asp-validation-for="PublishedOn" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="Files" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<div class="custom-file">
<input asp-for="Files" multiple type="file" class="form-control custom-file-input" placeholder="file" />
<label class="custom-file-label">Chose File...</label>
<span asp-validation-for="Files" class="text-danger"></span>
</div>
</div>
</div>
<button class="btn btn-success" type="submit" asp-action="UploadToFileSystem" asp-controller="Files">Upload</button>
</form>
#section Scripts{
<script>
$(document).ready(function () {
$('.custom-file-input').on("change", function () {
var fileLabel = $(this).next('.custom-file-label');
var files = $(this)[0].files;
if (files.length > 1) {
fileLabel.html(files.length + 'files selected');
}
else if (files.length == 1) {
fileLabel.html(files[0].name);
}
});
});
</script>
}
I want to make dropdown list with this table from postgresql database
FileTypes table in pgadmin
And i have this table for genres in database
Genres table in pgadmin
So if i pick FileType with ID=1 in first dropdown,in the second dropdown i want to show only genres with with FileTypeID=1,I try to fill the genres table manualy but i have error(will be posted below).Any help for this way,or other way to filter genres dropdown depends on file type selected in first dropdown.Error trying to fill rows in Genre table
Based on that error, you didn't create a foreign key but a unique index on that column in the Genre table. They prefix IX for index and FK for foreign keys by default I believe. Check your table relationships and check IX_genres_FileTypesID and I am pretty sure you will see the relationship isn't there.
I'm using ASP.NET Core MVC and don't know how validate my form properly.
I want to disable my other form inputs if one gets filled. If the user decides to delete his input all elements should be enabled again.
Here's my code:
<form enctype="multipart/form-data" asp-controller="certificate" asp-action="index" method="post" class="mt-3">
<div class="form-group row">
<label asp-for="Hostname" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input asp-for="Hostname" class="form-control" placeholder="Hostname">
<span asp-validation-for="Hostname" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="Content" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<textarea asp-for="Content" class="form-control" placeholder="Copy your File-Content here" id="content"></textarea>
<span asp-validation-for="Content" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="FileDirectory" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<div class="custom-file">
<input asp-for="FileDirectory" accept=".pem, .der" class="form-control custom-file-input">
<label class="custom-file-label">Choose File...</label>
</div>
</div>
</div>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group row">
<div class="col-sm-12">
<input type="submit" class=" float-right" value="Next"/>
</div>
</div>
</form>
Please let me know if you have any solution.
Do you mean you want to disable other inputs when the input you filled is not valid?If so,here is a demo:
Model:
public class ValidationModel1
{
[Required]
public string Hostname { get; set; }
[Required]
public string Content { get; set; }
public IFormFile FileDirectory { get; set; }
}
View:
<form enctype="multipart/form-data" method="post" class="mt-3" id="myform">
<div class="form-group row">
<label asp-for="Hostname" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input asp-for="Hostname" class="form-control" placeholder="Hostname" onblur="check(this)">
<span asp-validation-for="Hostname" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="Content" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<textarea asp-for="Content" class="form-control" placeholder="Copy your File-Content here" id="content" onblur="check(this)"></textarea>
<span asp-validation-for="Content" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="FileDirectory" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<div class="custom-file">
<input asp-for="FileDirectory" accept=".pem, .der" class="form-control custom-file-input">
<label class="custom-file-label">Choose File...</label>
</div>
</div>
</div>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group row">
<div class="col-sm-12">
<input type="submit" class=" float-right" value="Next" />
</div>
</div>
</form>
js($("#myform").valid() will validate the form.):
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script>
function check(t) {
var id = $(t).attr("Id");
$("#myform").valid()
if (document.getElementById(id).classList.contains("input-validation-error")) {
$(".form-control").each(function () {
if ($(this).attr("Id") != id) {
$(this).attr("disabled", "disabled");
}
})
} else {
$(".form-control").each(function () {
$(this).removeAttr("disabled");
})
}
}
</script>
result:
Update:
js:
function check(t) {
var id = $(t).attr("Id");
//$("#myform").valid()
if ($(t).val() != "") {
$(".form-control").each(function () {
if ($(this).attr("Id") != id) {
$(this).attr("disabled", "disabled");
}
})
} else {
$(".form-control").each(function () {
$(this).removeAttr("disabled");
})
}
}
result:
I have a single page with ASP.NET Core and wanna save the model, Product, with an AJAX form.
My problem arises when I click the submit button to post the data with AJAX, I get a null model in the controller.
my problem in the controller
This model Product :
public class Product
{
[Key]
public int ProductId { get; set; }
public string ProductName { get; set; }
public string Model { get; set; }
public uint price { get; set; }
public string Descriprion { get; set; }
}
This is the AJAX code:
<script type="text/javascript">
$(document).on('click', '#submitdate', function (evt) {
evt.preventDefault();
var data = new FormData();
$('input').each(function (index,filds) {
data.append($(filds).attr('name'), $(filds).val());
});
$.ajax({
type: "POST",
url: '#Url.Action("Index","Home")',
data: data
});
});
</script>
This is the Controller :
[HttpPost]
public IActionResult Index(Product model)
{
_context.products.Add(model);
_context.SaveChanges();
return Json(new { status = "success", message = "successfully save new product" });
}
This is Form in View :
<form method="post" enctype="multipart/form-data">
<div class="modal-body form-horizontal">
<div class="row">
<div class="form-group">
<label asp-for="ProductName" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="ProductName" name="ProductName" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Model" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="Model" name="Model" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="price" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="price" name="price" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Descriprion" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="Descriprion" name="Descriprion" class="form-control" />
</div>
</div>
</div>
</div>
<input type="button" id="submitdate" class="btn btn-submit" value="save" />
</form>
where am I mistake? and how to solve it?
You can try this code:
<script type="text/javascript">
$(document).ready(function(){
$("#submitdate").click(function(evt){
evt.preventDefault();
$.post('#Url.Action("Index","Home")', $("form").serialize(), function(data, status){
if(status == "success")
{
//add code
}
})
})
})
</script>
<form method="post" enctype="multipart/form-data">
<div class="modal-body form-horizontal">
<div class="row">
<div class="form-group">
<label asp-for="ProductName" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="ProductName" name="ProductName" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Model" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="Model" name="Model" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="price" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="price" name="price" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Descriprion" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="Descriprion" name="Descriprion" class="form-control" />
</div>
</div>
</div>
</div>
<input type="button" id="submitdate" class="btn btn-submit" value="save" />
</form>
I wasn't able to find a way to make it work with the FormData approach that you have tried. However I was able to get it to work sending the data as JSON instead.
To do this method you need to make the following changes.
Change the jQuery to this
<script type="text/javascript">
$(document).on('click', '#submitdate', function (evt) {
evt.preventDefault();
var data = {};
$('input').each(function (index, filds) {
var $filds = $(filds);
if ($filds.attr('name')) {
var val = $filds.val();
if ($filds.hasClass("js-is-int")) {
val = parseInt(val);
}
data[$filds.attr('name')] = val;
}
});
$.ajax({
type: "POST",
url: '#Url.Action("Index","Home")',
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8"
});
});
</script>
and change the form to this
<form method="post">
<div class="modal-body form-horizontal">
<div class="row">
<div class="form-group">
<label asp-for="ProductName" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="ProductName" name="ProductName" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Model" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="Model" name="Model" class="form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="price" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="price" name="price" class="form-control js-is-int"/>
</div>
</div>
<div class="form-group">
<label asp-for="Descriprion" class="col-lg-2 col-sm-2 control-label"></label>
<div class="col-lg-6">
<input asp-for="Descriprion" name="Descriprion" class="form-control" />
</div>
</div>
</div>
</div>
<input type="button" id="submitdate" class="btn btn-submit" value="save" />
</form>
Note that enctype="multipart/form-data" is not needed.
I've added the class js-is-int to the price input. This is because its value on the server is a uint. If this is sent as a string the model binding doesn't work. So I've added the class so that when the data is created parseInt is used to cast it to an integer.
Finally the controller logic becomes this
[HttpPost]
public IActionResult Index([FromBody]Product model)
{
_context.products.Add(model);
_context.SaveChanges();
return Json(new { status = "success", message = "successfully save new product" });
}
Note the use of [FromBody] which is needed when you are model binding a JSON post.
I've spent several hours combing Stackoverflow and other sites trying everyone's solutions with no luck so far. I'm sure I've missed something, but I can't see it. Hopefully you can point me to a fix.
I have an initial form inside a partial view that is rendered into a parent view whose validation works fine. Once the form is submitted via Ajax replace, I return either a login or registration partial view with a new form in the response. This second form will not display the model validation errors when an incomplete form is submitted and the same partial view is returned.
Thanks in advance for any tips you can offer to bring an end to this insanity!
Parent View Section
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div class="panel panel-primary" id="formData">
#await Html.PartialAsync("_UserNamePartial", new UserNameViewModel())
</div>
</div>
</div>
Working Rendered Partial View
<div class="panel-heading">
<h3 class="panel-title">Let's Start With Your E-mail Address</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-12">
<form asp-controller="Account" asp-action="IsAccountValid" data-ajax="true" data-ajax-method="POST"
data-ajax-mode="replace" data-ajax-update="#formData">
#Html.AntiForgeryToken()
<div class="form-group">
<label for="UserName">Your Email Address</label>
<div class="input-group">
<input type="text" id="UserName" name="UserName" class="form-control" placeholder="Your email address" />
<div class="input-group-btn">
<button type="submit" id="btnGetStarted" class="btn btn-primary">Get Started</button>
</div>
</div>
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
</form>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
</div>
</div>
</div>
Initial Validation Controller Action
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public IActionResult IsAccountValid(UserNameViewModel model)
{
if (!ModelState.IsValid)
return PartialView("../Home/_UserNamePartial", model);
AccountRepository accountRepository = new AccountRepository(ConnectionConfig.InshoraDev);
AuthName match = accountRepository.GetAuthName(model.UserName);
if (match != null)
{
ModelState.Clear();
LoginViewModel loginModel = new LoginViewModel()
{
UserName = model.UserName
};
return PartialView("_UserLoginPartial", loginModel);
}
ModelState.Clear();
SignUpViewModel signupModel = new SignUpViewModel()
{
UserName = model.UserName,
};
return PartialView("_UserSignUp", signupModel);
}
Login Partial View (Validation Error Display Not Working)
#model Inshora.Models.Account.LoginViewModel
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="panel-heading">
<h3 class="panel-title">Log Into Your Account</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-12">
<form id="login-form" asp-controller="Account" asp-action="Login" method="post" role="form" style="display: block;"
data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="formData" data-ajax-complete="AcctLib.Login.Events.onComplete">
#Html.AntiForgeryToken()
<div class="form-group">
<input type="text" name="UserName" id="UserName" tabindex="1" class="form-control" placeholder="Email Address" value="#Model.UserName">
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group">
<input type="password" name="Password" id="Password" tabindex="2" class="form-control" placeholder="Password">
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group text-center">
<input type="checkbox" tabindex="3" class="" name="RememberMe" id="RememberMe">
<label for="RememberMe"> Remember Me</label>
</div>
<div class="form-group">
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<input type="submit" name="login-submit" id="login-submit" tabindex="4" class="form-control btn btn-primary" value="Log In">
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-lg-12">
<div class="text-center">
<a id="PasswordReset" asp-controller="Account" asp-action="PasswordReset" data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#formData" tabindex="5" class="inshora-forgot-password">Forgot Password?</a>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
AcctLib.Login.Init();
})
</script>
LoginViewModel
public class LoginViewModel
{
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
[Required]
public bool RememberMe { get; set; }
}
Client Side Initialization Code
AcctLib.Login.RebindForm = function() {
$('form').each(function (i, f) {
$form = $(f);
$form.removeData('validator');
$form.removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse($form);
});
}
AcctLib.Login.Init = function () {
AcctLib.Login.RebindForm();
$('#UserName').focus();
}
Update
I have updated the parent page (index.cshtml) to the following and it still doesn't display the messages.
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div class="panel panel-primary" id="formData">
#await Html.PartialAsync("_UserNamePartial", new UserNameViewModel())
</div>
</div>
</div>
#section Scripts
{
#{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
The problem was that I had not used the asp-for tag helpers. Those helpers are responsible for generating the data-* attributes needed by the unobtrusive validation parser. Once I started using them it started working. Thank you to everyone who tried to help.
Corrected View
<div class="panel-body">
<div class="row">
<div class="col-xs-12">
<form id="login-form" asp-controller="Account" asp-action="Login" method="post" role="form"
data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#formData">
#Html.AntiForgeryToken()
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="UserName"></label>
<input asp-for="UserName" class="form-control" placeholder="Email Address"/>
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" class="form-control" placeholder="Password"/>
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group text-center">
<input asp-for="RememberMe" />
<label asp-for="RememberMe"> Remember Me</label>
</div>
<div class="form-group">
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<input type="submit" name="login-submit" id="login-submit" tabindex="4" class="form-control btn btn-primary" value="Log In">
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-lg-12">
<div class="text-center">
<a id="PasswordReset" asp-controller="Account" asp-action="PasswordReset" data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#formData" tabindex="5" class="inshora-forgot-password">Forgot Password?</a>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
if (!ModelState.IsValid)
return PartialView("..\\Home\\_UserNamePartial", model);
pretty sure this violates pathing
if(!ModelState.IsValid)
return PartialView("../Home/_UserNamePartial", model);
Cut renderPartial link and paste to before #script section, like below:
#{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
#section Scripts
{
}