MvC multiple submits diffrent columns same row - asp.net-mvc-4

So this is the code, i have 2 submit buttons when i press "Start" I want it to send the Datetime.now to the start row, and when i press "Stop" i want it to send the Stop datetime.now to the column, this should be happening in the same row. And when i press Start again it should generate a new ID 2, etc. print the start date on the second row.
Exampel ID 1 : Start 2013-11-15 05:12 Slut : 2013-11-15 05:15
Greetings Patrik
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.Start)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Start, new { style = "display: none;", #Value = #DateTime.Now })
#Html.ValidationMessageFor(model => model.Start)
</div>
<p>
<input type="submit" name="#Html.NameFor(x => x.Command)" value="Start" formaction="/tider/create" />
</p>
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.Slut)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Slut, new { #Value = #DateTime.Now })
#Html.ValidationMessageFor(model => model.Slut)
</div>
<p>
<input type="submit" name="#Html.NameFor(x => x.Command)" value="Stop" />
</p>
}
</fieldset>
<div class="editor-label">
#Html.LabelFor(model => model.Slut)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Slut, new { #Value = #DateTime.Now })
#Html.ValidationMessageFor(model => model.Slut)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
controller
{
public class TiderController : Controller
{
private TiderDBContext db = new TiderDBContext();
//
// GET: /Tider/
public ActionResult Index()
{
return View(db.Tider.ToList());
}
//
// GET: /Tider/Details/5
public ActionResult Details(int id = 0)
{
ArbetsTider arbetstider = db.Tider.Find(id);
if (arbetstider == null)
{
return HttpNotFound();
}
return View(arbetstider);
}
//
// GET: /Tider/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Tider/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ArbetsTider arbetstider)
{
if (ModelState.IsValid)
{
db.Tider.Add(arbetstider);
db.SaveChanges();
}
return View(arbetstider);
}
//
// GET: /Tider/Edit/5
public ActionResult Edit(int id = 0)
{
ArbetsTider arbetstider = db.Tider.Find(id);
if (arbetstider == null)
{
return HttpNotFound();
}
return View(arbetstider);
}
//
// POST: /Tider/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ArbetsTider arbetstider)
{
if (ModelState.IsValid)
{
db.Entry(arbetstider).State = EntityState.Modified;
return RedirectToAction("Index");
}
return View(arbetstider);
}
//
// GET: /Tider/Delete/5
public ActionResult Delete(int id = 0)
{
ArbetsTider arbetstider = db.Tider.Find(id);
if (arbetstider == null)
{
return HttpNotFound();
}
return View(arbetstider);
}
//
// POST: /Tider/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
ArbetsTider arbetstider = db.Tider.Find(id);
db.Tider.Remove(arbetstider);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
[HttpPost]
public ActionResult Start(ArbetsTider model)
{
using (var context = new TiderDBContext())
{
context.Tider.FirstOrDefault(x => x.ID == model.ID).Start = model.Start;
context.SaveChanges();
}
return View("Index");
}
[HttpPost]
public ActionResult Stop(ArbetsTider model)
{
using (var context = new TiderDBContext())
{
context.Tider.FirstOrDefault(x => x.ID == model.ID).Slut = model.Slut;
context.SaveChanges();
}
return View("Index");
}
}
}
model
public class ArbetsTider
{
public int ID { get; set; }
public DateTime Start { get; set; }
public DateTime Slut { get; set; }
}
public class TiderDBContext : DbContext
{
public DbSet<ArbetsTider> Tider { get; set; }
}

