MVC Client side validation are not working in partial view - asp.net-mvc

I have a partial view which gets populated in modal body of my home page of MVC project. Partial view holds the login form as follows -
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-xs-6">
<div class="well">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-12">
#Html.LabelFor(model => model.UserEmailId, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.UserEmailId, new { htmlAttributes = new { #class = "form-control", placeholder = "example#gmail.com" } })
#Html.ValidationMessageFor(model => model.UserEmailId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-12">
#Html.LabelFor(model => model.UserPassword, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.UserPassword, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.UserPassword, "", new { #class = "text-danger" })
</div>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="remember" id="remember"> Remember login
</label>
</div>
</div>
<button type="button" class="btn btn-success btn-block" onclick="location.href='#Url.Action("Login", "Home")'">
Login
</button>
</div>
</div>
<div class="col-xs-6">
<p class="lead">Sign up with</p>
<ul class="list-unstyled" style="line-height: 2">
<li><span class="fa fa-check text-success"></span> See all your orders</li>
<li><span class="fa fa-check text-success"></span> Fast re-order</li>
<li><span class="fa fa-check text-success"></span> Save your favorites</li>
<li><span class="fa fa-check text-success"></span> Fast checkout</li>
<li><span class="fa fa-check text-success"></span> Get a gift <small>(only new customers)</small></li>
<li><u>Read more</u></li>
</ul>
</div>
</div>
}
I am using a partial classes to define my data validations for the models(so that they wont get missed if I update my db first models) -
public class UserMetadata
{
[Display(Name ="Username")]
[EmailAddress(ErrorMessage ="Please enter your email address")]
[Required(ErrorMessage ="Required field")]
public string UserEmailId { get; set; }
[Display(Name ="Password")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "Username is required")]
[StringLength(15, ErrorMessage = "Must be between 8 and 15 characters", MinimumLength = 8)]
public string UserPassword { get; set; }
}
The validations are not working on the client side. They are not getting triggered. Am I missing some script reference?
I already have "ClientValidationEnabled" set to true in my web.config.
Please help. Thanks!
Edit -
The following is all included in my layout -
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
<link href='https://fonts.googleapis.com/css?family=Kaushan+Script' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700' rel='stylesheet' type='text/css'>
<script src="https://use.fontawesome.com/2d83329334.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")

Hi please check below code for reference
1. Model
public class UserMetadata
{
[Display(Name = "Username")]
[EmailAddress(ErrorMessage = "Please enter your email address")]
[Required(ErrorMessage = "Required field")]
public string UserEmailId { get; set; }
[Display(Name = "Password")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "Username is required")]
[StringLength(15, ErrorMessage = "Must be between 8 and 15 characters", MinimumLength = 8)]
public string UserPassword { get; set; }
}
2. Controller
public class UserDataController : Controller
{
// GET: Contacts/UserData
public ActionResult Index()
{
var userData = new UserMetadata();
return View(userData);
}
}
view and Javascript
#model UserMetadata
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
<div class="row">
<div class="col-xs-6">
<div class="well">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text- danger" })
<div class="form-group">
<div class="col-md-12">
#Html.LabelFor(model => model.UserEmailId, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.UserEmailId, new { htmlAttributes = new { #class = "form-control", placeholder = "example#gmail.com" } })
#Html.ValidationMessageFor(model => model.UserEmailId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-12">
#Html.LabelFor(model => model.UserPassword, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.UserPassword, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.UserPassword, "", new { #class = "text-danger" })
</div>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="remember" id="remember"> Remember login
</label>
</div>
<button type="button" class="btn btn-success btn-block" onclick="loginUser();">
Login
</button>
</div>
</div>
</div>
</div>
}
<script>
function loginUser()
{
if($('form').valid())
{
//redirect to some action like window.location=somerootPath+/login/home
}
else
{
//not valid
}
}
OutPut
Ensure the highlighted js are loaded except jquery UI.

