So many People like to do Insert/Update/Delete in single View i.e. similar to asp.net. But asp.net MVC default it does not support this approach. We can achieve this functionality like this
Step 1:
Create the blank application like this
Step 2: Create the database table like this
Step 3: In model layer, create the model using EF database first approach like this
Step 4: Now create a blank Emp controller like this
Step 5: Add a class i.e HttpParamActionAttribute in solution like this
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Web; using System.Web.Mvc; namespace EmpDemoInMVC { public class HttpParamActionAttribute : ActionNameSelectorAttribute { public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) { if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase)) return true; var request = controllerContext.RequestContext.HttpContext.Request; return request[methodInfo.Name] != null; } } }
Note: We are writing this class to fire the multiple Submit button events from single view.
Step 6: Write the Action Method in Controller for Insert/Update/Delete and fetch functionalities like this
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using EmpDemoInMVC.Models; using System.Data.Entity; namespace EmpDemoInMVC.Controllers { public class EmpController : Controller { EmpEntities db = new EmpEntities(); // // GET: /Emp/ public ActionResult Index(int? id) { ViewBag.Operation = id; ViewBag.Name = db.tblEmps.ToList(); tblEmp objEmp = db.tblEmps.Find(id); return View(objEmp); } [HttpPost] [HttpParamAction] [ValidateAntiForgeryToken] public ActionResult Create(tblEmp objEmp) { if (ModelState.IsValid) { db.tblEmps.Add(objEmp); db.SaveChanges(); } return RedirectToAction("Index"); } [HttpPost] [HttpParamAction] [ValidateAntiForgeryToken] public ActionResult Update(tblEmp objEmp) { if (ModelState.IsValid) { db.Entry(objEmp).State = EntityState.Modified; db.SaveChanges(); } return RedirectToAction("Index", new { id = 0 }); } public ActionResult Delete(int id) { tblEmp objEmp = db.tblEmps.Find(id); db.tblEmps.Remove(objEmp); db.SaveChanges(); return RedirectToAction("Index", new { id = 0 }); } } }
Step 7: Create the Empty View from controller like this
Step 8: Now write the html code as per as our requirement like this
@model EmpDemoInMVC.Models.tblEmp @{ ViewBag.Title = "Index"; } <h2>Index</h2> @using (Html.BeginForm()) { // This is For EmpDetail in Grid <fieldset> <legend><b>Emp Details</b></legend> <table border="1" cellpadding="10"> <tr> <th> @Html.DisplayNameFor(model => model.Name) </th> <th> @Html.DisplayNameFor(model => model.Address) </th> <th> @Html.DisplayNameFor(model => model.EmailId) </th> <th> @Html.DisplayNameFor(model => model.MobileNo) </th> <th> @Html.DisplayNameFor(model => model.Country) </th> <th> Action </th> </tr> @foreach (var item in (IEnumerable<EmpDemoInMVC.Models.tblEmp>)ViewBag.Name) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Address) </td> <td> @Html.DisplayFor(modelItem => item.EmailId) </td> <td> @Html.DisplayFor(modelItem => item.MobileNo) </td> <td> @Html.DisplayFor(modelItem => item.Country) </td> <td> @Html.ActionLink("Edit", "Index", new { id = item.Id }) | @Html.ActionLink("Delete", "Delete",new { id = item.Id },new { onclick = "return confirm('Are you sure you wish to delete this article?');" }) </td> </tr> } </table> </fieldset> // This is for the Emp Entry Screen @Html.AntiForgeryToken() <div class="form-horizontal"> @Html.ValidationSummary(true) <fieldset> <legend> <b>Entry Screen</b></legend> <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.Address, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Address) @Html.ValidationMessageFor(model => model.Address) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.EmailId, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.EmailId) @Html.ValidationMessageFor(model => model.EmailId) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.MobileNo, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.MobileNo) @Html.ValidationMessageFor(model => model.MobileNo) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Country, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Country) @Html.ValidationMessageFor(model => model.Country) </div> </div> <div class="form-group"> <p> <input type="submit" value="Create" name="Create" style=@((ViewBag.Operation != null && Convert.ToInt32(ViewBag.Operation) > 0) ? "display:none" : "display:block") /> <input type="submit" value="Update" name="Update" style=@((ViewBag.Operation != null && Convert.ToInt32(ViewBag.Operation) > 0) ? "display:block" : "display:none") /> </p> </div> </fieldset> </div> }
Summary:
In this article we show that we are using only one view for doing Insert/Update/Delete and Fetch function. If you like to implement entry screen similar to asp.net style you can use this approach.
I have created same way but validation message(Html.ValidationMessageFor is not working) is not showing.
Could you please share your complete code. You might have missed out to add this code in down of the html page.
@section Scripts {
@Scripts.Render(“~/bundles/jqueryval”)
}
my code is not working
i have created it using 2013..@model MyMVC2.Models.mvc_employee
@{
ViewBag.Title = “Index”;
}
Index
@Html.AntiForgeryToken()
@using (Html.BeginForm())
{
// This is For EmpDetail in Grid
Emp Details
@Html.DisplayNameFor(model => model.name)
@Html.DisplayNameFor(model => model.email)
@Html.DisplayNameFor(model => model.mobile)
@Html.DisplayNameFor(model => model.province)
Action
@foreach (var item in (IEnumerable)ViewBag.employee)
{
@Html.DisplayFor(modelItem => item.name)
@Html.DisplayFor(modelItem => item.email)
@Html.DisplayFor(modelItem => item.mobile)
@Html.DisplayFor(modelItem => item.province)
@Html.ActionLink(“Edit”, “Index”, new { id = item.empID })
}
// This is for the Emp Entry Screen
@Html.ValidationSummary(true)
Entry Screen
@Html.LabelFor(model => model.name, new { @class = “control-label col-md-2” })
@Html.EditorFor(model => model.name)
@Html.ValidationMessageFor(model => model.name)
@Html.LabelFor(model => model.email, new { @class = “control-label col-md-2” })
@Html.EditorFor(model => model.email)
@Html.ValidationMessageFor(model => model.email)
@Html.LabelFor(model => model.mobile, new { @class = “control-label col-md-2” })
@Html.EditorFor(model => model.mobile)
@Html.ValidationMessageFor(model => model.mobile)
@Html.LabelFor(model => model.province, new { @class = “control-label col-md-2” })
@Html.EditorFor(model => model.province)
@Html.ValidationMessageFor(model => model.province)
0) ? “display:none” : “display:block”) />
0) ? “display:block” : “display:none”) />
}
there is an error that says Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type ‘System.Collections.Generic.List`1[MyMVC2.Models.mvc_employee]’, but this dictionary requires a model item of type ‘MyMVC2.Models.mvc_employee’
I dont know where that is happening, but i have used the same code it differs with that i have used the Stored procedures. Any help plz
Thanks for sharing