You need to use Ajax method to submit the one form partially without refreshing the whole page.
Try something like this:
First change like this(remove type='submit'):
#using (Html.BeginForm("Create", "Tider", FormMethod.Post, new { #id= "formStart" } ))
{
// html code
<input id="submittStartDate" name="#Html.NameFor(x => x.Command)" value="Start" class="submitButton" />
});
And
#using (Html.BeginForm("Stop", "Tider", FormMethod.Post, new { #id= "formStop" } ))
{
//html
<input id="stop" name="#Html.NameFor(x => x.Command)" value="Stop" class="submitButton" />
//html
});
Then add a function in javascript file:
$(document).ready(function () {
$("input.submitButton").click(function() {
SubmitForm(this);
});
});
function SubmitForm(input) {
var url = "";
var formData = "";
if(input[0].id == "formStart")
{
url = "../Tider/Create";
data = $('form#formStart').serialize();
}
else if(input[0].id == "formStop") {
url = "../Tider/Stop";
data = $('form#formStop').serialize();
}
$.ajax({
type: "POST",
url: url,
data: data,
success: function (result) {
// Do your stuff here
},
error: function () {
alert("Error in saving");
}
});
}
You need to change the return types of the C# methods Create and Stop to required type(I think you need int here) and retun that. And you will get the data "success" function of the Ajax call.

Related

I wanted to perform crud operations for Admin Panel of an ecommerce project but not able to edit image gallery in asp.net core