One way of solution is:
In the html editor add 'required' field as below
#Html.EditorFor(model => model.UserEmailId, new { htmlAttributes = new { #class = "form-control", placeholder = "example#gmail.com",#required="required" } })
and no need of Html.ValidationMessageFor() for this.

Related

How can i show DisplayName label before and after editor (English + Arabic ) in MVC?

I want to create multi-language system using MVC (English and Arabic) , I want to use one view for both languages , i created the Login view based on the following model :
public partial class WEBSITE_USERS
{
[DisplayName("ID / Iqamam No - رقم الهوية او الاقامة")]
[Required(ErrorMessage ="This field is required يجب ادخال رقم الهوية المسجل في الملف الطبي ")]
public string ID_NO { get; set; }
[DisplayName("Mobile No - رقم الجوال")]
[Required(ErrorMessage = "Mobile No is required - يجب ادخال رقم الجوال المسجل في الملف ")]
public string MOBILE { get; set; }
[DisplayName("Medical Record No - رقم الملف")]
[Required(ErrorMessage = "File No is required يجب ادخال رقم الملف الطبي ")]
}
Now the DisplayName appeared on left side ,
How can i show the English label on left side and Arabic label on right side of editor to show like this for example :
ID/Iqama No ----------------- رقم الهوية او الاقامة
Now its appear all in left side like this :
ID / Iqamam No - رقم الهوية او الاقامة ---------------------------
this is the view code
#model kaashtaif.Models.WEBSITE_USERS
#{
ViewBag.Title = "Login Window - شاشة تسجيل الدخول";
}
<h2>Login</h2>
#using (Html.BeginForm("Authorise","Login",FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ID_NO, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ID_NO, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ID_NO, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MOBILE, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MOBILE, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MOBILE, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PATIENT_NO, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PATIENT_NO, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PATIENT_NO, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-10">
<label>#Html.DisplayFor(model => model.LoginErrorMessage)</label>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Login" class="btn btn-default" />
<input type="reset" name="name" value="Clear" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
and this is screen shot of view
Fastest way of doing it is changing your markup and manually using Html.DisplayNameFor() then split that string up.
Repeat this process for the rest of the input fields/ form-group.
<div class="form-group">
<div class="col-md-3">
#Html.DisplayNameFor(x => x.ID_NO).ToString().Split('-')[0]
</div>
<div class="col-md-6">
#Html.EditorFor(model => model.ID_NO, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ID_NO, "", new { #class = "text-danger" })
</div>
<div class="col-md-3">
#Html.DisplayNameFor(x => x.ID_NO).ToString().Split('-')[1]
</div>
</div>
What's happening here is we're getting the value of DisplayName attribute which is [DisplayName("ID / Iqamam No - رقم الهوية او الاقامة")] and since you have a delimiter which is a hyphen, we're splitting the string into two using that - or hyphen then displaying the string by index.

partial view renders as full view on validation fail

