I am using EF to save data in DB and so far farm works fine and saves the data, but when i try to add validation to form it doesnt work & doesnt show any error message or save any data in database.
Example of working & non working code.
Below code without validation
Employee.cs
using System.ComponentModel.DataAnnotations;
namespace BlazorSPA1.Data
{
public class Employee
{
[MaxLength(50)]
public string Id { get; set; }
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(50)]
public string Department { get; set; }
[MaxLength(100)]
public string Designation { get; set; }
[MaxLength(100)]
public string Company { get; set; }
[MaxLength(100)]
public string City { get; set; }
}
}
AddEmployee.razor
#page "/addemployee"
#inject NavigationManager NavigationManager
#inject IEmployeeService EmployeeService
<h2>Create Employee</h2>
<hr />
<form>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="Name" class="control-label">Name</label>
<input for="Name" class="form-control" #bind="#employee.Name" />
</div>
<div class="form-group">
<label for="Department" class="control-label">Department</label>
<input for="Department" class="form-control" #bind="#employee.Department" />
</div>
<div class="form-group">
<label for="Designation" class="control-label">Designation</label>
<input for="Designation" class="form-control" #bind="#employee.Designation" />
</div>
<div class="form-group">
<label for="Company" class="control-label">Company</label>
<input for="Company" class="form-control" #bind="#employee.Company" />
</div>
<div class="form-group">
<label for="City" class="control-label">City</label>
<input for="City" class="form-control" #bind="#employee.City" />
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<input type="button" class="btn btn-primary" #onclick="#CreateEmployee" value="Save" />
<input type="button" class="btn" #onclick="#Cancel" value="Cancel" />
</div>
</div>
</div>
</form>
#code {
Employee employee = new Employee();
protected async Task CreateEmployee()
{
await EmployeeService.CreateEmployee(employee);
NavigationManager.NavigateTo("listemployees");
}
void Cancel()
{
NavigationManager.NavigateTo("listemployees");
}
}
Code which is not working after i made validation changes
Employee.cs
using System.ComponentModel.DataAnnotations;
namespace BlazorSPA1.Data
{
public class Employee
{
[MaxLength(50)]
public string Id { get; set; }
[Required]
[StringLength(20)]
public string Name { get; set; }
[Required]
[StringLength(20)]
public string Department { get; set; }
[MaxLength(100)]
public string Designation { get; set; }
[MaxLength(100)]
public string Company { get; set; }
[MaxLength(100)]
public string City { get; set; }
}
}
AddEmployeeValidation.razor
#page "/addemployeeValidation"
#inject NavigationManager NavigationManager
#inject IEmployeeService EmployeeService
<h2>Create Employee</h2>
<hr />
<EditForm Model="#employee" OnValidSubmit="#CreateEmployee">
<DataAnnotationsValidator />
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="Name" class="control-label">Name</label>
<input for="Name" class="form-control" #bind="#employee.Name" />
<ValidationMessage For="#(()=> employee.Name)" />
</div>
<div class="form-group">
<label for="Department" class="control-label">Department</label>
<input for="Department" class="form-control" #bind="#employee.Department" />
</div>
<div class="form-group">
<label for="Designation" class="control-label">Designation</label>
<input for="Designation" class="form-control" #bind="#employee.Designation" />
</div>
<div class="form-group">
<label for="Company" class="control-label">Company</label>
<input for="Company" class="form-control" #bind="#employee.Company" />
</div>
<div class="form-group">
<label for="City" class="control-label">City</label>
<input for="City" class="form-control" #bind="#employee.City" />
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<input type="button" class="btn btn-primary" value="Save" />
<input type="button" class="btn" #onclick="#Cancel" value="Cancel" />
</div>
</div>
</div>
</EditForm>
#code {
Employee employee = new Employee();
protected async Task CreateEmployee()
{
await EmployeeService.CreateEmployee(employee);
NavigationManager.NavigateTo("listemployees");
}
void Cancel()
{
NavigationManager.NavigateTo("listemployees");
}
}
I am using below code example show in this example https://www.c-sharpcorner.com/article/visual-studio-extension-for-blazor-spa-with-ef-core-3-1/
When i add validation code, it open Add Employee page but nothing happens no validation message no form submit even no data is save in database. not sure where issue is
I had made a tiny mistake which went un-noticed, Validation started working when i changed the input type to submit
<input type="button" class="btn btn-primary" value="Save" />
Correct
<input type="submit" class="btn btn-primary" value="Save" />
Related
I want to make the user only choose between two strings, Internal or Consigned, to be inserted into the InternalConsigned column of a database. How do I do that?
This is my current code:
Equipment.cs model class:
public class Equipment
{
[Key]
public int Id { get; set; }
[Required]
[DisplayName("Equipment Name")]
public string Name { get; set; }
[Required]
public int Amount { get; set; }
[Required]
public string Status { get; set; }
[ForeignKey("DepartmentId")]
public int DepartmentId { get; set; }
public Department? Department { get; set; }
[Required]
public string InternalConsigned { get; set; }
public DateTime EOLDate { get; set; }
}
Create action method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name,Amount,Status,DepartmentId,InternalConsigned,EOLDate")] Equipment equipment)
{
if (ModelState.IsValid)
{
_context.Add(equipment);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["DepartmentId"] = new SelectList(_context.Departments, "Id", "Name", equipment.DepartmentId);
return View(equipment);
}
Create.cshtml:
#model Equipment
#{
ViewData["Title"] = "Create";
}
<h4>Equipment</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<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="Amount" class="control-label"></label>
<input asp-for="Amount" class="form-control" />
<span asp-validation-for="Amount" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Status" class="control-label"></label>
<input asp-for="Status" class="form-control" />
<span asp-validation-for="Status" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DepartmentId" class="control-label"></label>
<select asp-for="DepartmentId" class ="form-control" asp-items="ViewBag.DepartmentId"></select>
</div>
<div class="form-group">
<label asp-for="InternalConsigned" class="control-label"></label>
<input asp-for="InternalConsigned" class="form-control" />
<span asp-validation-for="InternalConsigned" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="EOLDate" class="control-label"></label>
<input asp-for="EOLDate" class="form-control" />
<span asp-validation-for="EOLDate" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
I know I have to use the select tag in the View, but I'm not sure what to write in the Controller.
If I don't misunderstand your question, You want to write a dropdown list with two options Internal or Consigned, So you can refer to this simple demo, Hope it can help you.
List<SelectListItem> test = new List<SelectListItem>();
test.Add(new SelectListItem { Text = "Internal ", Value = "Internal " });
test.Add(new SelectListItem { Text = "Consigned", Value = "Consigned" });
ViewData["demo"] = test;
Then in the view:
<select asp-for="InternalConsigned" asp-items="#ViewBag.demo"></select>
Demo:
I'm trying to use client-side validation in my razor pages app but it's not working for the views.
It does work on the register page that is located under the identity area.
Create.cshtml
#model Toolbox.Models.ProjectsModel.Assignment
#{
ViewData["Title"] = "Create";
}
<h1>Nieuwe taak maken</h1>
<h4>Taak</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<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="Fase" class="control-label"></label>
<input asp-for="Fase" class="form-control" />
<span asp-validation-for="Fase" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Maak nieuwe taak" class="btn btn-primary my-2"/>
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index" class="btn btn-primary">Terug</a>
</div>
Assignment.cs
using System.ComponentModel.DataAnnotations;
using Toolbox.Interfaces;
namespace Toolbox.Models.ProjectsModel
{
public class Assignment : IAssignment
{
[Key]
public int Id { get; set; }
[Display(Name = "Naam")]
[Required]
public string Name { get; set; }
[Required]
public string Fase { get; set; }
public List<SubAssignment> SubAssignment { get; set; }
}
}
_ViewImports.cshtml
#using Toolbox
#using Toolbox.Models
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
_viewStart.cshtml
#{
Layout = "_Layout";
}
Program.cs
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "default",
pattern: "{controller=Home}/{action=Index}");
endpoints.MapRazorPages();
});
Does anybody know how I need to solve this problem?
You need to include the _ValidationScriptsPartial file in the Razor page. Add the following to the bottom of the page/view:
#section scripts{
<partial name="_ValidationScriptsPartial" />
}
i have a login page with Username and Password inputs and also a submit button. I want to call a method in my Controller that checks if the data matches and shows the result. how do i call that method? I tried the following but it didnt work it passes those as parameters
#using (Html.BeginForm("Logmein", "LoginController", FormMethod.Post))
{
<form method="post">
<div class="input-group mt-3">
<div class="input-group-prepend">
</div>
<input type="text" class="form-control" placeholder="Username" asp-for="Userusername">
</div>
<div id="login_usernametxt" class="input-group mt-2">
<input id="login_passwordtxt" type="password" class="form-control" placeholder="Password" asp-for="Userpassword">
</div>
<button id="login_signinbtn" class="mt-3 btn bg-warning text-light" style="float: right;" formmethod="post">Sign in</button>
</form>
}
here is my controller.
public class LoginController : Controller
{
public LoginInfo Logininformation { get; set; }
public IActionResult Userlogin()
{
return View();
}
[HttpPost]
public IActionResult Logmein()
{
//checks if the data matches....
return RedirectToPage("/Home/Index");
}
}
Tyr to include model with following properties Userusername,Userpassword in Logmein() method
Also u can remove html helper method ( #using (Html.BeginForm("Logmein", "LoginController", FormMethod.Post)))
Ex:
<form method = "post" asp-controller = "Login" asp-action = "Logmein" >
<div class="input-group mt-3">
<div class="input-group-prepend">
</div>
<input type="text" class="form-control" placeholder="Username" asp-for="Userusername">
</div>
<div id="login_usernametxt" class="input-group mt-2">
<input id="login_passwordtxt" type="password" class="form-control" placeholder="Password" asp-for="Userpassword">
</div>
<input type = "submit" value = "Login" />
</form>
Model Class
public class Login
{
public string Userusername { get; set; }
public string Userpassword { get; set; }
}
Controller Method:
[HttpPost]
public IActionResult Logmein(LoginModel login)
{
//checks if the data matches....
return RedirectToPage("/Home/Index");
}
I currently have 2 models:
Movie.cs
public int MovieId { get; set; }
public Genre Genre { get; set; }
public int GenreId { get; set; }
public string MovieTitle { get; set; }
Genre.cs
public int GenreId { get; set; }
public string GenreName { get; set; }
public List<Movie> Movies;
My Create.cshtml View
<div class="row">
<div class="col-md-4">
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="GenreId" class="control-label"></label>
<select asp-for="GenreId" class="form-control" asp-items="ViewBag.GenreId"></select>
</div>
<div class="form-group">
<label asp-for="DirectorId" class="control-label"></label>
<select asp-for="DirectorId" class="form-control" asp-items="ViewBag.DirectorId"></select>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="IsHot" /> #Html.DisplayNameFor(model => model.IsHot)
</label>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="IsNew" /> #Html.DisplayNameFor(model => model.IsNew)
</label>
</div>
<div class="form-group">
<label asp-for="MovieTitle" class="control-label"></label>
<input asp-for="MovieTitle" class="form-control" />
<span asp-validation-for="MovieTitle" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieLang" class="control-label"></label>
<input asp-for="MovieLang" class="form-control" />
<span asp-validation-for="MovieLang" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieLink" class="control-label"></label>
<input asp-for="MovieLink" class="form-control" />
<span asp-validation-for="MovieLink" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MoviePlot" class="control-label"></label>
<input asp-for="MoviePlot" class="form-control" />
<span asp-validation-for="MoviePlot" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieImageFile" class="control-label"></label>
<input asp-for="MovieImageFile" accept="image/*" />
<span asp-validation-for="MovieImageFile" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieReleaseYear" class="control-label"></label>
<input asp-for="MovieReleaseYear" class="form-control" />
<span asp-validation-for="MovieReleaseYear" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CreateDate" class="control-label"></label>
<input asp-for="CreateDate" class="form-control" />
<span asp-validation-for="CreateDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieTrailerLink" class="control-label"></label>
<input asp-for="MovieTrailerLink" class="form-control" />
<span asp-validation-for="MovieTrailerLink" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
so when I make a View to let Admins create a new Movie it allows them to choose from a dropdown list of Genres.
But now I want a many-to-many relationship which would allow me to add 3,4 Genres into one Movie, how do I make views and models for that?
I'm pretty sure I need to make a third model for many-to-many
relationship but I can't find an example on the internet that use it.
Yes, you need to create a third table to connect the two tables many-to-many relationship, first you need to modify your model, as follows:
public class Movie
{
[Key]
public int MovieId { get; set; }
public string MovieTitle { get; set; }
public List<MovieGenre> MovieGenres { get; set; }
}
public class Genre
{
public int GenreId { get; set; }
public string GenreName { get; set; }
public List<MovieGenre> MovieGenres { get; set; }
}
//Intermediate table
public class MovieGenre
{
public int MovieId { get; set; }
public Movie Movie { get; set; }
public int GenreId { get; set; }
public Genre Genre { get; set; }
}
You still need to determine the relationship between these three tables in OnModelCreating in the dbcontext file:
public partial class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options)
{
}
public DbSet<Movie> Movie { get; set; }
public DbSet<Genre> Genre { get; set; }
public DbSet<MovieGenre> MovieGenre { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MovieGenre>()
.HasKey(bc => new { bc.MovieId, bc.GenreId });
modelBuilder.Entity<MovieGenre>()
.HasOne(bc => bc.Movie)
.WithMany(b => b.MovieGenres)
.HasForeignKey(bc => bc.MovieId);
modelBuilder.Entity<MovieGenre>()
.HasOne(bc => bc.Genre)
.WithMany(c => c.MovieGenres)
.HasForeignKey(bc => bc.GenreId);
}
}
Next, you can pass Movie object and select the list of GenreId to the controller:
View:
#model WebApplication_core_mvc.Models.Movie
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Index</h1>
<div class="row">
<div class="col-md-4">
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label class="control-label"></label>
<select class="form-control" asp-items="ViewBag.GenreId" name="GenreIdList" multiple></select>
</div>
<div class="form-group">
<label asp-for="MovieTitle" class="control-label"></label>
<input asp-for="MovieTitle" class="form-control" />
<span asp-validation-for="MovieTitle" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
Controller:
public class MMTestController : Controller
{
private readonly MyDbContext _context;
public MMTestController(MyDbContext context)
{
_context = context;
}
public IActionResult Index()
{
List<SelectListItem> selectListItems = _context.Genre.Select(a => new SelectListItem
{
Text = a.GenreName,
Value = a.GenreId.ToString()
}).ToList();
ViewBag.GenreId = selectListItems;
return View();
}
public IActionResult Create(Movie movie, List<int> GenreIdList)
{
_context.Movie.Add(movie);
_context.SaveChanges();
foreach (var item in GenreIdList)
{
MovieGenre movieGenre = new MovieGenre()
{
GenreId = item,
MovieId = movie.MovieId,
Genre = _context.Genre.Where(x => x.GenreId == item).FirstOrDefault(),
Movie = movie
};
_context.MovieGenre.Add(movieGenre);
}
_context.SaveChanges();
return View();
}
}
Here is the test result:
I'm trying to Add values in table(Flight) which have one to many relation with table(Flight classes)
for view of flightClasses i'm using foreach loop but it comes with null model
i can't understand how to do it please help me
Flight Table will have one Row against which i want to add multiple rows in the FlightClasses Table
Flight Modle
public class FlightModel
{
public int Id { get; set; }
public string FlightName { get; set; }
public string FlightNo { get; set; }
public string OriginCity { get; set; }
public string DestinationCity { get; set; }
public DateTime Departure { get; set; }
public DateTime Arrival { get; set; }
public virtual ICollection<FlightClassesModel> FlightClasses { get; set; }
}
FlightClasses Model
public class FlightClassesModel
{
public int FlightClassesModelId { get; set; }
public type Class { get; set; }
public int AvailableSeats { get; set; }
public double Price { get; set; }
public virtual FlightModel Flight { get; set; }
public int? FlightId { get; set; }
}
public enum type
{
Business_Class,
First_Class,
Club_Class
}
View
#model Airline.Models.FlightModel
#{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<h4>FlightModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="FlightName" class="control-label"></label>
<input asp-for="FlightName" class="form-control" />
<span asp-validation-for="FlightName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="FlightNo" class="control-label"></label>
<input asp-for="FlightNo" class="form-control" />
<span asp-validation-for="FlightNo" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="OriginCity" class="control-label"></label>
<input asp-for="OriginCity" class="form-control" />
<span asp-validation-for="OriginCity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DestinationCity" class="control-label"></label>
<input asp-for="DestinationCity" class="form-control" />
<span asp-validation-for="DestinationCity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Departure" class="control-label"></label>
<input asp-for="Departure" class="form-control" />
<span asp-validation-for="Departure" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Arrival" class="control-label"></label>
<input asp-for="Arrival" class="form-control" />
<span asp-validation-for="Arrival" class="text-danger"></span>
</div>
#foreach (var flightClass in Model.FlightClasses)
{
<div class="form-group">
<label asp-for="#flightClass.Class" class="control-label"></label>
<select asp-for="#flightClass.Class" asp-items="Html.GetEnumSelectList<type>()"></select>
<span asp-validation-for="#flightClass.Class" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#flightClass.AvailableSeats" class="control-label"></label>
<input asp-for="#flightClass.AvailableSeats" class="form-control" />
<span asp-validation-for="#flightClass.AvailableSeats" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#flightClass.Price" class="control-label"></label>
<input asp-for="#flightClass.Price" class="form-control" />
<span asp-validation-for="#flightClass.Price" class="text-danger"></span>
</div>
}
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
Controller
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(FlightModel flightModel)
{
if (ModelState.IsValid)
{
_context.Add(flightModel);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(flightModel);
}