ProductModel class file
public class ProductModel
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string ProductDesc { get; set; }
public string Image { get; set; }
public IFormFile Img { get; set; }
public IFormFileCollection GalleryImages { get; set; }
public List<ProductGalleryModel> ProductGallery { get;set;}
}
ProductGalleryModel class file
public class ProductGalleryModel
{
public int ID { get; set; }
public int ProductId { get; set; }
public string Name { get; set; }
public string URL { get; set; }
public IFormFileCollection GalleryImages { get; set; }
public List<ProductGalleryModel> ProductGallery { get; set; }
}
ProductController class file
public class ProductController : Controller
{
private readonly IProductRepository _productRepository = null;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public async Task<IActionResult> AddNewProduct(bool isSuccess = false, int prodId = 0)
{
ViewBag.Categories = new SelectList(await _categoryRepository.GetAllCategories(), "CatID", "CategoryName");
ViewBag.IsSuccess = isSuccess;
ViewBag.ProductID = prodId;
return View();
}
[HttpPost]
public async Task<IActionResult> AddNewProduct(ProductModel productModel)
{
if (ModelState.IsValid)
{
if (productModel.Img1 != null)
{
string folder = "images/product/cover/";
productModel.Image1 = await UploadImage(folder, productModel.Img1);
}
if (productModel.GalleryImages != null)
{
string folder = "images/product/cover/gallery/";
productModel.ProductGallery = new List<ProductGalleryModel>();
foreach (var file in productModel.GalleryImages)
{
var gallery = new ProductGalleryModel()
{
Name = file.FileName,
URL = await UploadImage(folder, file)
};
productModel.ProductGallery.Add(gallery);
}
}
var id = await _productRepository.AddProduct(productModel);
if (id > 0)
{
return RedirectToAction(nameof(AddNewProduct), new { isSuccess = true, prodId = id });
}
}
ViewBag.Categories = new SelectList(await _categoryRepository.GetAllCategories(), "CatID", "CategoryName");
return View();
}
private async Task<string> UploadImage(string folderPath, IFormFile file)
{
folderPath += Guid.NewGuid().ToString() + "_" + file.FileName;
string serverfolderpath = Path.Combine(_webHostEnvironment.WebRootPath, folderPath);
await file.CopyToAsync(new FileStream(serverfolderpath, FileMode.Create));
return "/" + folderPath;
}
public async Task<IActionResult> GetProductGallery(int id)
{
var data = await _productRepository.GetProductById(id);
return View(data);
}
public async Task<IActionResult> EditProductGallery (int id, bool isSuccess = false)
{
ViewBag.IsSuccess = isSuccess;
ViewBag.ProductID = id;
var ListOfProducts = await _productRepository.GetProductById(id);
ViewData["ProductGallery"] = ListOfProducts.ProductGallery;
return View(ListOfProducts);
}
public async Task<PartialViewResult> RenderProduct(int id)
{
var ListOfProducts = await _productRepository.GetProductById(id);
ViewData["ProductGallery"] = ListOfProducts.ProductGallery;
return PartialView(ListOfProducts);
}
public async Task<PartialViewResult> RenderProductGallery(int id)
{
var ListOfProducts = await _productRepository.getProductGallery(id);
ViewData["ProductId"] = ListOfProducts.ProductGallery;
return PartialView(ListOfProducts);
}
[HttpPost]
public async Task<IActionResult> EditProductGallery(ProductGalleryModel productGalleryModel)
{
if (ModelState.IsValid)
{
if (productGalleryModel.URL != null)
{
if (productGalleryModel.GalleryImages != null)
{
string fileName = Path.GetFileName(productGalleryModel.GalleryImages.ToString());
string filePath = Path.Combine(_webHostEnvironment.WebRootPath, fileName);
System.IO.File.Delete(filePath);
string folder = "images/product/cover/gallery/";
productGalleryModel.ProductGallery = new List<ProductGalleryModel>();
foreach (var file in productGalleryModel.GalleryImages)
{
var gallery = new ProductGalleryModel()
{
Name = file.FileName,
URL = await UploadImage(folder, file)
};
productGalleryModel.ProductGallery.Add(gallery);
}
await _productRepository.UpdateProductGallery(productGalleryModel.ID, productGalleryModel);
}
}
return RedirectToAction("GetAllProducts", new { isSuccess = true, ViewBag.ProductID });
}
return View();
}
}
}
ProductRepository for all get and edit methods
public class ProductRepository : IProductRepository
{
public async Task<ProductGalleryModel> getProductGallery(int id)
{
var result = await _prcContext.tblProductGalleries.Where(x => x.ProductsProductID == id).
Select(getgallerybyid => new ProductGalleryModel()
{
URL = getgallerybyid.URL,
}).FirstOrDefaultAsync();
return result;
}
public async Task<ProductModel> GetProductById(int id)
{
return await _prcContext.tblProducts.Where(x => x.ProductID == id).
Select(getproductbyId => new ProductModel()
{
ProductID = getproductbyId.ProductID,
ProductName = getproductbyId.ProductName,
ProductDesc = getproductbyId.ProductDesc,
Image1 = getproductbyId.Image1,
Image2 = getproductbyId.Image2,
Image3 = getproductbyId.Image3,
Image4 = getproductbyId.Image4,
OldPrice = getproductbyId.OldPrice,
NewPrice = getproductbyId.NewPrice,
Discount = getproductbyId.Discount,
CategoryId = getproductbyId.CategoryId,
ProductGallery = getproductbyId.productGallery.Select(g => new ProductGalleryModel()
{
ID = g.GalleryID,
ProductId = g.ProductsProductID,
Name = g.Name,
URL= g.URL
}).ToList()
}).FirstOrDefaultAsync();
}
public async Task<ProductModel> UpdateProduct(int id, ProductModel productModel)
{
var updateProduct = await _prcContext.tblProducts.FirstOrDefaultAsync(x => x.ProductID == id);
if (updateProduct != null)
{
updateProduct.ProductName = productModel.ProductName;
updateProduct.ProductDesc = productModel.ProductDesc;
updateProduct.Image1 = productModel.Image1;
updateProduct.Image2 = productModel.Image2;
updateProduct.Image3 = productModel.Image3;
updateProduct.Image4 = productModel.Image4;
updateProduct.OldPrice = productModel.OldPrice;
updateProduct.NewPrice = productModel.NewPrice;
updateProduct.Discount = productModel.Discount;
updateProduct.CategoryId = productModel.CategoryId;
}
await _prcContext.SaveChangesAsync();
return productModel;
}
public async Task<ProductGalleryModel> UpdateProductGallery(int id, ProductGalleryModel productGalleryModel)
{
var updateProductGallery = await _prcContext.tblProductGalleries.FirstOrDefaultAsync(x => x.ProductsProductID == id);
if (updateProductGallery != null)
{
var newproduct = new List<tblProductGallery>();
foreach (var gallery in newproduct)
{
updateProductGallery.URL = productGalleryModel.URL;
}
await _prcContext.SaveChangesAsync();
}
return productGalleryModel;
}
}
Edit Product Gallery View file
#model ProductGalleryModel
#{
ViewData["Title"] = "Edit Product Gallery";
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}
<style>
.img-fluid {
width: 250px;
height: 250px;
}
</style>
<div class="">
<!-- Content Header (Page header) -->
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-md-6">
<h1>Edit Product Gallery</h1>
</div>
<div class="col-md-6">
<ol class="breadcrumb float-md-right">
<li class="breadcrumb-item"><a asp-action="Index" asp-controller="Home">Home</a></li>
<li class="breadcrumb-item"><a asp-action="GetAllProducts" asp-controller="Product">Products</a></li>
<li class="breadcrumb-item active">Edit Product Gallery</li>
</ol>
</div>
</div>
</div><!-- /.container-fluid -->
</section>
<section class="content">
<div class="container-fluid">
<div class="card card-primary py-2">
<div class="card-header">
<h3 class="card-title">Existing Gallery</h3>
</div>
<div class="card-body">
<div class="row">
<input type="hidden" value="#ViewData["ProductGallery"]" />
<partial name="~/Areas/Admin/Views/RenderProduct.cshtml"
view-data="ViewData" />
</div>
</div>
</div>
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Update Gallery</h3>
</div>
<form method="post" enctype="multipart/form-data" asp-action="EditProductGallery" asp-controller="Product">
<div class="card-body">
<div class="row">
<partial name="~/Areas/Admin/Views/RenderProductGallery.cshtml" view-data="ViewData" />
<div class="">
</div>
</div>
<div class="card-footer">
<input type="submit" value="Update" class="btn btn-success" />
</div>
</form>
</div>
</div>
</section>
</div>
#section Scripts
{
<script>
$(document).ready(function () {
$('.custom-file-input').on("change", function () {
var filename = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(filename);
});
});
</script>
}
Product PartialView
#model ProductModel
<div class="col-sm-3">
<img src="#Model.Image1" class="img-fluid mb-2" alt="white sample" />
</div>
#for (int i = 0; i < Model.ProductGallery.Count(); i++)
{
<div class="col-sm-3">
<img src="#Model.ProductGallery[i].URL" class="img-fluid mb-2" alt="white sample" />
</div>
}
Product Gallery PartialView
model ProductGalleryModel
#{
ViewData["ProductGallery"] = true;
}
<div class="">
<input type="hidden" value="#Model.ProductId" />
#*<input type="hidden" value="#Model.ProductGallery" />*#
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="GalleryImages"></label>
<div class="custom-file">
<input asp-for="GalleryImages" class="custom-file-input" id="inputGroupFile01">
<label class="custom-file-label" for="inputGroupFile01">Choose file</label>
</div>
<span asp-validation-for="GalleryImages" class="text-danger"></span>
</div>
</div>
#section Scripts
{
<script>
$(document).ready(function () {
$('.custom-file-input').on("change", function () {
var filename = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(filename);
});
});
</script>
}
I am able to return the ProductPartialView with desired results but when i am calling the ProductGalleryPartialView then i am getting an Exception: The model item passed into the ViewDataDictionary is of type 'PRC_webapp.Areas.Admin.Models.ProductModel', but this ViewDataDictionary instance requires a model item of type 'PRC_webapp.Areas.Admin.Models.ProductGalleryModel'.
public IActionResult Index()
{
return View(_context.students);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(student student)
{
if (!ModelState.IsValid)
{
return View();
}
student.Image = await student.Photo.SaveFileAsync(_env.WebRootPath, "images");
await _context.students.AddAsync(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public async Task<IActionResult> Update(int? id)
{
if (id == null)
{
return BadRequest();
}
var student = await _context.students.FindAsync(id);
if (student == null)
{
return NotFound();
}
return View(student);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Update(int? id, student newstudent)
{
if (id == null)
{
return BadRequest();
}
var oldstudent = _context.students.Find(id);
if (oldstudent == null)
{
return NotFound();
}
if (!ModelState.IsValid)
{
return View();
}
var path = Helper.GetPath(_env.WebRootPath, "img", oldstudent.Image);
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
newstudent.Image = await newstudent.Photo.SaveFileAsync(_environment.WebRootPath, "images");
oldstudent.Image = newstudent.Image;
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
public async Task<IActionResult> Delete(int id)
{
if (id == null)
{
return BadRequest();
}
var student = _context.students.Find(id);
if (student == null)
{
return NotFound();
}
var path = Helper.GetPath(_environment.WebRootPath, "img", student.Image);
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
_context.students.Remove(student);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}

i would like to populate one drop down list using another drop down list

i tried a code from a video and got an error :
This is the Error when i click my drop down to display the states from country
this is my controller code:
public ActionResult Submit()
{
List<Country> allCountry = new List<Country>();
List<State> allState = new List<State>();
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
allCountry = dc.Countries.OrderBy(a => a.CountryName).ToList();
}
ViewBag.CountryID = new SelectList(allCountry, "CountryID", "CountryName");
ViewBag.StateID = new SelectList(allState, "StateID", "StateName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken] // this is for prevent CSRF Attack
public ActionResult Submit(Feedback fb)
{
List<Country> allCountry = new List<Country>();
List<State> allState = new List<State>();
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
allCountry = dc.Countries.OrderBy(a => a.CountryName).ToList();
if (fb != null && fb.CountryID > 0)
{
allState = dc.States.Where(a => a.CountryID.Equals(fb.CountryID)).OrderBy(a => a.StateName).ToList();
}
}
ViewBag.CountryID = new SelectList(allCountry, "CountryID", "CountryName", fb.CountryID);
ViewBag.StateID = new SelectList(allState, "StateID", "StateName", fb.StateID);
if (ModelState.IsValid)
{
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
dc.Feedbacks.Add(fb);
dc.SaveChanges();
ModelState.Clear();
fb = null;
ViewBag.Message = "Successfully submitted";
}
}
else
{
ViewBag.Message = "Failed! Please try again";
}
return View(fb);
}
[HttpGet]
public JsonResult GetStates(string countryID = "")
{
List<State> allState = new List<State>();
int ID = 0;
if (int.TryParse(countryID, out ID))
{
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
allState = dc.States.Where(a => a.CountryID.Equals(ID)).OrderBy(a => a.StateName).ToList();
//allState = dc.States.Where(a => a.CountryID.Equals(ID)).OrderBy(a => a.StateName).ToList();
}
}
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = allState,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
return new JsonResult
{
Data = "Not valid request",
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
}
}
this is my model code :
public partial class Feedback
{
public int FeedbackID { get; set; }
[Display(Name = "Full Name")]
[Required(ErrorMessage = "Please provide your fullname", AllowEmptyStrings = false)]
public string FullName { get; set; }
[Display(Name = "Mobile No")]
public string MobileNo { get; set; }
[Display(Name = "Country")]
[Required(ErrorMessage = "Please select country", AllowEmptyStrings = false)]
public int CountryID { get; set; }
[Display(Name = "State")]
[Required(ErrorMessage = "Please select state", AllowEmptyStrings = false)]
public int StateID { get; set; }
}
and this is my view with my ajax code :
#using (Html.BeginForm("Submit", "Feedback", FormMethod.Post))
{
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
<fieldset>
<legend>Feedback</legend>
#if (ViewBag.Message != null)
{
<div style="border:solid 1px black">
#ViewBag.Message
</div>
}
<div class="editor-label">
#Html.LabelFor(model => model.FullName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FullName)
#Html.ValidationMessageFor(model => model.FullName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.MobileNo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MobileNo)
#Html.ValidationMessageFor(model => model.MobileNo)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CountryID)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.CountryID, #ViewBag.CountryID as SelectList, "Select Country")
#Html.ValidationMessageFor(model => model.CountryID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.StateID)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.StateID, #ViewBag.StateID as SelectList, "Select State")
#Html.ValidationMessageFor(model => model.StateID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript">
$(document).ready(function () {
$("#CountryID").change(function () {
// this will call when Country Dropdown select change
var countryID = parseInt($("#CountryID").val());
if (!isNaN(countryID)) {
var ddState = $("#StateID");
ddState.empty(); // this line is for clear all items from State dropdown
ddState.append($("<option></option").val("").html("Select State"));
// Here I will call Controller Action via Jquery to load State for selected Country
$.ajax({
url: "#Url.Action("GetStates","Feedback")",
type: "GET",
data: { countryID: countryID },
dataType: "json",
success: function (data) {
$.each(data, function (i, val) {
ddState.append(
$("<option></option>").val(val.StateID).html(val.StateName)
);
});
},
error: function () {
alert("Error!");
}
});
}
});
});
</script>
}
All i want is for my country selecteditem to populate my state with the link between the two. E.g. if i select South Africa, it must only display Gauteng, Cape Town etc.
Please can your'll help me with my error or provide guidance thanks.
Issue 1: Try using == instead of using .Equals() because if CountryIDis null, you'll throw an error.
Issue 2: Change
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = allState,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
to
return Json(allState, JsonRequestBehavior.AllowGet);
Possible Issue 3?
Try this as your success function:
success: function (data) {
$(data).each(function () {
ddState.append(
$("<option></option>").val(this.StateID).html(this.StateName)
);
});
},

Model is null after submit

I wonder why the ContactModel in ContactController is not filled with the values provided in the form. Where has my head exploded?
Code as is:
HomeController (where the contact form is)
public class HomeController : Controller
{
public ActionResult Index()
{
var viewModel = new HomeViewModel();
return View(viewModel);
}
}
ViewModel for Home
public class HomeViewModel
{
public ContactModel ContactModel { get; set; }
}
ContactModel to hold the values
public class ContactModel
{
[Required(ErrorMessage = "Required")]
public String Name { get; set; }
[EmailAddress]
[Required(ErrorMessage = "Required")]
public String Email { get; set; }
[Required(ErrorMessage = "Required")]
public String Message { get; set; }
}
Index View for HomeController
#model MyNameSpace.ViewModels.HomeViewModel
#using (Html.BeginForm("Send", "Contact", FormMethod.Post))
{
<div class="form-group">
#Html.LabelFor(model => model.ContactModel.Name, "Name", new { #class = "sr-only" })
#Html.TextBoxFor(model => model.ContactModel.Name, new { #class = "form-control", #placeholder = "Name" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.ContactModel.Email, "E-mail", new { #class = "sr-only" })
#Html.TextBoxFor(model => model.ContactModel.Email, new { #class = "form-control", #placeholder = "E-mail" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.ContactModel.Email, "Message", new { #class = "sr-only" })
#Html.TextAreaFor(model => model.ContactModel.Message, new { #class = "form-control", #placeholder = "Message" })
</div>
<p><button type="submit" class="btn btn-default">Send</button></p>
}
ContactController Send
public class ContactController : Controller
{
[HttpPost]
public ActionResult Send(ContactModel model)
{
if (ModelState.IsValid)
{
// ModelState is not valid - but why!?
return RedirectToAction("Index", "Success");
}
return RedirectToAction("Index", "Error");
}
}
For some reason on my form submit, the model provided in ContactController.Send(ContactModel model) has all null values - where is the link broken?
Your POST action should take the view model as parameter instead of your domain model:
[HttpPost]
public ActionResult Send(HomeViewModel model)
The reason for that is pretty simple - it's the way the default model binder works. Your input fields in the view are all prefixed with ContactModel.
Alternatively you could use the Bind attribute and explicitly specify that:
[HttpPost]
public ActionResult Send([Bind(Prefix = "ContactModel")] ContactModel model)

Add error message if duplicate record exist in MVC Popup Form

I have a popup window called AddNew will display when the user click a button called add New. The button itself has number of field called TRN and DOB. The problem that i have now that i am trying to display error message when the user try to add duplicate TRN but unfortunately no error message display only if the required field is empty.
Is there anyway i could display the duplicate error message in validation summary like displaying in required field and hold all the previous entered value in the form. Please advise. Thank you
Here is the code that i have so far. Thank you
Index.cshtml
<input type="button" id="btnAddNew" style="height:50px; font-size:14px; width:95px; background-color:#3399FF; white-space: normal;" class="k-button" title="AddNew" value="Add New" />
<script type="text/javascript">
$(document).ready(function () {
$('#btnAddNew').click(function () {
window.open('#Url.Action("AddNew", "Details")', 'AddProduct', 'height=' + (window.screen.height - 450) + ',width=950,left=' + (window.screen.width - 5) + ',top=10,status=no,toolbar=no,resizable=yes,scrollbars=yes');
});
});
</script>
AddNew.cshtml (window popup)
#{
Layout = "~/Views/Shared/_LayoutNoMenu.cshtml";
}
<script src="../../Scripts/jquery.validate.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.validate.unobtrusive.js" type="text/javascript"></script>
#model HHIMS_Web_App.Models.CModel
#{
ViewBag.Title = "New Product";
}
#using (Html.BeginForm("Create", "Details", FormMethod.Post, new { id = "frmAsset" }))
{
ViewContext.FormContext.ValidationSummaryId = "valSumId";
#Html.ValidationSummary(false, "Please fix the following errors:", new Dictionary<string, object> { { "id", "valSumId" } });
<fieldset id="AddNew">
<div>
<div class="addInfo">
#Html.LabelFor(model => model.TRN)
#Html.EditorFor(model => model.TRN)
#Html.ValidationMessageFor(model => model.TRN, "*")
</div>
<div class="AddSmallBox">
#Html.LabelFor(model => model.DOB)
#Html.EditorFor(model => model.DOB)
#Html.ValidationMessageFor(model => model.DOB, "*")
</div>
</div>
<div>
<div class="smallAddAndCancel">
<input type="button" id="btnCancel" style="height:50px; width:85px; font-size:14px; background-color:#3399FF" class="k-button" title="Cancel" value="Cancel" onclick="window.close()" />
<input type="submit" id="btnSave" style="height:50px; width:85px; font-size:14px; background-color:#3399FF;white-space: normal" class="k-button" title="Save" value="Save"/>
</div>
</div>
</fieldset>
}
<script type="text/javascript">
$(document).ready(function () {
$("#datepicker").closest("span.k-datepicker").width(400);
$('#btnSave').click(function () {
var validation = $("#frmAsset");
if (!validation.valid()) {
return false;
else
{
$.ajax({
type: 'POST',
url: "#Url.Action("Create","Details")",
data: {
TRN: $("#TRN").val(),
DOB: $("#DOB").val(),
},
success: function () {
window.close()
}
});
}
});
});
</script>
Controller:
[HttpPost]
public ActionResult Create(Cmodel)
{
try
{
if (ModelState.IsValid)
{
CheckDuplicateHRNExist(model);
return RedirectToAction("AddNew");
}
if (ModelState.IsValid)
{
HH_DataAccessLayer.Consumers dalModel = new HH_DataAccessLayer.Consumers();
Mapper.CreateMap<CModel, HH_DataAccessLayer.Consumers>();
Mapper.Map(model, dalModel);
return RedirectToAction("Index");
}
}
catch (DbUpdateConcurrencyException e)
{
var entry = e.Entries.Single();
var clientValues = (CModel)entry.Entity;
}
return RedirectToAction("Index");
}
/// <summary>
/// Validate TRN find if no duplicate TRN recorded
/// </summary>
/// <param name="model"></param>
private void CheckDuplicateTRNExist(CModel model)
{
HEntities context = new HEntities();
if (model.TRN != null)
{
var duplicateTRN = context.Consumers.Where(d => d.TRN == model.TRN).FirstOrDefault();
if (duplicateTRN != null)
{
var errorMessage = String.Format("TRN is already exist.", duplicateTRN);
ModelState.AddModelError(string.Empty, errorMessage);
}
}
}
Model
[Required(ErrorMessage = "Please enter TRN")]
[DisplayName("TRN")]
[StringLength(20)]
public string TRN { get; set; }
[Required(ErrorMessage = "Please enter or select Date of Birth")]
[DisplayName("Date Of Birth")]
public DateTime? DOB { get; set; }
If I'm not mistaking, ValidationSummary must be set to true to display custom errors.
Edit: to be complete:
In your AddNew.cshtml file, replace
#Html.ValidationSummary(false, "Please fix the following errors:", new Dictionary<string, object> { { "id", "valSumId" } });
With:
#Html.ValidationSummary(true, "Please fix the following errors:", new Dictionary<string, object> { { "id", "valSumId" } });

MVC4 application on handling list

This is my model class with two classes Employee and Employee list
namespace EditMultiplerecords.Models
{
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Employeelist : IEnumerable<Employee>
{
public List<Employee> employee { get; set; }
public IEnumerator<Employee> GetEnumerator()
{
return employee.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return employee.GetEnumerator();
}
}
}
This is my View where i am writing code for editing using javascript
#model EditMultiplerecords.Models.Employeelist
#{
ViewBag.Title = "Homepage";
}
<link href="../../Content/StyleSheet1.css" rel="stylesheet" type="text/css" />
<script src="../../Scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$('.editor input').blur(function () {
$(this).hide();
$(this).closest('p').find('label').html($(this).val()).show();
});
$('.editor label').click(function () {
$(this).hide();
$(this).closest('p').find('input').show();
});
});
</script>
#foreach (var item in Model)
{
using (Html.BeginForm())
{
<div class="editor">
<p>
#Html.HiddenFor(x => item.Id)
#Html.LabelFor(x => item.Name, item.Name)
#Html.EditorFor(x => item.Name)
<input type="submit" value="OK" />
</p>
</div>
}
#* #Html.Partial("Details", item);*#
}
And this controller class
public ActionResult Homepage()
{
Employeelist el = new Employeelist();
el.employee = new List<Employee>();
el.employee.Add(new Employee { Id = 1, Name = "Rahul" });
el.employee.Add(new Employee { Id = 2, Name = "America" });
el.employee.Add(new Employee { Id = 3, Name = "NewJersey" });
return View(el);
}
[HttpPost]
public ActionResult Homepage(Employeelist el)
{
return View(el);
}
My problem is when i edit Rahul or America or NewJersey, on Post Action iam getting an empty list with null values rather an updated list
you need to add #foreach (var item in Model) loop inside using (Html.BeginForm()) to accept modified List
using (Html.BeginForm())
{
#foreach (var item in Model)
{
<div class="editor">
<p>
#Html.HiddenFor(x => item.Id)
#Html.LabelFor(x => item.Name, item.Name)
#Html.EditorFor(x => item.Name)
</p>
</div>
}
}
<input type="submit" value="OK" />
#* #Html.Partial("Details", item);*#
-- Edit Accept formCollection
[HttpPost]
public ActionResult Homepage(FormCollection formCollection)
{
var itemid = formCollection.GetValue("item.id");
var itemname= formCollection.GetValue("item.name");
---//use values to send it back to view----
return View();
}