my controller
public ActionResult Create()
{
return PartialView();
}
//
// POST: /User/Create
[HttpPost]
public ActionResult Create(User user)
{
if (ModelState.IsValid)
{
db.User.Add(user);
db.SaveChanges();
TempData["Message"] = "Data has been saved successfully!";
return RedirectToAction("Index");
}
return View(user);
}
my view
<div class="row">
#Html.ActionLink("Create New", "Create", null, new { #class = "modal-with-form btn btn-default", href = "#modalForm" })
<!-- Modal Form -->
<div id="modalForm" class="modal-block modal-block-primary mfp-hide">
#Html.Partial("Create", new jQuery_CRUD.DAL.User())
</div>
</div>
my partial view
#using (Ajax.BeginForm("Create", "User", null, new AjaxOptions { UpdateTargetId = "modalForm", InsertionMode = InsertionMode.Replace }))
{
<section class="panel">
<header class="panel-heading">
<h2 class="panel-title">Create</h2>
</header>
<div class="panel-body">
<div class="form-group mt-lg">
#Html.LabelFor(model => model.Name, new { #class = "col-sm-3 control-label" })
<div class="col-sm-9">
#Html.TextBoxFor(model => model.Name, new { name = "name", #class = "form-control", placeholder = "Type your name..."})
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, new { #class = "col-sm-3 control-label" })
<div class="col-sm-9">
#Html.TextBoxFor(model => model.Address, new { name = "address", #class = "form-control", placeholder = "Type your Address..." })
#Html.ValidationMessageFor(model => model.Address)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ContactNo, new { #class = "col-sm-3 control-label" })
<div class="col-sm-9">
#Html.TextBoxFor(model => model.ContactNo, new { name = "contactno", #class = "form-control", placeholder = "Type your Contact No..." })
#Html.ValidationMessageFor(model => model.ContactNo)
</div>
</div>
</div>
<footer class="panel-footer">
<div class="row">
<div class="col-md-12 text-right">
<input type="submit" value="Create" class="btn btn-primary" />
<button class="btn btn-default modal-dismiss" id="btnCancel">Cancel</button>
</div>
</div>
</footer>
</section>
}
when i click the button , modal pops up,upon validation fail on post action, the view returns to full view. where could be the problem????..
i'm new to mvc help me with this..
Add in the beginning of your partial view
{
Layout = null;
}
And return partialView in Validation Error not View
[HttpPost]
public ActionResult Create(User user)
{
if (ModelState.IsValid)
{
db.User.Add(user);
db.SaveChanges();
TempData["Message"] = "Data has been saved successfully!";
return RedirectToAction("Index");
}
return PartialView(user);
}

Validate required model only

I'm using two models, Login & Signup Model in a View.
public class Login
{
[Required(ErrorMessage ="User ID Required.")]
public string UserID { get; set; }
[Required(ErrorMessage ="Password Required")]
public string Password { get; set; }
}
public class SignUp
{
[Required (ErrorMessage ="User ID Required")]
public string UserID { get; set; }
[Required (ErrorMessage ="Name Required")]
public string Name { get; set; }
[Required (ErrorMessage ="Mail ID Required")]
public string MailID { get; set; }
[Required(ErrorMessage ="Password Required")]
public string Password { get; set; }
[Required(ErrorMessage ="Confirm Password Required")]
[Compare (nameof(Password), ErrorMessage ="Password does not match")]
public string ConfirmPassword { get; set; }
}
when I click Login button, it validates both the models. How to validate the model separately?
Used following codes in controller
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string Command, Login Login)
{
if (Command == "SIGNUP")
{
return RedirectToAction("Contact");
}
else
{
if (ModelState.IsValidField("USERID") && ModelState.IsValidField("PASSWORD"))
{
return RedirectToAction("About");
}
}
return View();
}
Index.cshtml VIEW CODE:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="HolderForm">
<div class="col-md-6">
<div class="form-horizontal">
<h4>Login</h4>
<hr />
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.Login.UserID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "USER ID" } })<br>
#Html.ValidationMessageFor(o => o.Login.UserID,"", new {#class= "LoginValidation" } )
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.Login.Password, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "PASSWORD" } })<br>
#Html.ValidationMessageFor(o => o.Login.Password,"", new { #class = "LoginValidation" })
#ViewBag.Posted
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
#ViewBag.Posted
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit"
value="LOGIN"
id="btn_Login"
name="Command"
class="btn btn-default" />
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-horizontal">
<h4>SignUp</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.UserID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "USER ID" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.UserID,"", new { #class = "LoginValidation" } )
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.Name, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "NAME" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.Name, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.MailID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "MAIL ID" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.MailID, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.Password, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "PASSWORD", #type = "password" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.Password, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.ConfirmPassword, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "CONFIRM PASSWORD", #type = "password" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.ConfirmPassword, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type= "submit" value="SIGNUP"
id="btn_Login"
name="Command"
class="btn btn-default" />
</div>
</div>
</div>
</div>
</div>
}
Above code place on the view using two different model.
Please help and also suggest me where to learn ASP.NET (Beginner level)?
you add Login and SignUp in one Form
#using (Html.BeginForm()){
...
}
try this
<div class="HolderForm">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-md-6">
<div class="form-horizontal">
<h4>Login</h4>
<hr />
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.Login.UserID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "USER ID" } })<br>
#Html.ValidationMessageFor(o => o.Login.UserID,"", new {#class= "LoginValidation" } )
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.Login.Password, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "PASSWORD" } })<br>
#Html.ValidationMessageFor(o => o.Login.Password,"", new { #class = "LoginValidation" })
#ViewBag.Posted
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
#ViewBag.Posted
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit"
value="LOGIN"
id="btn_Login"
name="Command"
class="btn btn-default" />
</div>
</div>
</div>
</div>
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-md-6">
<div class="form-horizontal">
<h4>SignUp</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.UserID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "USER ID" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.UserID,"", new { #class = "LoginValidation" } )
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.Name, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "NAME" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.Name, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.MailID, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "MAIL ID" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.MailID, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.Password, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "PASSWORD", #type = "password" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.Password, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(o => o.SignUp.ConfirmPassword, new { htmlAttributes = new { #class = "LoginEntry", #placeholder = "CONFIRM PASSWORD", #type = "password" } })<br>
#Html.ValidationMessageFor(o => o.SignUp.ConfirmPassword, "", new { #class = "LoginValidation" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type= "submit" value="SIGNUP"
id="btn_Login"
name="Command"
class="btn btn-default" />
</div>
</div>
</div>
</div>
</div>
}

