I use breakpoint debug it my ClientsId always come null and display on my payments index always is the first value of my Dropdownlist
Model:
public class Payments
{
[Key]
public int PaymentsId { get; set; }
public int ClientId { get; set; }
public virtual Client Client { get; set; }
}
ViewModel:
public class PaymentsViewModel
{
[Required(ErrorMessage = "Please select a client")]
[Display(Name = "Client")]
public int SelectedClient { get; set; }
public IEnumerable<SelectListItem> Client { get; set; }
}
GET CONTROLLER:
public ActionResult Create(Payments model)
{
var liste= new PaymentsViewModel
{
Clients = new SelectList(db.ClientList, "ClientId", "ClientName")
};
return View(liste);
}
POST CONTROLLER:
public ActionResult Create([Bind(Include = "....")] PaymentsViewModel model)
{
if (ModelState.IsValid)
{
model.PaymentsCreate();
return RedirectToAction("Index", "Payments");
}
return View(model);
}
CREATE VIEW:
#Html.DropDownListFor(m => m.SelectedClient, Model.Clients, "-Please select-", new { #class = "form-control" })
</div>
</div>
--------------------------------------------UPDATE---------------------------------------------------
EDIT CONTROLLER (GET):
public ActionResult Edit(int? id, PaymentsViewModel model)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Payments payments = db.PaymentsList.Find(id);
if (payments == null)
{
return HttpNotFound();
}
return View();
}
EDIT CONTROLLER (POST)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "PaymentsId,Paymentnumber,PaymentDate,Amount,Discount,Reference,Total")] Payments payments)
{
if (ModelState.IsValid)
{
db.Entry(payments).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(payments);
}
You should add a ClientsId initialization from model.SelectedClient at PaymentsCreate functions like: ClientsId = model.SelectedClient. And then you need to add SelectedClient string to properties enumeration at Create (post) method to Bind(Include.... attribute
Related
I have an application written using C# on the top of ASP.NET Core 5.0.
I have the following view-model
public class TestVM
{
public Name { get; set; }
public MenuViewModel<string> State { get; set;}
public TestVM()
{
State = MenuViewModel<string>();
}
}
Here is a stripped down version of my MenuViewModel
public class MenuViewModel
{
[BindNever]
public IEnumerable<SelectListItem> Items { get; set; }
}
public class MenuViewModel<T> : MenuViewModel
{
public T Value { get; set; }
}
The problem, is when the post request comes in, the viewModel.State.Value is null. When I evaluate Request.Form I do see the key State.Value with the correct value of CA
Here is a stripped down of my action method in the controller.
[HttpPost, ValidateAntiForgeryToken]
public IActionResult Store(TestVM viewModel)
{
if(ModelState.IsValid)
{
// do some
}
return View(viewModel);
}
How can I bind the form data from the request to State.Value property correctly?
Updated I created an editor-template to allow me to render the MenuVieModel. The ~/Views/Shared/EditorTemplates/MenuViewModel.cshtml contains the following code
#model dynamic
#{
if (!(Model is MenuViewModel m))
{
return;
}
dynamic obj = new System.Dynamic.ExpandoObject();
obj.Class = "form-control";
if (Html.ViewData.ModelMetadata.IsRequired)
{
obj.Required = true;
}
}
#Html.DropDownList("Value", m.Options, Html.ViewData.ModelMetadata.Placeholder, obj)
Firsly,you need know that for each property of the complex type, model binding looks through the sources for the name pattern prefix.property_name. If nothing is found, it looks for just property_name without the prefix.
Here is a working demo you could follow:
Model:
public class TestVM
{
public string Name { get; set; }
public MenuViewModel<string> State { get; set; }
public TestVM()
{
State =new MenuViewModel<string>();
}
}
public class MenuViewModel
{
[BindNever]
public IEnumerable<SelectListItem> Items { get; set; }
}
public class MenuViewModel<T> : MenuViewModel
{
public T Value { get; set; }
}
View:
#model dynamic
#{
if (!(Model is MenuViewModel m))
{
return;
}
dynamic obj = new System.Dynamic.ExpandoObject();
obj.Class = "form-control";
if (Html.ViewData.ModelMetadata.IsRequired)
{
obj.Required = true;
}
}
<form asp-action="Store">
#*change here,And I do not find Options in your MenuViewModel,So I change it to Items*#
#Html.DropDownList("State.Value", m.Items, Html.ViewData.ModelMetadata.Placeholder, obj)
<input type="submit" value="post" />
</form>
Controller:
public IActionResult Index()
{
var model = new MenuViewModel<string>()
{
Items = new List<SelectListItem>() {
new SelectListItem() { Value = "-1", Text = "--- Select ---" },
new SelectListItem() { Value = "org1", Text = "org1" },
new SelectListItem() { Value = "org2", Text = "org2" },
new SelectListItem() { Value = "org3", Text = "org3" }
}
};
return View(model);
}
[HttpPost, ValidateAntiForgeryToken]
public IActionResult Store(TestVM viewModel)
{
if (ModelState.IsValid)
{
// do some
}
return View(viewModel);
}
Result:
I am updating database values using an action method but I am using ajax call to send updated values into that method so I am not binding model with this method so how can I validate the model for this action method such as I am not binding this with my method?
public ActionResult Update(int id, double? value)
{
if (!ModelState.IsValid)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json("Not valid model");
}
if (ModelState.IsValid) {
var oldTag = db.Tags.Where(x => x.Id == id).FirstOrDefault();
List<UpdatedData> updatedDatas = new List<UpdatedData> {
new UpdatedData
{
Id=id,
OldTagValue=oldTag.TagValue,
NewTagValue=value,
TagName = oldTag.TagName
}
};
obj.updatedDatas = new List<UpdatedData>();
obj.updatedDatas.AddRange(updatedDatas);
return PartialView("_Update_Confirmation", obj);
}
return View("Index");
}
you can change Update method
public class ProfileViewModel
{
[Required]
public int Id { get; set; }
public double? value { get; set; }
}
then
public ActionResult Update(ProfileViewModel viewModel)
{
if (!ModelState.IsValid)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json("Not valid model");
}
//...
}
The sample DataAnnotations model binder will fill model state with validation errors taken from the DataAnnotations attributes on your model.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a very big issuse here. I'm trying to make a list off all cars and push them to View, but it doesn't work as I assume. Any idea how can I do that ?? I would be very thankfull
Here is my Car Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Automarket.Models;
using System.Data.Entity;
using System.Web.Script.Serialization;
using System.Net;
namespace Automarket.Controllers
{
public class CarController : Controller
{
OurDBContext db = new OurDBContext();
private object Viewbag;
private readonly object ds;
// GET: Automarket
public ActionResult Index()
{
List<Marke> marke = db.Marke.ToList();
List<Modeli> modeli = db.Modeli.ToList();
JavaScriptSerializer oSerializer = new JavaScriptSerializer();
string deps = oSerializer.Serialize(modeli);
ViewData["deps"] = deps;
ViewData["marke"] = marke;
ViewData["modeli"] = modeli;
return View(db.car.ToList());
}
// GET: Cars/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Car car = db.car.Find(id);
if (car == null)
{
return HttpNotFound();
}
return View(car);
}
// GET: Cars/Create
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "CarID,Make,Model,Price,Registration,Mileage,FuealType,Country,ZipCode,Picture")] Car car)
{
if (ModelState.IsValid)
{
db.car.Add(car);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(car);
}
// GET: Cars/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Car car = db.car.Find(id);
if (car == null)
{
return HttpNotFound();
}
return View(car);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "CarID,Make,Model,Price,Registration,Mileage,FuealType,Country,ZipCode,Picture")] Car car)
{
if (ModelState.IsValid)
{
db.Entry(car).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(car);
}
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Car car = db.car.Find(id);
if (car == null)
{
return HttpNotFound();
}
return View(car);
}
// POST: Cars/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Car car = db.car.Find(id);
db.car.Remove(car);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Here is my Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Automarket.Models
{
public class Car
{
public int CarID { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public float Price { get; set; }
public int Registration { get; set; }
public double Mileage { get; set; }
public string FuealType { get; set; }
public string Country { get; set; }
public int ZipCode { get; set; }
public string pathToImage { get; set; }
}
}
To show a list of objects in your view, bascally, you need:
In Controller, send a list of objects to View using View(<data>) method:
public ActionResult Index() {
OurDBContext db = new OurDBContext();
return View(db.car.ToList());
}
In View, receive the list of objects in Model variable:
#model List<Car>
<html>
...
<body>
#foreach(var item in Model) {
<p>#item.Property</p>
}
</body></html>
I have controller
public class NewsController : Controller
{
private SchoolDbContext db = new SchoolDbContext();
//
// GET: /News/
public ActionResult Index()
{
return View(db.News.ToList());
}
//
// GET: /News/Details/5
public ActionResult Details(int id = 0)
{
News news = db.News.Find(id);
if (news == null)
{
return HttpNotFound();
}
return View(news);
}
//
// GET: /News/Create
public ActionResult Create()
{
return View();
}
//
// POST: /News/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(News news)
{
if (ModelState.IsValid)
{
var file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
string path2 = Path.GetRandomFileName();
fileName = path2 + fileName;
var path = Path.Combine(Server.MapPath("~/Uploads/"), fileName);
news.Image = fileName;
file.SaveAs(path);
}
db.News.Add(news);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(news);
}
//
// GET: /News/Edit/5
public ActionResult Edit(int id = 0)
{
News news = db.News.Find(id);
if (news == null)
{
return HttpNotFound();
}
return View(news);
}
//
// POST: /News/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(News news)
{
if (ModelState.IsValid)
{
db.Entry(news).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(news);
}
//
// GET: /News/Delete/5
public ActionResult Delete(int id = 0)
{
News news = db.News.Find(id);
if (news == null)
{
return HttpNotFound();
}
return View(news);
}
//
// POST: /News/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
News news = db.News.Find(id);
db.News.Remove(news);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
I have a Model
public class News
{
[Key]
public int newsID { get; set; }
[Required]
public string newsName { get; set; }
[Required]
public string newsDescription { get; set; }
public string Image { get; set; }
}
and a simple view
<div class="grid">
#foreach (var item in Model)
{
<div class="holder_content">
<section class="group1">
<h3>#Html.DisplayFor(modelItem => item.newsName)</h3>
<p class="desc">#Html.DisplayFor(modelItem => item.newsDescription)</p>
<a class="photo_hover3" href="#"><img src="~/Uploads/#Html.DisplayFor(modelItem => item.Image)" width="240" height="214" alt=""></a>
<div class="forbutton">
#Html.ActionLink("სრულად ", "Details", new { id = item.newsID }, new { #class = "button" })
</div>
#{ if (User.Identity.IsAuthenticated)
{
#Html.ActionLink("Edit ", "Edit", new { id = item.newsID })
#Html.ActionLink("Delete", "Delete", new { id = item.newsID })
}
}
</section>
}
I want to display this data in another page, where I have this code
#RenderPage("~/Views/News/Index.cshtml")
but web page goes on runtime error, with null pointer exception on foreach tag
have you any solution with this error? sorry for my english. Hope you understand
Please use the partial view rendering.
Note main thing you have to mention the namespace in the view page
Like : #model YourApplicationName.Models.exampleClassName
and then render the page as partial view.
#Html.Partial("partialViewName", new exampleClassName())
or other wise pass the model which you have denoted as namespace in the Partialview like below
#Html.Partial("partialViewName", #Modle.exampleClassName)
or
#Html.Partial("partialViewName", #Modle)
In my application I'am populating a dropdownlist from database using ADO Entity Framework, after this when i try to submit the form the value of the dropdown list it is giving Null reference exception.
Error Code (in INDEX.ASPX)
<%: Html.DropDownListFor(model => model.race, Model.Races, "--Select--")%> <--error
<%: Html.ValidationMessageFor(model => model.race)%>
CONTROLLER (in NewPersonController)
public ActionResult Index()
{
Person person= new Person();
return View(new PersonFormViewModel(person));
}
[HttpPost]
public ActionResult Index(Person person)
{
if (ModelState.IsValid) //Also not enter the race parameter
{
personRepo.Add(person);
personRepo.Save();
}
return View(); // When return the view I get the error
}
MODEL (in PersonFormViewModel)
public class PersonFormViewModel
{
public Person Person {
get;
private set;
}
public SelectList Races
{
get;
private set;
}
public string race
{
get { return Person.race; }
set { Person.race = value; }
}
public PersonFormViewModel(Person person)
{
Person = person;
RaceRepository repository = new RaceRepository();
IList<Race> racesList= repository.FindRaces().ToList();
IEnumerable<SelectListItem> selectList =
from c in racesList
select new SelectListItem
{
Text = c.race,
Value = c.id.ToString()
};
Races = new SelectList(selectList, "Value", "Text");
}
}
IN VALIDATION MODEL
[MetadataType(typeof(Person_Validation))]
public partial class Person {
}
public class Person_Validation
{
[Required(ErrorMessage = "Required race")]
public string race
{
get;
set;
}
}
Can you help me please? Thank you.
In the POST method you have to give the same type of model to the view.
[HttpPost]
public ActionResult Index(Person person)
{
if (ModelState.IsValid)
{
personRepo.Add(person);
personRepo.Save();
}
return View(new PersonFormViewModel(person));
}
You're not passing the ViewModel in the post action.
[HttpPost]
public ActionResult Index(Person person)
{
if (ModelState.IsValid) //Also not enter the race parameter
{
personRepo.Add(person);
personRepo.Save();
}
return View(new PersonFormViewModel(person));
}
Or maybe
[HttpPost]
public ActionResult Index(Person person)
{
if (ModelState.IsValid) //Also not enter the race parameter
{
personRepo.Add(person);
personRepo.Save();
}
return RedirectToAction("Index");
}