MVC AD search - Displaying multiple results as .cshtml - asp.net-mvc

I have fully working code that searches active directory and displays it with MVC .cshtml But I have been trying to figure out away to add all the users found to a list then display them. As currently it just displays the first user found.
This is the HomeController that takes a value, Searches AD and returns the results.
public class HomeController : Controller
{
public ActionResult Index(IndexViewModel profile)
{
if (ModelState.IsValid)
{
//List<Principal> users = new List<Principal>();
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.DisplayName = profile.Name + "*";
using (PrincipalSearcher srch = new PrincipalSearcher(qbeUser))
{
if(!(srch.FindAll().Count() < 0))
{
foreach(var found in srch.FindAll())
{
//users.Add(found);
IndexViewModel returnmodel = new IndexViewModel(found);
return View(returnmodel);
}
}
}
}
}
return View(profile);
}
}
The IndexViewModel
public class IndexViewModel
{
public IndexViewModel(Principal found)
{
Name = found.DisplayName;
Email = found.UserPrincipalName;
Description = found.Description;
}
[Required(ErrorMessage = "Please enter a name")]
[Display(Name = "Persons Name")]
public string Name { get; set; }
public string Email { get; set; }
public string Description { get; set; }
//public List<Principal> user { get; set; }
}
Index.cshtml
<div id="content">
#Html.ValidationSummary(true)
#using (Html.BeginForm("Index", "Home"))
{
<fieldset>
<div class="form-group col-md-12">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(modelItem => Model.Name, new { htmlAttributes = new { #class = "form-control", #style = "width:280px" }, })
#Html.ValidationMessageFor(x => x.Name)
</div>
<div class="col-md-2">
<input type="submit" class="btn btn-default" value="Search">
</div>
<div class="col-md-3">
</div>
</div>
</fieldset>
}
<br>
</div>
<table id="historyTable" class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>#Model.Name</td>
<td>#Model.Email</td>
<td>#Model.Description</td>
</tr>
</tbody>
</table>
EDIT-----------
This is one method I tried ----------------
HomeController.cs
public class HomeController : Controller
{
public ActionResult Index(IndexViewModel profile)
{
if (ModelState.IsValid)
{
List<Principal> users = new List<Principal>();
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.DisplayName = profile.Name + "*";
using (PrincipalSearcher srch = new PrincipalSearcher(qbeUser))
{
if(!(srch.FindAll().Count() < 0))
{
foreach(var found in srch.FindAll())
{
users.Add(found);
IndexViewModel returnmodel = new IndexViewModel(users);
return View(returnmodel);
}
}
}
}
}
return View(profile);
}
IndexViewModel.cs
public class IndexViewModel
{
public IndexViewModel(List<Principal> found)
{
user = found;
}
[Required(ErrorMessage = "Please enter a name")]
[Display(Name = "Persons Name")]
public string Name { get; set; }
public string Email { get; set; }
public string Description { get; set; }
public List<Principal> user { get; set; }
}
index.html
<div id="content">
#Html.ValidationSummary(true)
#using (Html.BeginForm("Index", "Home"))
{
<fieldset>
<div class="form-group col-md-12">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(modelItem => Model.Name, new { htmlAttributes = new { #class = "form-control", #style = "width:280px" }, })
#Html.ValidationMessageFor(x => x.Name)
</div>
<div class="col-md-2">
<input type="submit" class="btn btn-default" value="Search">
</div>
<div class="col-md-3">
</div>
</div>
</fieldset>
}
<br>
</div>
<table id="historyTable" class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Description</th>
</tr>
</thead>
<tbody>
#using System.DirectoryServices.AccountManagement
#foreach (Principal prin in Model.user)
{
<tr>
<td>#prin.DisplayName</td>
<td>#prin.UserPrincipalName</td>
<td>#prin.Description</td>
</tr>
}
</tbody>
</table>
The error I get on compile is --
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 37: <tbody>
Line 38: #using System.DirectoryServices.AccountManagement
Line 39: #foreach (Principal prin in Model.user)
Line 40: {
Line 41: <tr>
Source File: C:\Users\hga\Documents\Visual Studio 2015\Projects\Intra AD people searcher\Intra AD people searcher\Views\Home\Index.cshtml Line: 39

You can add if statement to check for null
#if(Model.user !=null)
{
#foreach (Principal prin in Model.user)
{
<!--your code here-->
}
}

In your controller, your return statement is inside your foreach loop. So the first time it goes through the loop, it will return. That means you will only have one result.
Try this:
foreach(var found in srch.FindAll())
{
users.Add(found);
}
IndexViewModel returnmodel = new IndexViewModel(users);
return View(returnmodel);

Related

One-To-Many relationship between ApplicationUser and an other object

I am struggling trying to implement à create action and an index for my controller.
Basically, I want each user to have multiple pizzas.
I want the connected user to create his own pizzas.
And in the index of my controller I want to show, only the pizzas created by the current connected user.
Here are my models :
1/Pizzas :
public class PizzaModel
{
[Key]
public int PizzaID { get; set; }
[Display(Name = "Nom")]
public string nom { get; set; }
[Display(Name = "Prix(€)")]
public float prix { get; set; }
[Display(Name = "Végétarienne")]
public bool vegetarienne { get; set; }
[Display(Name = "Ingrédients")]
public string ingredients { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
public string ApplicationUserId { get; set; }
}
2/ ApplicationUser :
public class ApplicationUser : IdentityUser
{
public ICollection<PizzaModel> Pizzas { get; set; }
}
3/ This is my Context :
public class AuthDbContext : IdentityDbContext<ApplicationUser>
{
public AuthDbContext(DbContextOptions<AuthDbContext> options) : base(options)
{
}
public DbSet<PizzaModel> Pizzas { get; set; }
public DbSet<ApplicationUser> ApplicationUsers { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<ApplicationUser>()
.HasMany(p => p.Pizzas)
.WithOne(u => u.ApplicationUser)
.IsRequired()
.HasForeignKey(p => p.ApplicationUserId);
base.OnModelCreating(builder);
}
I want to create a "create action" and an "index action" that shows only the pizzas created by the current connected user. Here is what I have done so far :
1/ Index action method :
public async Task<IActionResult> Index(string searchByName)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
IEnumerable<PizzaModel> pizzas = new List<PizzaModel>();
pizzas = _context.Pizzas.Where(x => x.ApplicationUserId == userId);
return View(pizzas);
}
2/ Create Action Method :
public async Task<IActionResult> Create(PizzaModel model)
{
_context.ApplicationUsers.Add(model);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index), "Pizza");
}
Could you please help me with these 2 actions (Create and Index) ?
According to your Model and DbContext, I create the actions as below: I'm using the Home Controller and Project name is "WebApplication3"
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly ApplicationDbContext _dbContext;
public HomeController(ILogger<HomeController> logger, ApplicationDbContext dbContext)
{
_logger = logger;
_dbContext = dbContext;
}
public IActionResult Index()
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
IEnumerable<PizzaModel> pizzas = new List<PizzaModel>();
pizzas = _dbContext.Pizzas.Where(x => x.ApplicationUserId == userId);
return View(pizzas);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Create(PizzaModel model)
{
//Note: if you check the ModelState.IsValid, it will return false, because there is no ApplicationID and PizzaID,
//you can create a view model to enter the new value, then, convert it to PizzaModel
//validate the model
//if (ModelState.IsValid)
//{
//get current user id
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (userId != null)
{
//based on the userid to find current user and get its pizzas.
var currentuser = _dbContext.ApplicationUsers.Include(c => c.Pizzas).First(c => c.Id == userId);
List<PizzaModel> pizzas = new List<PizzaModel>();
pizzas = currentuser.Pizzas.ToList();
//add the new item to pizza list
pizzas.Add(new PizzaModel()
{
nom = model.nom,
prix = model.prix,
vegetarienne = model.vegetarienne,
ingredients = model.ingredients
});
//update the pizzas for current user.
currentuser.Pizzas = pizzas;
await _dbContext.SaveChangesAsync();
}
return RedirectToAction(nameof(Index));
//}
//else
//{
// return View();
//}
}
The Index view as below:
#model IEnumerable<WebApplication3.Data.PizzaModel>
#{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.PizzaID)
</th>
<th>
#Html.DisplayNameFor(model => model.nom)
</th>
<th>
#Html.DisplayNameFor(model => model.prix)
</th>
<th>
#Html.DisplayNameFor(model => model.vegetarienne)
</th>
<th>
#Html.DisplayNameFor(model => model.ingredients)
</th>
<th>
#Html.DisplayNameFor(model => model.ApplicationUserId)
</th>
<th></th>
</tr>
</thead>
<tbody>
#if(Model.ToList().Count > 0)
{
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.PizzaID)
</td>
<td>
#Html.DisplayFor(modelItem => item.nom)
</td>
<td>
#Html.DisplayFor(modelItem => item.prix)
</td>
<td>
#Html.DisplayFor(modelItem => item.vegetarienne)
</td>
<td>
#Html.DisplayFor(modelItem => item.ingredients)
</td>
<td>
#Html.DisplayFor(modelItem => item.ApplicationUserId)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
}
else
{
<tr><td colspan="7">Empty</td></tr>
}
</tbody>
</table>
<p>
<a asp-action="Create">Create New Pizza</a>
</p>
The Create View:
#model WebApplication3.Data.PizzaModel
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>PizzaModel</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="nom" class="control-label"></label>
<input asp-for="nom" class="form-control" />
<span asp-validation-for="nom" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="prix" class="control-label"></label>
<input asp-for="prix" class="form-control" />
<span asp-validation-for="prix" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="vegetarienne" /> #Html.DisplayNameFor(model => model.vegetarienne)
</label>
</div>
<div class="form-group">
<label asp-for="ingredients" class="control-label"></label>
<input asp-for="ingredients" class="form-control" />
<span asp-validation-for="ingredients" class="text-danger"></span>
</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>
The result as below:
Generally, in the HttpPost method such as the Create or Update action method, we need to validte the model is valid or not, then based on the result to show validation message or go the next steps. You can refer the following tutorials:
Model validation in ASP.NET Core MVC and Razor Pages
Tutorial: Implement CRUD Functionality - ASP.NET MVC with EF Core

Search filter using multiple fields showing error in ASP.NET MVC with Entitiy Framework

I am trying to apply search filter in ASP.NET MVC using multiple fields for which I have used view models. I have reached close to it but it is showing this error:
The model item passed into the dictionary is of type 'System.Data.Entity.DbSet`1[HMS.Models.tblPatient]', but this dictionary requires a model item of type 'HMS.ViewModels.SearchViewModel'
I don't know what I am doing wrong.
Here is my code:
SearchController.cs:
public ActionResult Index(SearchViewModel searchModel)
{
var search = new SearchDAL();
var model = search.GetSearchResults(searchModel);
return View(model);
}
ViewModel.cs:
public class SearchViewModel
{
public SearchViewModel()
{
PatientsSearch = new List<SearchResult>();
}
public int? Patient_ID { set; get; }
public string Patient_Name { set; get; }
public string Patient_Address { set; get; }
public string Contact_Number { set; get; }
public int Age { set; get; }
public string Gender { set; get; }
public List<SearchResult> PatientsSearch { set; get; }
}
public class SearchResult
{
public int? Patient_ID { set; get; }
public string Patient_Name { set; get; }
public string Patient_Address { set; get; }
public string Contact_Number { set; get; }
public int Age { set; get; }
public string Gender { set; get; }
}
SearchDAL.cs:
public class SearchDAL
{
private HMS_DBEntity Context;
public SearchDAL()
{
Context = new HMS_DBEntity();
}
public IQueryable<tblPatient> GetSearchResults(SearchViewModel searchModel)
{
var result = Context.tblPatients.AsQueryable();
if (searchModel != null)
{
if (searchModel.Patient_ID.HasValue)
result = result.Where(x => x.Patient_id == searchModel.Patient_ID);
if (!string.IsNullOrEmpty(searchModel.Patient_Name))
result = result.Where(x => x.Patient_Name.Contains(searchModel.Patient_Name));
if (!string.IsNullOrEmpty(searchModel.Patient_Address))
result = result.Where(x => x.Patient_address.Contains(searchModel.Patient_Address));
if (!string.IsNullOrEmpty(searchModel.Contact_Number))
result = result.Where(x => x.Contact_no.Contains(searchModel.Contact_Number));
}
return result;
}
}
Index.cshtml:
#using HMS.ViewModels
#model HMS.ViewModels.SearchViewModel
#*#model HMS.Models.tblPatient*#
#{
ViewBag.Title = "Index";
}
<section class="content">
#using (Html.BeginForm("Index", "Search", FormMethod.Get))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(false, "", new { #class = "text-danger" })
<div class="container-fluid">
<div class="block-header">
<h2>Patients Record</h2>
</div>
<div class="row clearfix">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="card">
<div class="body">
<div class="row clearfix">
<div class="col-sm-6 col-md-6 col-lg-6">
<div class="form-group">
<div class="form-line">
#Html.TextBoxFor(x => x.Patient_ID, new { #type = "Text", #class = "form-control", #id = "PatientID", #placeholder = "Patiend ID" })
</div>
</div>
</div>
<div class="col-sm-6 col-md-6 col-lg-6">
<div class="form-group">
<div class="form-line">
#Html.TextBoxFor(x => x.Patient_Name, new { #type = "Text", #class = "form-control", #id = "PatientName", #placeholder = "Patiend Name" })
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-6 col-md-6 col-lg-6">
<div class="form-group">
<div class="form-line">
#Html.TextBoxFor(x => x.Patient_Address, new { #type = "Text", #class = "form-control", #id = "PatientAddress", #placeholder = "Patient Address" })
</div>
</div>
</div>
<div class="col-sm-6 col-md-6 col-lg-6">
<div class="form-group">
<div class="form-line">
#Html.TextBoxFor(x => x.Contact_Number, new { #type = "Text", #class = "form-control", #id = "ContactNo", #placeholder = "Contact Number" })
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-6 col-md-6 col-lg-6">
<input type="submit" id="Submit" class="btn btn-raised g-bg-cyan waves-effect" value="Search" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
<div class="row clearfix">
<div class="container-fluid">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="card">
<div class="body table-responsive">
<table class="table table-bordered table-striped table-hover js-basic-example dataTable">
<tr>
<th>
#Html.DisplayNameFor(model => model.Patient_Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Patient_Address)
</th>
<th>
#Html.DisplayNameFor(model => model.Contact_Number)
</th>
<th>
#Html.DisplayNameFor(model => model.Age)
</th>
<th>
#Html.DisplayNameFor(model => model.Gender)
</th>
<th></th>
</tr>
#{
if (Model.PatientsSearch != null && Model.PatientsSearch.Count > 0)
{
foreach (var item in Model.PatientsSearch)
{
<tr>
<td>#item.Patient_Name</td>
<td>#item.Patient_Address</td>
<td>#item.Contact_Number</td>
<td>#item.Age</td>
<td>#item.Gender</td>
</tr>
}
}
}
</table>
</div>
The error message is clear. Your model defined in view Index.cshtml is
#model HMS.ViewModels.SearchViewModel
But the data you pass to the view is result of GetSearchResults, which is System.Data.Entity.DbSet`1[HMS.Models.tblPatient]
var model = search.GetSearchResults(searchModel);
return View(model);
I think you know how to make it works now.
It's a type mismatch issue at:
return View(model);
So, inside GetSearchResults method, make following change while returning the result object:
result = new List<SearchViewModel>(result);
return result;
And, change your return type of GetSearchResults() method from IQueryable to List
public List<SearchViewModel> GetSearchResults(SearchViewModel searchModel)

View is expecting for viewmodel while List item has been passed to controller

Error::
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[ProjDAL.Models.ViewModels.EmpViewModel]', but this dictionary requires a model item of type 'ProjDAL.Models.ViewModels.EmpViewModel'.
I am working on a mvc application. For one view which basically has a functionality for multiple parameter search. I am using same view for get and post method... It means i am passing 1 or more parameters to the textboxes and fetching the result using linq and mapping to a datatable.
After passing the parameters, the values are going to the controller and fetching the exact result using linq but the problem is coming when i am trying to map the linq result-set to my view.
Here is the code for the project -
Controller -
[HttpPost]
public ActionResult EmpSearch([Bind(Include = "employee,EmpID,PAN")] Get_EmpDetails_Result get_EmpDetails_Result)
{
var result = from emp in dbCollections.Employees
join nat in dbCollections.NationalID on emp.EmpID equals nat.EmpID
select new EmpViewModel
{
PAN = nat.pan,
EmpID = emp.EmpID,
employee = emp.Name
};
var searchRes = result
.Where(s => s.PAN.Contains(get_EmpDetails_Result.pan)
|| s.EmpID.Contains(get_EmpDetails_Result.empid)
|| s.employee.Contains(get_EmpDetails_Result.employee));
var modelSys = searchRes.ToList();
return View(modelSys);
}
View ::::
#model NewProjDAL.Models.ViewModels.EmpViewModel
#{
ViewBag.Title = "empDetails";
Layout = "~/Views/Shared/_Layout.cshtml";
}
//////////// this part is for the multiple criteria search
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<label>By EmpID</label>
<div class="col-md-10">
#Html.EditorFor(model => model.GetEmpDetails.FirstOrDefault().empid, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<label>By PAN</label>
<div class="col-md-10">
#Html.EditorFor(model => model.GetEmpDetails.FirstOrDefault().pan, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<label>By Name</label>
<div class="col-md-10">
#Html.EditorFor(model => model.GetEmpDetails.FirstOrDefault().employee, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-actions center">
<button type="submit" data-animation="pulse" class="btn btn-lg font-medium-1 btn-outline-teal mb-1 block-multiple-msgs buttonAnimation">
<i class="fa fa-check-square-o"></i> Go
</button>
</div>
</div>
}
//////////////////////////////this part is to fetch the result of the previously mentioned multiple search
#if (Model.EmpDetails.Count != 0)
{
<div class="table-responsive">
<table class="table table-striped table-bordered dom-jQuery-events compact" id="DataTbl">
<thead class="navbar-dark navbar-dark bg-blue-grey white">
<tr>
<th>
employee
</th>
<th>
PAN
</th>
<th>
empid
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.GetEmpDetails)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.employee)
</td>
<td>
#Html.DisplayFor(modelItem => item.PAN)
</td>
<td>
#Html.DisplayFor(modelItem => item.empid)
</td>
</tr>
}
</tbody>
</table>
</div>
}
It's told you exactly what the problem is. You've set up the view to accept a single EmpViewModel as the Model, but your controller is passing a List
You need to create a view model to represent the search criteria and the results
public class EmployeeSearchViewModel
{
public string EmpId { get; set; }
public string PAN { get; set; }
public string Employee { get; set; }
public List<EmpViewModel> Employees { get; set; } = new List<EmpViewModel>();
}
then in your controller method:
var modelSys = searchRes.ToList();
var viewModel = new EmployeeSearchViewModel
{
PAN = get_EmpDetails_Result.pan,
EmpId = get_EmpDetails_Result.empid,
Employee = get_EmpDetails_Result.employee
Employees = modelSys
};
return View(viewModel);
In the view:
#Model EmployeeSearchViewModel
Then your parameters display don't need to pull the EmpID, PAN, etc. from the collection, just from the view model, and you can bind your repeated results to the inner collection "Employees".

Not able to apply validation in the database first approach in asp.net mvc System.Data.Entity.Validation.DbEntityValidationException:

I have made a small mvc application and was not trying to implement validation on it. For this I tried using this tutorial
http://www.tutorialsteacher.com/mvc/implement-validation-in-asp.net-mvc
I had done the exact thing but getting an error
My code is as follows
Model Class
namespace Bittu2
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class student1
{
public int StudentId { get; set; }
[Required]
[StringLength(30)]
public string Name { get; set; }
public string Branch { get; set; }
[Display(Name = "Mobile Number:")]
[Required(ErrorMessage = "Mobile Number is required.")]
[RegularExpression(#"^([0-9]{10})$", ErrorMessage = "Invalid Mobile Number.")]
public Nullable<int> Mobile { get; set; }
}
}
create Action method in Home Controller
private StudentDemoEntities studentDemoEntities = new StudentDemoEntities();
public ActionResult Index()
{
var s = from student1 in studentDemoEntities.student1 select student1;
return View(s);
}
[HttpPost]
public ActionResult Create(String Name, String Branch, int Mobile)
{
student1 stud = new student1();
stud.Name = Name;
stud.Branch = Branch;
stud.Mobile = Mobile;
if(ModelState.IsValid)
{
studentDemoEntities.student1.Add(stud);
studentDemoEntities.SaveChanges(); //getting exception here. System.Data.Entity.Validation.DbEntityValidationException: 'Validation failed for one or more entities.
return RedirectToAction("Index");
}
return View();
}
My create view
model Bittu2.student1
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Create</title>
</head>
<body>
#using (Html.BeginForm("Create", "Home"))
{
<table>
<tr>
<td>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
</td></tr>
<tr>
<td>
#Html.LabelFor(model => model.Name)
</td>
<td>
#Html.TextBoxFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</td>
</tr>
<tr>
<td>
#Html.LabelFor(model => model.Branch)
</td>
<td>
#Html.TextBoxFor(model => model.Branch)
#Html.ValidationMessageFor(model => model.Branch, "", new { #class = "text-danger" })
</td>
</tr>
<tr>
<td>
#Html.LabelFor(model => model.Mobile)
#Html.ValidationMessageFor(model => model.Mobile, "", new { #class = "text-danger" })
</td>
<td>
#Html.TextBoxFor(model => model.Mobile)
#Html.ValidationMessageFor(model => model.Mobile, "", new { #class = "text-danger" })
</td>
</tr>
</table>
<input type="submit" value="Create" />
}
<p>
</p>
#Html.ActionLink("Back to List", "Index")
</body>
</html>
I was supposed to get message on the view itself if entered incorrectly but I don't understand what is wrong.
You should pass a model to the create action instead passing several strings. Pass student1 class to the Create action and after that call ModelState.IsValid to check model is valid or not.
public ActionResult Create(student1 student)
{
if(ModelState.IsValid)
{
studentDemoEntities.student1.Add(student);
studentDemoEntities.SaveChanges()
return RedirectToAction("Index");
}
return View(student);
}
you can also check which property is not valid when you call SaveChanges:
if(ModelState.IsValid)
{
studentDemoEntities.student1.Add(stud);
try
{
return studentDemoEntities.SaveChanges();
return RedirectToAction("Index");
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Debug.WriteLine("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
return Index(student);
}
}

error to get value from controller

i try to create new room, but roomTypeID always return 1, whats wrong with my code?
i can make a new room type, but i cant insert room facility in my database, because RoomType ID always return 1
this my code..
my controller
public ActionResult NewRoom()
{
ViewBag.hotel = _hotelService.GetByID(_HotelID).HotelName;
List<ShowEditRoomViewModel> showEditRoomViewModel = _roomTypeService.showNewRooms();
return View(showEditRoomViewModel.FirstOrDefault());
}
[HttpPost]
public ActionResult NewRoom(FormCollection typeRoom)
{
_roomTypeService.NewRoom(_HotelID, typeRoom["RoomTypeName"], typeRoom["RoomTypeDescription"]);
List<string> IDs = typeRoom["FacilityIDs"].Split(',').ToList();
List<int> FacilityIDs = new List<int>();
foreach (string ID in IDs)
{
FacilityIDs.Add(Convert.ToInt32(ID));
}
_roomTypeService.UpdateFacilityInRooms(FacilityIDs, Convert.ToInt32(typeRoom["RoomTypeID"]));
return NewRoom();
}
my service
public void UpdateFacilityInRooms(List<int> FacilityIDs, int RoomTypeID)
{
List<HotelRoomFacility> hotelRoomFacilities = _HotelRoomFacilityRopository.AsQueryable().Where(f => f.RoomTypeID == RoomTypeID).ToList();
foreach (int newRoomFacility in FacilityIDs)
{
if (hotelRoomFacilities.Where(h => h.RoomFacilityID == newRoomFacility).Count() == 0)
{
HotelRoomFacility facility = new HotelRoomFacility
{
RoomFacilityID = newRoomFacility,
RoomTypeID = RoomTypeID
};
_HotelRoomFacilityRopository.Add(facility);
}
}
_HotelRoomFacilityRopository.CommitChanges();
}
my view model
public class ShowEditRoomViewModel
{
public int RoomTypeID { get; set; }
public string RoomTypeName { get; set; }
public string RoomTypeDescription { get; set; }
public List<FaciliyInRoom> facilityinRoom { get; set; }
}
my view
#model XNet.Repository.Model.ShowEditRoomViewModel
#{
ViewBag.Title = "NewRoom";
}
<h2>New Room</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Isikan Data</legend>
<div>
#Html.Label("Hotel Name")
</div>
<div>
#ViewBag.hotel
</div>
<br />
<div>
#Html.HiddenFor(model => model.RoomTypeID)
</div>
<br />
<div>
#Html.Label("Room Type Name")
</div>
<div>
#Html.EditorFor(model => model.RoomTypeName)
#Html.ValidationMessageFor(model => model.RoomTypeName)
</div>
<br />
<div>
#Html.Label("Room Type Description")
</div>
<div>
#Html.TextAreaFor(model => model.RoomTypeDescription)
#Html.ValidationMessageFor(model => model.RoomTypeDescription)
</div>
<br />
<table>
<thead>
<tr>
<th>Facility Name</th>
<th> is available</th>
</tr>
</thead>
<tbody>
#foreach (var facility in Model.facilitiesInRoom)
{
<tr>
<td>
#(facility.RoomFacilityName)
</td>
<td style="text-align:center;">
<input type="checkbox" #(facility.RoomFacilityAvailable ? " checked=checked" : null) name="FacilityIDs" value="#facility.RoomFacilityID" />
</td>
</tr>
}
</tbody>
</table>
<br />
<p>
<input type="submit" value="Save" />
<input style="width:100px;" type="button" title="EditHotelDetail" value="Back to Detail" onclick="location.href='#Url.Action("Room", "Hotel") '" />
</p>
</fieldset>
}
My method
public List<ShowEditRoomViewModel> showNewRooms()
{
List<RoomType> roomTypes = (from d in _RoomTypeRepository.All()
select d).ToList();
List<ShowEditRoomViewModel> showEditRoomViewModel = new List<ShowEditRoomViewModel>();
foreach (RoomType roomType in roomTypes)
{
showEditRoomViewModel.Add(new ShowEditRoomViewModel
{
RoomTypeID = roomType.RoomTypeID,
facilitiesInRoom = LoadFacilityInRoom()
});
}
return showEditRoomViewModel;
}
can someone tell me, where is my mistake??
thanks
When you are inserting RoomtypeId in Database, you are using ExecuteNonQuery() method, It will always return 1 whenever you insert a new record in it,
If you are using stored procedure for inserting,you can use
select Scope_identity()
after insertion.

Resources