mvc No data in ActionResult method after submit

I have an Index page on which there is a section to write a project name and select from a dropdownlist a project type.
Below that I have a submit button that directs to the ActionResult method Create in the Projects controller.
Code:
[UPDATE]
index.cshtml:
#using reqcoll.ViewModels
#model myViewModel
#{
ViewBag.Title = "ReqColl - project";
}
#* First half *#
#using (Html.BeginForm("CreateProject", "Projects"))
{
#Html.AntiForgeryToken()
<div class="top-spacing col-md-12 col-lg-12 col-sm-12">
#RenderTopHalf(Model.modelProject)
</div>
}
#* Second half *#
#using (Html.BeginForm("CreateRequirement", "Projects"))
{
#Html.AntiForgeryToken()
<div class="form-group" id="pnSecondHalf">
#* Requirements list *#
<div class=" col-md-6 col-lg-6 col-sm-12">
#RenderBottomLeftHalf(Model.modelRequirement)
</div>
#* New/Edit requirements panel *#
<div class="col-md-6 col-lg-6 col-sm-12">
#RenderBottomRightHalf(Model.modelRequirement)
</div>
</div>
}
#* ================================================================================= ============= *#
#* Helpers *#
#helper RenderTopHalf(reqcoll.Models.Project project)
{
<div class=" well">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
#Html.LabelFor(model => project.projectName, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.TextBoxFor(model => project.projectName, htmlAttributes: new { #class = "ProjectNameInput" })
#Html.ValidationMessageFor(model => project.projectName)
</div>
</div>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row row-spacing">
#Html.LabelFor(model => project.projectType, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.DropDownListFor(model => project.projectType, new SelectList(
new List<Object>{
new { value = 0 , text = "...Select..." },
new { value = 1 , text = "Windows application" },
new { value = 2 , text = "Web application" },
new { value = 3 , text = "Device application"}
},
"value",
"text",
project.projectType), htmlAttributes: new { #class = "DropDownList" })
#Html.ValidationMessageFor(model => project.projectType)
</div>
<input type="hidden" value="" id="hdProjectID" />
</div>
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnCreate" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Create" />
</div>
<div id="pnEdit" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Edit" />
|
<input type="submit" class="btn btn-default" value="Delete" />
</div>
</div>
</div>
}
#helper RenderBottomLeftHalf(reqcoll.Models.Requirement requirement)
{
<div class=" well">
<table class="table">
<tr>
<th>
#if (Model.modelProject.Requirements != null)
{
var m = Model.modelProject;
if (m.Requirements.Count > 0)
{
#Html.DisplayNameFor(model => model.modelProject.Requirements[0].shortDesc)
}
}
else
{
<label class="label label-primary col-sm-12 col-md-6 col-lg-6">No requirements available</label>
}
</th>
<th></th>
</tr>
#if (Model.modelProject.Requirements != null)
{
var m = Model.modelProject;
if (m.Requirements.Count > 0)
{
foreach (var item in Model.modelProject.Requirements)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.shortDesc)
</td>
<td>
#* buttons here*#
#*#Html.ActionLink("E", "Edit", new { id = item.requirementID }) |
#Html.ActionLink("D", "Delete", new { id = item.requirementID })*#
</td>
</tr>
}
}
}
</table>
</div>
}
#helper RenderBottomRightHalf(reqcoll.Models.Requirement requirement)
{
<div class=" well">
#Html.ValidationSummary(true)
<div class="row">
#Html.LabelFor(model => requirement.shortDesc, htmlAttributes: new { #class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12">
#Html.TextBoxFor(model => requirement.shortDesc, htmlAttributes: new { #class = "RequirementShortDesc" })
#Html.ValidationMessageFor(model => requirement.shortDesc)
</div>
</div>
#Html.ValidationSummary(true)
<div class="row row-spacing">
#Html.LabelFor(model => requirement.longDesc, htmlAttributes: new { #class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12 RequirementLongDesc">
#Html.EditorFor(model => requirement.longDesc)
#Html.ValidationMessageFor(model => requirement.longDesc)
</div>
</div>
#Html.ValidationSummary(true)
<div class="row row-spacing">
#Html.LabelFor(model => requirement.priorityCode, htmlAttributes: new { #class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12">
#foreach (var value in Enum.GetValues(requirement.priorityCode.GetType()))
{
<div class="control-label col-sm-5 col-md-5 col-lg-5">
#Html.RadioButtonFor(m => requirement.priorityCode, value)
#Html.Label(value.ToString())
</div>
}
#Html.ValidationMessageFor(model => requirement.priorityCode)
</div>
</div>
<input type="hidden" value="" id="hdRequirementID" />
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnReqCreate" class=" col-sm-12 col-md-6 col-lg-6">
#* submit button here *#
#*#Html.ActionLink("Add", "Add", "Requirement", new { #class = "btn btn-default btnSize" })*#
</div>
<div id="pnReqEdit" class=" col-sm-12 col-md-6 col-lg-6">
#* submit buttons here *#
#*#Html.ActionLink("Edit", "Edit", "Requirement", new { #class = "btn btn-default btnSize" })
#Html.ActionLink("Delete", "Delete", "Requirement", new { #class = "btn btn-default btnSize" })*#
</div>
</div>
</div>
}
#section Scripts {
<script>
$(function () {
var pID = $('#hdProjectID').val();
if (pID != null) {
if (pID.length > 0) {
$('#pnEdit').show();
$('#pnCreate').hide();
$('#pnSecondHalf').show();
} else {
$('#pnEdit').hide();
$('#pnCreate').show();
$('#pnSecondHalf').hide();
}
} else {
$('#pnEdit').hide();
$('#pnCreate').show();
$('#pnSecondHalf').hide();
}
var rID = $('#hdRequirementID').val();
if (rID != null) {
if (rID.length > 0) {
$('#pnReqEdit').show();
$('#pnReqCreate').hide();
} else {
$('#pnReqEdit').hide();
$('#pnReqCreate').show();
}
} else {
$('#pnReqEdit').hide();
$('#pnReqCreate').show();
}
});
</script>
#Scripts.Render("~/bundles/jqueryval")
}
ViewModel:
using reqcoll.Models;
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project modelProject;
public Requirement modelRequirement;
}
}
Controller:
using System.Web.Mvc;
using reqcoll.Models;
using reqcoll.ViewModels;
namespace reqcoll.Controllers
{
public class ProjectsController : Controller
{
private myContext db = new myContext();
// GET: Projects
public ActionResult Index()
{
// allow more than one model to be used in the view
var vm = new myViewModel()
{
modelProject = new Project() { projectName = "test", projectType = 1 },
modelRequirement = new Requirement() { requirementID = -1 },
};
return View(vm);
}
[HttpPost]
[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateProject(myViewModel vm)
{
if (vm != null)
{
var ab = Request.Form;
// key 1: __RequestVerificationToken
// key 2: project.projectName
// key 3: project.projectType
if (ModelState.IsValid)
{
Project project = vm.modelProject;
// db.Project.Add(project.Item1);
// db.SaveChanges();
// return RedirectToAction("Index");
}
}
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
[ORIGINAL]
#using (Html.BeginForm("Create", "Projects"))
{
#Html.AntiForgeryToken()
<div class="top-spacing col-md-12 col-lg-12 col-sm-12">
<div class=" well">
#Html.ValidationSummary(true)
<div class="row">
#Html.LabelFor(model => model.Item1.projectName, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.TextBoxFor(model => model.Item1.projectName, htmlAttributes: new { #class = "ProjectNameInput" })
#Html.ValidationMessageFor(model => model.Item1.projectName)
</div>
</div>
#Html.ValidationSummary(true)
<div class="row row-spacing">
#Html.LabelFor(model => model.Item1.projectType, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.DropDownListFor(model => model.Item1.projectType, new SelectList(
new List<Object>{
new { value = 0 , text = "...Select..." },
new { value = 1 , text = "Windows application" },
new { value = 2 , text = "Web application" },
new { value = 3 , text = "Device application"}
},
"value",
"text",
0), htmlAttributes: new { #class = "DropDownList" })
#Html.ValidationMessageFor(model => model.Item1.projectType)
</div>
<input type="hidden" value="" id="hdProjectID" />
</div>
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnCreate" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Create" />
</div>
<div id="pnEdit" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Edit" />
|
<input type="submit" class="btn btn-default" value="Delete" />
</div>
</div>
</div>
</div>
}
ProjectsController:
private myContext db = new myContext();
// GET: Projects
public ActionResult Index()
{
// allow more than one model to be used in the view
return View(new Tuple<Project, Requirement, Priority>(new Project(), new Requirement(), new Priority()));
}
[HttpPost]
[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Include = "projectName,projectType")] Project project)
{
if (ModelState.IsValid)
{
db.Project.Add(project);
db.SaveChanges();
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
So when the submit button is clicked, the ActionResult Create is called, but the ModelState is not valid and does not have the information enterd by the user.
What am I doing wrong?
Your model is looking like complex object as you are using model.Item1.projectName and model.Item1.projectType, but in action method you are trying to get values directly which is wrong.
[Updated code]
With the new code posted, this quick correction to your model will allow it to bind correctly from your view:
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project project;
public Requirement requirement;
}
}
[Original]
Despite the fact of using a Tuple<> type instead of defining a class that would encapsulate the data to pass to the view. You can still achieve what you want by creating a helper in your view.
#helper RenderMyProject(Project project) {
...
#Html.TextBoxFor(x=> project.projectType)
...
}
Then, you will call this helper
#RenderMyProject(model.Item1)
Whats the difference?
The name of the input will change. Instead of posting [Item1.projectType] Inside the response object to your controller, it will look like [project.projectType] which will be mapped to your project parameter automatically.
Found the problem.
I added {get; set;} in the myViewModel to both the models and then it worked.
so:
using reqcoll.Models;
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project Project { get; set; }
public Requirement Requirement { get; set; }
}
}

