<span asp-validation-for="Password" class="text-danger"></span>
<div class="form-group">
<label asp-for="Password">პაროლი</label>
#Html.TextBoxFor(x => x.Password, new { type = "password",#class = "form-control" })
<!--
<input asp-for="Password" class="form-control" />
-->
</div>
This is Sample input. I am doing Server-side validation only. How can I make input field border red when user input is not validated?
Model Validation feature adds the CSS Class input-validation-error to all the controls that have failed the validation checks .
Here is a example you could refer to :
1.Model
public class User
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[StringLength(8, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 6)]
public string Password { get; set; }
}
2.View
<style type="text/css">
.input-validation-error {
border-color: yellowgreen;
}
</style>
<div class="row">
<div class="col-md-4">
<form asp-action="Create" class="myForm">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password">პაროლი</label>
<input asp-for="Password" type="password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
#section Scripts
{
#{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
Result :
Reference : https://www.yogihosting.com/aspnet-core-model-validation/
Related
my html code
<div class="border backgroundWhite border-info">
<div class="row">
<div class="col-6">
<div class="form-group row">
<div class="col-4">
<label asp-for="Shift.TSBalance"></label>
</div>
<div class="col-6">
<input asp-for="Shift.TSBalance" class="form-control" id="sbalance"/>
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label asp-for="Shift.TSupply"></label>
</div>
<div class="col-6">
<input asp-for="Shift.TSupply" class="form-control" id="supply" value="0" onkeyup="sum()" type="text"/>
</div>
<span asp-validation-for="Shift.TSupply" class="text-danger"></span>
</div>
<div class="form-group row">
<div class="col-4">
<label asp-for="Shift.TTotal"></label>
</div>
<div class="col-6">
<input asp-for="Shift.TTotal" class="form-control" readonly id="trbalance" value="0" onkeyup="sum()" type="text"/>
</div>
<span asp-validation-for="Shift.TTotal" class="text-danger"></span>
</div>
</div>
<div class="col-6">
<div class="form-group row">
<div class="col-7">
<label asp-for="Shift.TCBalance"></label>
</div>
<div class="col-5">
<input asp-for="Shift.TCBalance" class="form-control" id="calcebalance" value="0" onkeyup="sum()" type="text" readonly/>
</div>
</div>
<div class="form-group row">
<div class="col-7">
<label asp-for="Shift.TABalance"></label>
</div>
<div class="col-5">
<input asp-for="Shift.TABalance" class="form-control" id="actualebalance" value="0" onkeyup="sum()" type="text" />
</div>
</div>
<div class="form-group row">
<div class="col-7">
<label asp-for="Shift.TDifferance" class="text-info"></label>
</div>
<div class="col-5">
<input asp-for="Shift.TDifferance" class="form-control" style="background-color:blue;color:white;font-size:larger" id="differance" value="0" onkeyup="sum()" type="text" readonly />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
my page model
namespace Elwady.Pages.ShiftClosing
{
public class CreateModel : PageModel
{
private readonly ApplicationDbContext _db;
public SelectList Exlist { get; set; }
[BindProperty]
public Shift Shift { get; set; }
public CreateModel(ApplicationDbContext db)
{
_db = db;
}
public IActionResult OnGet()
{
this.Exlist = new SelectList(_db.ExpensesList, "Id", "ExName");
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
};
_db.Shift.Add(Shift);
await _db.SaveChangesAsync();
return RedirectToPage("../Index");
}
}
}
my data table
public class Shift
{
public int Id { get; set; }
public int TSBalance { get; set; }
public int TSupply { get; set; }
public int TTotal { get; set; }
public int TCBalance { get; set; }
public int TABalance { get; set; }
public int TDifferance { get; set; }
}
attached image to show clearly how you can support
i tried to get this value through assigning it to variable in get handler but i can't and tried to Asp-for model variable but i get an error in the Ui
if i need to print out this form after submit to specific printer, how can i do that?
trying to submit the commenting form,but the form send null data to my razor page.
it is the html:
<div class="comment-form-container">
<h6>Leave a Comment</h6>
<form method="post">
<div class="input-prepend">
<span class="add-on"><i class="icon-user"></i></span>
<input name="Name" class="span4" id="Name" size="16" type="text" placeholder="Name">
</div>
<div class="input-prepend">
<span class="add-on"><i class="icon-envelope"></i></span>
<input name="Email" class="span4" id="Email" size="16" type="email" placeholder="Email Address">
</div>
<input type="hidden" name="ArticleId" id="ArticleId" value="#Model.articleQueryView.Id" />
<textarea class="span6" name="Message" id="Message"></textarea>
<div class="row">
<div class="span2">
<input type="submit" class="btn btn-inverse" value="Post My Comment">
</div>
</div>
</form>
</div>
and here is the CsHtml code,when in hover the "comment" i just see the null and 0 value:
public class blog_singleModel : PageModel
{
public ArticleQueryView articleQueryView { get; set; }
private readonly ICommentApplication _commentApplication;
private readonly IArticleQuery _query;
public blog_singleModel(IArticleQuery query, ICommentApplication commentApplication)
{
_query = query;
_commentApplication = commentApplication;
}
public void OnGet(int id)
{
articleQueryView = _query.GetArticle(id);
}
public RedirectToPageResult OnPost(AddNewComment comment)
{
_commentApplication.Add(comment);
return RedirectToPage("./blog_single", new { id = comment.ArticleId });
}
}
}
comment.Id is 0 is because your articleQueryView.Id is 0.Name,Email,Message is null is because you did not set the values of them in form.I think your code is correct,but you did not set the values.
sample:
I have a model called, "GetInTouch" (contact us form) with its controller and view all works fine.
My problem is that, when the app loads it has a 'Home/landing page' and I need to display this 'GetInTouch' view on the landing page which has a 'HomeController' rather than having it as a separate page. So upon 'submit' from the Landing page it should go to the 'GetInTouchController' and process the data (save and send emails) but it comes back with null.
Here is the GetInTouch MODEL
public class GetInTouch
{
[Key]
public int Id { get; set; }
[Display(Name = "Your Name")]
public string YourName { get; set; }
[Display(Name = "Email Address")]
public string EmailAddress { get; set; }
[Display(Name = "Your Message")]
public string YourMessage { get; set; }
}
And here is the GetInTouchController
public async Task<IActionResult> Create(GetInTouch intouch)
{
if (ModelState.IsValid)
{
_GetInTouch.GetInTouch.Add(intouch);
await _GetInTouch.SaveChangesAsync();
//await _emailService.SendTestEmail(options);
return RedirectToAction(nameof(Create), new { isSuccess = true, sendId = intouch.Id });
}
return View(intouch.Id);
}
And the GetInTouch View
#model project.Models.GetInTouch
<div class="container">
<h3 class="display-4">Get In Touch</h3>
<hr />
#if (ViewBag.IsSuccess == true)
{
<div class="alert alert-success alert-dismissible fade show" role="alert">
<strong>Thank You for your enquiry!</strong> We'll be in touch with you asap <br />
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
}
<div class="row mt-5">
<div class="col-sm-12 col-md-12">
<h2 class="section-heading text-primary text-center no-after mb-4">
Contact Us
</h2>
<form method="post" class="form-contact" autocomplete="nope" id="contactForm" data-toggle="validator" asp-action="Create" asp-controller="GetInTouch">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="row">
<div class="col-sm-6 col-md-6">
<div class="form-group">
<input type="text" asp-for="YourName" autocomplete="nope" class="form-control" id="p_name" placeholder="Your Name" required="">
<span asp-validation-for="YourName" class="text-danger"></span>
</div>
</div>
<div class="col-sm-6 col-md-6">
<div class="form-group">
<input type="email" asp-for="EmailAddress" autocomplete="new_email" class="form-control" id="p_email" placeholder="Your Email" required="">
<span asp-validation-for="EmailAddress" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<textarea id="p_message" asp-for="YourMessage" class="form-control" rows="6" autocomplete="nope" placeholder="Your Message"></textarea>
<span asp-validation-for="YourMessage" class="text-danger"></span>
</div>
<div class="form-group">
<div class="text-center">
<div id="success"></div>
<input type="submit" value="SEND" class="btn btn-primary" />
</div>
</div>
</form>
</div>
</div>
</div
The above code works fine, now what I want to do is to display this 'form/view' as a section (just before the footer) in another view say Home Index View but when the user clicks 'send' it should of course go to the GetInTouchController create action and process.
So I copy the view from the GetInTouch Create View to the Home Index view just before the footer but the home page/view has a view model name, 'indexViewModel' which list data from another models but I know you can only pass one model to a view (so no way to say #model project.Model.GetInTouch, instead I have #model IndexViewModel in the HomePage) so all I want is once the user completes the form and hit 'Send' from the Home view it goes to the 'GetInTouchController' Create action and save all the details entered to the GetInTouch Model and send email (I got the email function) just need to save the data as it all comes back as null. Here is the IndexViewModel
public class IndexViewModel
{
//public IEnumerable<CategoryVM> Category { get; set; }
public GetInTouch GetInTouch { get; set; }
}
I don't know how to proceed, I tried copying the exact create method to the HomeController and point form to HomeController Create action but that didn't work either - any idea how to process a form in another view? Sorry about it being long but needed to explain what I want to achieve hope it's clear and thank you for your time.
As far as I know, if you want to post the data from another view, you could just set the form tag in the new view.
It will generate the form data according to the input tag and post to the GetInTouch view.
More details, you could refer to below test demo.
Notice: You should set the name in the input tag to match the GetInTouch controller:
Put below form into the index view:
IndexViewModel:
public class IndexViewModel
{
public GetInTouch GetInTouch { get; set; }
}
View:
<form method="post" class="form-contact" autocomplete="nope" id="contactForm" data-toggle="validator" asp-action="Create" asp-controller="GetInTouch">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="row">
<div class="col-sm-6 col-md-6">
<div class="form-group">
<input type="text" asp-for="GetInTouch.YourName" name="YourName" autocomplete="nope" class="form-control" id="p_name" placeholder="Your Name" required="">
<span asp-validation-for="GetInTouch.YourName" class="text-danger"></span>
</div>
</div>
<div class="col-sm-6 col-md-6">
<div class="form-group">
<input type="email" asp-for="GetInTouch.EmailAddress" name="EmailAddress" autocomplete="new_email" class="form-control" id="p_email" placeholder="Your Email" required="">
<span asp-validation-for="GetInTouch.EmailAddress" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<textarea id="p_message" asp-for="GetInTouch.YourMessage" name="YourMessage" class="form-control" rows="6" autocomplete="nope" placeholder="Your Message"></textarea>
<span asp-validation-for="GetInTouch.YourMessage" class="text-danger"></span>
</div>
<div class="form-group">
<div class="text-center">
<div id="success"></div>
<input type="submit" value="SEND" class="btn btn-primary" />
</div>
</div>
</form>
Result:
I have three input filed (text - tow radio button) for one property asp-validation-for works only for the input text I want to validate radio button also if it is not checked ,Model :
[BindProperty,Required(ErrorMessage = "Required")]
public string PriceAfter { get; set; }
Index.cshtml :
<div class="form-group">
<input type="number" class="form-control"
asp-for="Ad.PriceAfter">
<label class="custom-control custom-radio mb-2 ml-4">
<input type="radio" class="custom-control-input"
value="new" asp-for="Ad.PriceAfter" id="PriceAfter">
<span class="custom-control-label">new</span>
</label>
<label class="custom-control custom-radio mb-2">
<input type="radio" class="custom-control-input"
value="Used" asp-for="Ad.PriceAfter" id="PriceAfter">
<span class="custom-control-label">
Used </span>
</label>
<span asp-validation-for="Ad.PriceAfter" class="text-danger"></span>
</div>
I think you can define another field in your class. One is for the input text field and the other is for radio button.
Model:
public class MyViewModel
{
public Ad Ad { get; set; }
}
public class Ad
{
[BindProperty, Required(ErrorMessage = "Required")]
public string PriceAfter { get; set; }
[BindProperty, Required(ErrorMessage = "Required")]
public string Status { get; set; }
}
View:
<form method="post">
<div class="form-group">
<input type="number" class="form-control "
asp-for="Ad.PriceAfter">
<span asp-validation-for="Ad.PriceAfter" class="text-danger"></span>
<label class="custom-control custom-radio mb-2 ">
<input type="radio" class="custom-control-input"
value="new" asp-for="Ad.Status" id="PriceAfter">
<span class="custom-control-label">new</span>
</label>
<label class="custom-control custom-radio mb-2">
<input type="radio" class="custom-control-input"
value="Used" asp-for="Ad.Status" id="PriceAfter">
<span class="custom-control-label">
Used
</span>
</label>
<span asp-validation-for="Ad.Status" class="text-danger"></span>
</div>
<input type="submit" value="submit" />
</form>
Controller:
[HttpPost]
public ActionResult Index(MyViewModel myViewModel)
{
if (!ModelState.IsValid)
{
return View(myViewModel);
}
return Content("Ok");
}
Result:
I have used Visual Studio 2019 to create a Create view (right-click > Add > View) and set the correct model when doing so. After the Create view was created, I added code to the Create HttpPost ActionMethod and just tried to run the app. The ActionMethod is hit, but the data model that is supposed to be passed in to the method is not populated; everything is nulls despite having entered data in the browser. What is weird is that I have other pages in the app created the exact same way (even other Creates on other Areas) that work fine. What am I missing?
Model:
public class BondsAllProjectsModel
{
[Key]
public int ProjectID { get; set; }
[Display(Name = "Project Name")]
[Required (ErrorMessage = "Project Name is required.")]
[StringLength(50)]
public string ProjectName { get; set; }
[Display(Name = "Project Name Alias")]
[StringLength(50)]
public string ProjectNameAlias { get; set; }
[StringLength(50)]
public string Municipality { get; set; }
[StringLength(4)]
public string ProjectCode { get; set; }
public bool IsProject { get; set; }
[RegularExpression(#"^[0-9]*\.?[0-9]*", ErrorMessage = "Only numbers are allowed.")]
public double? ProjectAcres { get; set; }
[RegularExpression(#"\d+", ErrorMessage = "Only numbers are allowed.")]
public double? ProjectUnits { get; set; }
public int? MunicipalityID { get; set; }
[DataType(DataType.Date, ErrorMessage = "Project Completed must be a valid date.")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? ProjectCompleted { get; set; }
[MaxLength(100)]
public string CurrentNotes { get; set; }
public int? ProjectTypeID { get; set; }
public bool Discontinued { get; set; }
}
View:
#model BOnlineMVC.Models.BondsAllProjectsModel
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>BondsAllProjectsModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="ProjectID" class="control-label"></label>
<input asp-for="ProjectID" class="form-control" />
<span asp-validation-for="ProjectID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProjectName" class="control-label"></label>
<input asp-for="ProjectName" class="form-control" />
<span asp-validation-for="ProjectName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProjectNameAlias" class="control-label"></label>
<input asp-for="ProjectNameAlias" class="form-control" />
<span asp-validation-for="ProjectNameAlias" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Municipality" class="control-label"></label>
<input asp-for="Municipality" class="form-control" />
<span asp-validation-for="Municipality" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProjectCode" class="control-label"></label>
<input asp-for="ProjectCode" class="form-control" />
<span asp-validation-for="ProjectCode" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="IsProject" /> #Html.DisplayNameFor(model => model.IsProject)
</label>
</div>
<div class="form-group">
<label asp-for="ProjectAcres" class="control-label"></label>
<input asp-for="ProjectAcres" class="form-control" />
<span asp-validation-for="ProjectAcres" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProjectUnits" class="control-label"></label>
<input asp-for="ProjectUnits" class="form-control" />
<span asp-validation-for="ProjectUnits" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MunicipalityID" class="control-label"></label>
<input asp-for="MunicipalityID" class="form-control" />
<span asp-validation-for="MunicipalityID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProjectCompleted" class="control-label"></label>
<input asp-for="ProjectCompleted" class="form-control" />
<span asp-validation-for="ProjectCompleted" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CurrentNotes" class="control-label"></label>
<input asp-for="CurrentNotes" class="form-control" />
<span asp-validation-for="CurrentNotes" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProjectTypeID" class="control-label"></label>
<input asp-for="ProjectTypeID" class="form-control" />
<span asp-validation-for="ProjectTypeID" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="Discontinued" /> #Html.DisplayNameFor(model => model.Discontinued)
</label>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
Controller:
[HttpPost]
public ActionResult Create(BondsAllProjectsModel projectData)
{
try
{
if (ModelState.IsValid)
{
int newProjectID = bDAL.AddProject(projectData);
return Redirect("~/Bonds/ProjectMaintenance/Create2/" + newProjectID);
}
else
{
return View();
}
}
catch
{
return View();
}
}
You can try to explicitly specify where model binder should looks when binding data by using
[FromForm] attribute
click here for more info
top of the view add #model namespace.BondsAllProjectsModel
<div class="form-group">
<label asp-for="ProjectID" class="control-label"></label>
<input asp-for="#Model.ProjectID" class="form-control" />
<span asp-validation-for="ProjectID" class="text-danger"></span>
</div>
Just add this line in the top of your create view:
#model YourNamespace.BondsAllProjectsModel
There is no need to modify anything else.