I've created a MVC5 App which was generated from my model by scaffold the view and controller,
In the model I have a drop down for dev and prod which is working fine, I have validation
for name for alpha-numeric and the problem is for e.g. user chooses prod (the second
option) and enters incorrect data in the name field and presses enter, the view is refreshed and
the drop down changes the selection from prod to dev. How can I avoid that?
How can I ask in the view if the type is different than dev, if so put the selected item?
Model:
public class Ad
{
public int ID { get; set; }
[RegularExpression(#"^[a-zA-Z0-9]*$", ErrorMessage = "Invalid Name")]
public string Name { get; set; }
public IEnumerable<SelectListItem> Type
{
get
{
return new[]
{
new SelectListItem {Value = "D", Text = "Dev"},
new SelectListItem {Value = "p", Text = "Prod"}
};
}
}
View:
<div class="form-group">
#Html.LabelFor(model => model.SystemType, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Type, Model.Type)
</div>
</div>
Edit the create operation
#model WebApplication3.Models.Ad
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
debugger;
$('select[name="Type"]').change(function () {
if ($(this).val() === 'p') {
$('input[name="User"]').prop("disabled", true);
$('input[name="Password"]').prop("disabled", true);
}
else {
$('input[name="User"]').prop("disabled", false);
$('input[name="Password"]').prop("disabled", false);
}
});
});
</script>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Ad</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Type, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Type, Model.Type)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.User, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.User)
#Html.ValidationMessageFor(model => model.User)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Password, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
public class AdController : Controller
{
private AdDBContext db = new AdDBContext();
public ActionResult Index()
{
return View(db.Ad.ToList());
}
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Ad ad = db.Ad.Find(id);
if (ad == null)
{
return HttpNotFound();
}
return View(ad);
}
public ActionResult Create()
{
return View( new Ad());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="ID,Name,User,Password")] Ad ad)
{
if (ModelState.IsValid)
{
db.Ad.Add(ad);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ad);
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Ad ad = db.Ad.Find(id);
if (ad == null)
{
return HttpNotFound();
}
return View(ad);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Name,User,Password")] Ad ad)
{
if (ModelState.IsValid)
{
db.Entry(ad).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ad);
}
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Ad ad = db.Ad.Find(id);
if (ad == null)
{
return HttpNotFound();
}
return View(ad);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Ad ad = db.Ad.Find(id);
db.Ad.Remove(ad);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
On dropdown change event write the selected option value in a hidden field and when page refreshed get the value from hidden field and set the selected item from the action.
$('select#Type').change(function(){
$('#selectedOne').val($(this).val());
});
and in you action read from FormCollection and set selected item of the SelectList
Create Hidden Field in view:
<div class="form-group">
#Html.LabelFor(model => model.SystemType, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Type, Model.Type)
<input type="hidden" id="selectedOne" vlaue="" name="selectedOne" />
</div>
</div>
In your action:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="ID,Name,User,Password")] Ad ad,FormCollection form)
{
string selectedValue = form["selectedOne"].ToString();
if (ModelState.IsValid)
{
db.Ad.Add(ad);
db.SaveChanges();
return RedirectToAction("Index");
}
foreach(var item in ad.Type)
{
if(item.Value == selectedValue)
{
item.Selected = true;
}
}
return View(ad);
}
Solution 2:
Another simple solution is to use #Ajax.BeginForm Hepler instead of #Html.BeginForm, so that form posted via ajax, and your dropdown will not get reset.
Related
I am working on a library management website. As user of the application, I want to be able to create new employees, for example ceo, manager and regular employee. I have done that and it is working.
But I want to be able to the employees to manage each other depending on their role, for example I want the:
CEO to manage managers but not employees
Managers to manage other managers and employees
No one can manage the CEO
To do that I have tried to map managerID against the id of the employee (I don't know if its a good idea):
public partial class Employees
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] // For autoincrement
//public int EmployeeId { get; set; }
//[Required]
//[Index]
//public int TheManagerId { get; set; } // Manager ID Foreign Key
//[Required]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Nullable<decimal> Salary { get; set; }
public Nullable<bool> IsCEO { get; set; }
public Nullable<bool> IsManager { get; set; }
public Nullable<int> ManagerId { get; set; }
}
And this is how my Create.cshtml looks like:
#model LibraryProject.Employees
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Employees</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Salary, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Salary, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Salary, "Your input should be an integer between 1-10.", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsCEO, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsCEO)
#Html.ValidationMessageFor(model => model.IsCEO, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsManager, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsManager)
#Html.ValidationMessageFor(model => model.IsManager, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ManagerId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ManagerId, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ManagerId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
#using (Html.BeginForm())
{
if (!string.IsNullOrEmpty(ViewBag.ErrorMessage5))
{
<div>
<p>
<span style="color:red;">#ViewBag.ErrorMessage5</span>
</p>
</div>
}
<div class="form-horizontal" />
}
And this is how my Employee controller looks like:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using LibraryProject;
namespace LibraryProject.Controllers
{
public class EmployeesController : Controller
{
private LibraryDbEntities db = new LibraryDbEntities();
// GET: Employees
public ActionResult Index()
{
// Linq queries to show all the employees separately, is used to not mixed them up.
var getCeo = from employeCEO in db.Employees
where employeCEO.IsCEO == true
select employeCEO;
var getEmployee = from employee in db.Employees
where employee.IsCEO == false && employee.IsManager == false
select employee;
var getManager = from employeeManager in db.Employees
where employeeManager.IsManager == true && employeeManager.IsCEO == false
select employeeManager;
IEnumerable<Employees> list = getCeo.Concat(getEmployee).Concat(getManager);
return View(list.ToList());
}
public ActionResult CEO()
{
// linq query used to display ceo in a separate view
var getCeo = from employeCEO in db.Employees
where employeCEO.IsCEO == true
select employeCEO;
return View(getCeo);
}
public ActionResult TheManager()
{
// linq query used to display manager in a separate view
var getManager = from employeeManager in db.Employees
where employeeManager.IsManager == true && employeeManager.IsCEO == false
select employeeManager;
return View(getManager);
}
public ActionResult RegularEmployee()
{
// linq query used to display employee in a separate view
var getEmployee = from employee in db.Employees
where employee.IsCEO == false && employee.IsManager == false
select employee;
return View(getEmployee);
}
// GET: Employees/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Employees employees = db.Employees.Find(id);
if (employees == null)
{
return HttpNotFound();
}
return View(employees);
}
// GET: Employees/Create
public ActionResult Create()
{
ViewBag.Employees = new SelectList(db.Category, "Id", "Employees");
return View();
}
// POST: Employees/Create
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,FirstName,LastName,Salary,IsCEO,IsManager,ManagerId")] Employees employees)
{
if (ModelState.IsValid)
{
//salary coefficient for the employees
decimal salaryCeo = 2.725M;
decimal salaryManager = 1.725M;
decimal employeeSalary = 1.125M;
var ceo = db.Employees.Count(x => x.IsCEO == true);
//Checks if there is a ceo
if (ceo == 0)
{
employees.Salary = employees.Salary * salaryCeo; // calculate ceo salary
db.Employees.Add(employees);
db.SaveChanges();
return RedirectToAction("Index");
}
else if (ceo == 1 && employees.IsCEO == true) // check if there is a ceo, if yes show errormessage
{
ViewBag.ErrorMessage5 = "There is already a CEO in the database! You cannot create a second one!";
}
else if(employees.IsCEO == false && employees.IsManager == false) // check if the employee is ceo or manager, if false its a regular employee
{
employees.Salary = employees.Salary * employeeSalary; // calculate regular employees salary
db.Employees.Add(employees);
db.SaveChanges();
return RedirectToAction("Index");
}
else if (employees.IsCEO == false && employees.IsManager == true) // manager
{
employees.Salary = employees.Salary * salaryManager; // manager salary
db.Employees.Add(employees);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(employees);
}
// GET: Employees/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Employees employees = db.Employees.Find(id);
if (employees == null)
{
return HttpNotFound();
}
return View(employees);
}
// POST: Employees/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,FirstName,LastName,Salary,IsCEO,IsManager,ManagerId")] Employees employees)
{
if (ModelState.IsValid)
{
db.Entry(employees).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(employees);
}
// GET: Employees/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Employees employees = db.Employees.Find(id);
if (employees == null)
{
return HttpNotFound();
}
return View(employees);
}
// POST: Employees/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Employees employees = db.Employees.Find(id);
db.Employees.Remove(employees);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
I KNOW IT IS SOME CODE THERE... BUT I HOPE SOMEONE IS OUT THERE TO HELP.
THANKS.
But I want to be able to the employees to manage each other depending on their role, for example I want the:
CEO to manage managers but not employees
Managers to manage other
managers and employees No one can manage the CEO
I think what you want to achieve is Authorize, not the relationship in table.
For how to Customize a Authorize Attribute, You can refer to this thread.
i've been struggling with Model validation message in asp.net
I've got a model used by a viewmodel.
I want my view to display validation errors if users don't fill required fields.
My ModelState.IsValid is false when required fields are not fill (expected behaviour) but i can't see
any error message
My Model Class :
public class Model
{
[Required(ErrorMessage = "Name is required.")]
public string Name { get; set; }
[Required(ErrorMessage = "Adress is required.")]
public string Adress { get; set; }
}
My ViewModel Class:
public class ViewModel
{
[Required]
public Model SelectedModel { get; set; }
public string Title { get; set;}
}
My Controller:
[HttpPost]
public ActionResult Create(ViewModel vm)
{
try
{
if (ModelState.IsValid)
{
bool result = *DatabaseStuff*
if(result == true)
{
return RedirectToAction("Index");
}
else
{
return View();
}
}
return RedirectToAction("Index",vm);
}
catch
{
return View();
}
}
My View
#model ViewModel
#using (Html.BeginForm("Create", "MyController", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="box box-primary">
<div class="box-header with-border">
<h4 class="box-title">ViewModel Form</h4>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-12">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Title, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Title, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedModel.Name, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.SelectedModel.Name, null, "SelectedModel_Name",new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SelectedModel.Name, "", new { #class = "text-danger", #data_valmsg_for = "SelectedModel_Name" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedModel.Adress, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.SelectedModel.Adress, null, "SelectedModel_Adress",new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SelectedModel.Adress, "", new { #class = "text-danger", #data_valmsg_for = "SelectedModel_Adress" })
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="box-footer">
<input type="submit" value="Create" class="btn btn-success pull-right" />
</div>
</div>
</div>
}
Thanks.
I believe that you should return View when the ModelState is invalid.
Return View doesn't make a new requests, it just renders the view
without changing URLs in the browser's address bar.
Return RedirectToAction makes a new request and the URL in the browser's
address bar is updated with the generated URL by MVC.
try
{
if (ModelState.IsValid)
{
bool result = *DatabaseStuff*
if(result == true)
{
return RedirectToAction("Index");
}
else
{
return View();
}
}
return View();
}
I'm just getting started with MVC. I'm building a project in asp.net mcv 5 using entity framework. I have researched many threads but I didn't find anything that would help solve my problem. I have two models:
Resource:
public class Resource
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Comments { get; set; }
[Required]
public ResourceType Type { get; set; }
public bool IsActive { get; set; }
}
ResourceType:
public class ResourceType
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
And the problem is: In View > Resource > Create I want to add DropDownList for object ResourceType Type with values from class ResourceType string Name
Create.cshtml:
#model NetAudit.Models.Resource
#{
ViewBag.Title = "Create Resource";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Resource</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comments, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Comments, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Type, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
HERE
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsActive, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsActive)
#Html.ValidationMessageFor(model => model.IsActive, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Dodaj" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to list", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
RecourceType controller:
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using NetAudit.Models;
namespace NetAudit.Controllers
{
public class ResourceTypesController : BaseController
{
private readonly ApplicationDbContext _db = new ApplicationDbContext();
[Authorize]
public ActionResult Index()
{
return View(_db.ResourceTypes.ToList());
}
[Authorize]
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var resourceType = _db.ResourceTypes.Find(id);
if (resourceType == null)
{
return HttpNotFound();
}
return View(resourceType);
}
[Authorize]
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ResourceType resourceType)
{
if (ModelState.IsValid)
{
_db.ResourceTypes.Add(resourceType);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(resourceType);
}
[Authorize]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var resourceType = _db.ResourceTypes.Find(id);
if (resourceType == null)
{
return HttpNotFound();
}
return View(resourceType);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ResourceType resourceType)
{
if (ModelState.IsValid)
{
_db.Entry(resourceType).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(resourceType);
}
[Authorize]
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var resourceType = _db.ResourceTypes.Find(id);
if (resourceType == null)
{
return HttpNotFound();
}
return View(resourceType);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
var resourceType = _db.ResourceTypes.Find(id);
if (resourceType == null)
{
return HttpNotFound();
}
_db.ResourceTypes.Remove(resourceType);
_db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_db.Dispose();
}
base.Dispose(disposing);
}
}
}
Resource controller:
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using NetAudit.Models;
namespace NetAudit.Controllers
{
public class ResourceTypesController : BaseController
{
private readonly ApplicationDbContext _db = new ApplicationDbContext();
[Authorize]
public ActionResult Index()
{
return View(_db.ResourceTypes.ToList());
}
[Authorize]
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var resourceType = _db.ResourceTypes.Find(id);
if (resourceType == null)
{
return HttpNotFound();
}
return View(resourceType);
}
[Authorize]
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ResourceType resourceType)
{
if (ModelState.IsValid)
{
_db.ResourceTypes.Add(resourceType);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(resourceType);
}
[Authorize]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var resourceType = _db.ResourceTypes.Find(id);
if (resourceType == null)
{
return HttpNotFound();
}
return View(resourceType);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ResourceType resourceType)
{
if (ModelState.IsValid)
{
_db.Entry(resourceType).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(resourceType);
}
[Authorize]
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var resourceType = _db.ResourceTypes.Find(id);
if (resourceType == null)
{
return HttpNotFound();
}
return View(resourceType);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
var resourceType = _db.ResourceTypes.Find(id);
if (resourceType == null)
{
return HttpNotFound();
}
_db.ResourceTypes.Remove(resourceType);
_db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_db.Dispose();
}
base.Dispose(disposing);
}
}
}
I spent a lot of time looking for a solution to this problem. I would appreciate your feedback on this.
I think the best way to get what you want is to create a ViewModel, this allows you create a view with various classes.
Under your solution create a new folder named ViewModels. Create a new class and name it CreateResourceViewModel.
public class CreateResourceViewModel
{
public Resource Resource {get;set;}
public SelectList ResourceType {get;set;} //this will create the list of resourcetypes
public int IdResourceType {get;set;} //this will be used to select the id of resourceType you are selecting.
public CreateResourceViewModel (Resource resource,List<ResourceType>resourceType) //create a constructor
{
this.Resource = resource;
//here you will set the list as a new selectList, stating where the list will come from. the Id de valuevaluefield, and the name is the valuetextfield
this.ResourceType= new SelectList(resourceType,"Id","Name");
}
public CreateResourceViewModel(){} //you need this second constructor
}
Now you need a Create ActionResult that accepts a ViewModel in your resource Controller
// GET: Locals/Create
public ActionResult Create()
{
Resource resource = new Resource();
List<ResourceType> resourceType;
using (yourcontext db = new yourcontext())
{
resourceType = db.ResourceType.ToList(); //fill your list with the resourceTypes that are in your database
}
CreateResourceViewModel vm = new CreateResourceViewModel(resource,resourceType); //create a new viewmodel and give it the parameters necesary that we created
return View(vm);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CreateResourceViewModel vm)
{
using (yourcontext db = new yourcontext())
{
if (ModelState.IsValid)
{
try {
vm.Resource.Type = db.ResourceTpe.Find(vm.IdResourceType); //using the ID selected in the view find it in the database
db.Resources.Add(vm.Resource);
db.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception e)
{
e.Message();
}
}
return View(vm);
}
}
Now onto the view for the ViewModel
#model yourSolution.ViewModels.CreateResourceViewModel
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Resource</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comments, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Comments, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ResourceType, htmlAttributes: new { #class = "control-label col-md-2" })
//this is what you need to create a dropdownlist with all the resourceTypes
<div class="col-md-10">
#Html.DropDownListFor(model => model.IdResourceType, Model.ResourceType,"--Select--" )
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsActive, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsActive)
#Html.ValidationMessageFor(model => model.IsActive, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Dodaj" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to list", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Hope this helps!!
First of you have a mistake to put Resource Controller here (both of Resource and ResourceType are ResourceType). fix it first.
Put in the Here section this code to render a select element from ViewBag.Types:
#Html.DropDownListFor(m => m.Type.Id, (SelectList)ViewBag.Types, new
{
#class = "form-control"
});
Before it you must fill ViewBag.Types in the action, Change the first Create action of ResourceController to this:
[Authorize]
public ActionResult Create()
{
ViewBag.Types = new SelectList(_db.ResourceTypes.ToList(), "Id", "Name", "0");
return View();
}
It will be worked.
I'm trying to create a dropdown on my View that populates all the usernames specified in a different table.
I've tried the tuple route but it doesn't seem to be working for me.
Also looked into adding a model containing both models (Users and Tasks)
View
#model Tuple<Task,User>
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Task</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Item1.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Item1.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Item1.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Item1.Details, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Item1.Details, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Item1.Details, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Item1.StartDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Item1.StartDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Item1.StartDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Item1.EndDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Item1.EndDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Item1.EndDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Item1.AssignedTo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor()
#Html.ValidationMessageFor(model => model.Item1.AssignedTo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Controller
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Base.Models;
using PagedList;
namespace Base.Controllers
{
public class UsersController : Controller {
private WebDBEntities db = new WebDBEntities();
// GET: Users
public ActionResult Index(string sortOrder,string currentFilter, string searchString,int? page) {
ViewBag.NameSortParam = string.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.SurnameSortParam = sortOrder == "Surname" ? "surname_desc" : "Surname";
ViewBag.TeamSortParam = sortOrder == "Team" ? "team_desc" : "Team";
if(searchString != null) {
page = 1;
} else {
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var users = from u in db.Users select u;
if (!string.IsNullOrEmpty(searchString)) {
users = users.Where(u => u.Name.Contains(searchString) || u.Surname.Contains(searchString));
}
switch (sortOrder) {
case "name_desc":
users = users.OrderByDescending(u => u.Name);
break;
case "Team":
users = users.OrderBy(u => u.Team);
break;
case "team_desc":
users = users.OrderByDescending(u => u.Team);
break;
case "Surname":
users = users.OrderBy(u => u.Surname);
break;
case "surname_desc":
users = users.OrderByDescending(u => u.Surname);
break;
default:
users = users.OrderBy(u => u.Name);
break;
}
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(users.ToPagedList(pageNumber,pageSize));
}
// GET: Users/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
// GET: Users/Create
public ActionResult Create()
{
return View();
}
// POST: Users/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Name,Surname,Team,UserName")] User user)
{
if (ModelState.IsValid)
{
user.UserName = string.Format("{0}{1}", user.Name.Substring(0, 1), user.Surname);
db.Users.Add(user);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
// GET: Users/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
// POST: Users/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID,Name,Surname,Team,UserName")] User user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
// GET: Users/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
// POST: Users/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
User user = db.Users.Find(id);
db.Users.Remove(user);
db.SaveChanges();
return RedirectToAction("Index");
}
public ActionResult ViewUserTasks(string Username) {
return View("UserTasks",db.Tasks.Where(uu => uu.AssignedTo == Username));
}
public ActionResult GetAllUsers() {
List<string> users = new List<string>();
foreach (var item in db.Users) {
users.Add(item.UserName.ToString())
}
return View(users);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Any assistance would be great, thanks in advance.
I have the following create view
#model Inspinia_MVC5.Areas.GlobalAdmin.Models.Propiedad
#{
ViewBag.Title = "Create";
Layout = "~/Areas/GlobalAdmin/Views/Shared/_LayoutGlobalAdmin.cshtml";
}
<div class="row wrapper border-bottom white-bg page-heading">
<div class="col-sm-4">
<h2>Create</h2>
<ol class="breadcrumb">
<li>
#Html.ActionLink("List", "Index")
</li>
<li class="active">
<strong>Create</strong>
</li>
</ol>
</div>
<div class="col-sm-8">
<div class="title-action">
#Html.ActionLink("Back to List", "Index", null, new { #class = "btn btn-primary"})
</div>
</div>
</div>
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Create Propiedad</h5>
</div>
<div class="ibox-content">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Entidad, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Entidades", (IEnumerable<SelectListItem>)ViewData["Entidades"], new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Codigo, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Codigo)
#Html.ValidationMessageFor(model => model.Codigo)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Nombre, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Nombre)
#Html.ValidationMessageFor(model => model.Nombre)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TipoDeDatos, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TipoDeDatos)
#Html.ValidationMessageFor(model => model.TipoDeDatos)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-primary" />
#Html.ActionLink("Cancel", "Index", null, new { #class = "btn btn-white"})
</div>
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
and I have this controller
public class PropiedadesController : Controller
{
private AppDataContext db = new AppDataContext();
public ActionResult SelectCategory()
{
List<SelectListItem> items = new List<SelectListItem>();
foreach(Entidad entidad in db.Entidades.ToList())
{
items.Add(new SelectListItem { Text = entidad.Nombre, Value = entidad.Id.ToString() });
}
ViewBag.Entidades = items;
return View();
}
// GET: /GlobalAdmin/Propiedades/
public ActionResult Index()
{
return View(db.Propiedades.ToList());
}
// GET: /GlobalAdmin/Propiedades/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Propiedad propiedad = db.Propiedades.Find(id);
if (propiedad == null)
{
return HttpNotFound();
}
return View(propiedad);
}
// GET: /GlobalAdmin/Propiedades/Create
public ActionResult Create()
{
AppDataContext db = new AppDataContext();
var entidades = from c in db.Entidades select c;
List<SelectListItem> items = new List<SelectListItem>();
foreach (Entidad entidad in entidades)
{
items.Add(new SelectListItem { Text = entidad.Nombre, Value = entidad.Id.ToString() });
}
ViewBag.Entidades = items;
return View();
}
// POST: /GlobalAdmin/Propiedades/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="Id,Codigo,Nombre,TipoDeDatos")] Propiedad propiedad)
{
if (ModelState.IsValid)
{
db.Propiedades.Add(propiedad);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(propiedad);
}
// GET: /GlobalAdmin/Propiedades/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
AppDataContext db = new AppDataContext();
var entidades = from c in db.Entidades select c;
List<SelectListItem> items = new List<SelectListItem>();
foreach (Entidad entidad in entidades)
{
items.Add(new SelectListItem { Text = entidad.Nombre, Value = entidad.Id.ToString() });
}
ViewBag.Entidades = items;
Propiedad propiedad = db.Propiedades.Find(id);
if (propiedad == null)
{
return HttpNotFound();
}
return View(propiedad);
}
// POST: /GlobalAdmin/Propiedades/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="Id,Codigo,Nombre,TipoDeDatos")] Propiedad propiedad)
{
if (ModelState.IsValid)
{
db.Entry(propiedad).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(propiedad);
}
// GET: /GlobalAdmin/Propiedades/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Propiedad propiedad = db.Propiedades.Find(id);
if (propiedad == null)
{
return HttpNotFound();
}
return View(propiedad);
}
// POST: /GlobalAdmin/Propiedades/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Propiedad propiedad = db.Propiedades.Find(id);
db.Propiedades.Remove(propiedad);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
However when I created a row, the database shows the foreign KEY as null (Entidad ID)
What am I missing here?
Propiedad Model is this
public class Propiedad
{
[Key]
public int Id { get; set; }
public virtual Entidad Entidad { get; set; }
public string Codigo { get; set; }
public string Nombre { get; set; }
public string TipoDeDatos { get; set; }
}
Screenshot
http://screencast.com/t/B5m6X8mtbSdd
Update 1: I modified the controller like this:
public ActionResult Create()
{
ViewBag.Entidad = new SelectList(db.Entidades, "Id", "Nombre");
return View();
}
and the view like this:
<div class="form-group">
#Html.LabelFor(model => model.Entidad, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Entidad.Id, new SelectList(ViewBag.Entidad, "Id", "Nombre", Model.Entidad.Id), "Seleccionar", new { #class = "form-control" })
</div>
</div>
However on the view I get an object reference not set to an instance of an object.
This is the entity model
public class Entidad
{
[Key]
public int Id { get; set; }
public string Nombre { get; set; }
public virtual ICollection<Propiedad> Propiedades { get; set; }
}
and the property model
public class Propiedad
{
[Key]
public int Id { get; set; }
public virtual Entidad Entidad { get; set; }
public string Codigo { get; set; }
public string Nombre { get; set; }
public string TipoDeDatos { get; set; }
}
I don't see where print the dropdownlist in your view.
Well try this:
In your controller load the list:
ViewBag.entities = new SelectList(db.Entidades, "Id", "Nombre") ;
And then in your view inside the form:
#Html.DropDownListFor(model => model.Entidad.Id, (SelectList) ViewBag.entities, "Seleccionar")
Model equivalent a your class: Propiedad
With this you will automatically receive the object with the selected value.