Partial view validation change current page

I have page that uses a partial view for a contact form, and the contact form is validated (so when I don't provide a required field, it redirect me to specific layout I create for this partial.)
Here is how my page is laid out:
Last image is a blank_layout I created for my partial view because if I don't do it, it changes all content like navbar and other parts of the page.
View Model:
public class ContactoViewModel
{
public IEnumerable<ProductosModel> ProductosListes { set; get; }
public String Descripcion { get; set; }
public String Id { get; set; }
[Required(ErrorMessage = "Es necesario que ingrese su nombre")]
public String Name { get; set; }
[Required(ErrorMessage = "Es necesario que ingrese su correo")]
[Email(ErrorMessage = "Ingrese un Email válido")]
public String Email { get; set; }
[Required(ErrorMessage = "Ingrese algún comentario por favor")]
[MinLength(10, ErrorMessage = "Es necesario que ingrese al menos 10 caracteres")]
public String Comments { get; set; }
}
Partial view:
#model DismedHmo.Models.ContactoViewModel
#{
Layout = "~/Views/Shared/Blank_Layout.cshtml";
}
#*<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/Content/component.css" rel="stylesheet" />
<link href="~/Content/default.css" rel="stylesheet" />*#
<div class="row">
<!-- feedback -->
<article class="feedback">
#*<div class="title-contact">Deja un mensaje </div>*#
#using (Html.BeginForm("Contact_Partial", "ContactModels", FormMethod.Post))
{
<div class="title-margin">
#*<h6>Campos Requeridos*</h6>*#
</div>
<div class="input-group">
<div class="col-md-12">
<div class="relative">
<i class=" fa fa-user appointment-contact"></i>
<div class="contactlbl">
#Html.TextBoxFor(model => model.Name, new { #class = "form-control, txtboxexpand", #style = "width:100%", #placeholder = "Nombre*" })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="input-group">
<div class="col-md-12">
<div class="relative">
<i class=" fa fa-envelope appointment-contact"></i>
<div class="contactlbl">
#Html.TextBoxFor(model => model.Email, new { #class = "form-control, txtboxexpand", #style = "width:100%", #placeholder = "Email*", #type = "email" })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="input-group">
<div class="hidden-xs col-sm-12 col-md-12 col-lg-12">
<div class="relative">
<i class=" fa fa-align-left appointment-message"></i>
</div>
<div class="contactlbl">
#Html.TextAreaFor(model => model.Comments, new { #class = "form-control, txtareaexpand", #style = "width:100%", #placeholder = "Mensaje*" })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="input-group">
<div class="col-xs-12 hidden-sm hidden-md hidden-lg">
<div class="relative">
<i class=" fa fa-align-left appointment-message"></i>
</div>
<div class="contactlbl">
#Html.TextAreaFor(model => model.Comments, new { #class = "form-control, txtareaexpandxs", #style = "width:100%", #placeholder = "Mensaje*" })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group margen-btn">
<div class="col-sm-12">
<input type="submit" value="Solicitar cotización" class="btn btn-contacto" />
</div>
</div>
}
</article>
</div>
Calling partial view on main page:
<div class="col-md-6">
#Html.Action("Contact_Partial", "ContactModels")
</div>
Controller:
[HttpPost]
public ActionResult Contact_Partial(ContactoViewModel model)
{
if (!ModelState.IsValid)
{
Danger("Su mensaje no fue enviado, porfavor intente de nuevo.");
return View();
}
using (var emailService = new EmailService())
{
emailService.SetRecipient("contacto#dismedhmo.com");
emailService.Contacto(model.Name, model.Email, model.Comments);
emailService.Send();
}
Success(string.Format("Tu mensaje ha sido enviado con exito."), true);
return RedirectToAction("Productos", "Productos");
}
public ActionResult MensajeEnviado()
{
return View();
}
I really want the validation page to be displayed where the contact form was. How can I do this?

Resources