MVC3 (Razor) Passing Model Data - asp.net

I'm making Memo web application.
and the main page contain 'Create and List and Modify' functions.
But I don't know how to pass Model (for create) and List (for List) to View(Razor) from controller.
this is my note model,
[Table("note")]
public class Note
{
[Key]
public int id { get; set; }
[Required(ErrorMessage="Content is required")]
[DisplayName("Note")]
public string content { get; set; }
public DateTime date { get; set; }
[Required(ErrorMessage = "User ID is required")]
[DisplayName("User ID")]
public string userId {get; set;}
public Boolean isPrivate { get; set; }
public virtual ICollection<AttachedFile> AttachedFiles { get; set; }
}
I tried,
1)
public ActionResult Index()
{
var notes = unitOfWork.NoteRepository.GetNotes();
return View(notes);
}
Then, in view,
#model Enumerable<MemoBoard.Models.Note>
//I can not use this, because the model is Enumerable type
#Html.LabelFor(model => model.userId)
So, I made viewModel
2)
public class NoteViewModel
{
public IEnumerable<Note> noteList { get; set; }
public Note note { get; set; }
}
In Controller,
public ActionResult Index()
{
var notes = unitOfWork.NoteRepository.GetNotes();
return View(new NoteViewModel(){noteList=notes.ToList(), note = new Note()});
}
and In View,
#model MemoBoard.Models.NoteViewModel
#Html.LabelFor(model => model.note.userId)
it looks well, BUT in source view, it's showing
<input data-val="true" data-val-required="User ID is required" id="note_userId" name="note.userId" type="text" value="" />
the name is note.userId not userId.
List this case, how should I do to make working?
Please advice me.
Thanks
[EDIT]
(First of all, thanks for all advices)
Then, How can I change this controller
[HttpPost]
public ActionResult Index(Note note)
{
try
{
if (ModelState.IsValid)
{
unitOfWork.NoteRepository.InsertNote(note);
unitOfWork.Save();
return RedirectToAction("Index");
}
}catch(DataException){
ModelState.AddModelError("", "Unable to save changes. Try again please");
}
return RedirectToAction("Index");
}
If I change parameter type to NoteViewModel, then how should I do for valid check?
[HttpPost]
public ActionResult Index(NoteViewModel data)
{
try
{
if (ModelState.IsValid) <===

#model Enumerable<MemoBoard.Models.Note>
//I can not use this, because the model is Enumerable type
#Html.LabelFor(model => model.userId)
You can use it in foreach loop or return list and use it in for loop
the name is note.userId not userId.
It's normal, this made for model binding
Try this:
Html.TextBox("userId", Model.note.userId, att)

Related

Why ActionResult method doesn't take any parameter from Html.BeginForm() inside view?

I tried to make a database named PersonalJobManagement and it includes information of my employees.
I would like to code an ASP.NET MVC website to edit, delete or create new data for this database.
But here is the problem:
I write the create view, I enter parameters like name or id, but parameters're not processed into the database. There are 8 employees added already and I cannot add the 9th.
My Create Methods in Controller:
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Person model)
{
db.Person.Add(model);
db.SaveChanges();
return RedirectToAction("List");
}
My Create View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div>
<div>
<b>Name</b>
<div>
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new {} })
#Html.ValidationMessageFor(model => model.FirstName, "", new {})
</div>
</div>
<div>
<div>
<input type="submit" value="Save it"/>
</div>
</div>
</div>
}
And my Person model:
public partial class Person
{
public int BusinessEntityID { get; set; }
public string PersonType { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public System.DateTime ModifiedDate { get; set; }
public virtual BusinessEntity BusinessEntity { get; set; }
}
NAILED IT!
My ~/Views/Shared/_Layout.cshtml file has a form tag and i don't know why but it causes the error when calling POST method. So if you are here, be careful guys

Saving dropdown list value to database ASP.net 5.0 MVC 6 using tag helpers

I am trying to save my dropdown list values to my database in an ASP.NET web application using MVC6 and Entity Framework 7 but the values are not saving.
I have two classes one called expenses and when a user creates an expense they need to select a country. I have the country dropdown list populating but when the expense is saved the countryid is not being saved to the database.
Models
public class Country
{ public int Countryid { get; set; }
public string CountryCode { get; set; }
}
public class Expense
{
public int ExpenseId { get; set; }
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}",
ApplyFormatInEditMode = true)]
public DateTime ExpenseDate { get; set; }
public virtual Country Countryid { get; set; }
Expense Controller
private void PopulateCountriesDropDownList(object selectedCountry = null)
{
var list = _context.Countries.OrderBy(r => r.CountryCode).ToList().Select(rr =>
new SelectListItem { Value = rr.Countryid.ToString(), Text = rr.CountryCode }).ToList();
ViewBag.Countries = list;
}
// GET: Expenses/Create
public IActionResult Create()
{
PopulateCountriesDropDownList();
return View();
}
// POST: Expenses/Create
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Expense expense)
{
if (ModelState.IsValid)
{
_context.Expenses.Add(expense);
_context.SaveChanges();
return RedirectToAction("Index");
}
PopulateCountriesDropDownList(expense.Countryid);
return View(expense);
}
View
<div class="form-group">
<label asp-for="Countryid" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="Countryid" class="form-control"asp-items=#ViewBag.Countries></select>
<span asp-validation-for="Countryid" class="text-danger" />
</div>
</div>
First of all the Countryid property in your Expense model is a of a complex type (Country). The model binder cannot map the posted Countryid form value to this Complex object.
You should add a CountryId property to your Expense model of type Int
public class Expense
{
public int ExpenseId { get; set; }
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}",
ApplyFormatInEditMode = true)]
public DateTime ExpenseDate { get; set; }
public int CountryId { set;get;}
public virtual Country Country { get; set; }
}
While this will fix the problem, A more better & clean solution is to use a view model for transferring data between your view and action method. With this approach your view is not tightly coupled to the entity classes generated by your ORM.
So create a view model for your view with properties absolutely needed for the view.
public class CreateExpenseVm
{
public List<SelectListItem> Countries { set;get;}
public int CountryId { set;get;}
//Add other properties, if your view need them.
}
and in your GET action, you create an object of this class, load the Countries collection property and send it to your view.
public ActionResult Create()
{
var vm=new CreateExpenseVm();
vm.Countries = _context.Countries.OrderBy(r => r.CountryCode)
.Select(x=>new SelectListItem { Value=x.CountryId.ToString(),
Text=x.CountryCode}).ToList();
return View(vm);
}
And in your view,which is strongly typed to our new viewmodel,
#model CreateExpenseVm
<form asp-controller="Expense" asp-action="Create">
<label>Select Country</label>
<select asp-for="CountryId" asp-items="#Model.Countries" >
<option>Please select one</option>
</select>
<input type="submit"/>
</form>
and in your HttpPost action, Use CreateExpenseVm as the parameter type. When the form is submitted, the default model binder will be able to map the posted form data to the properties of this class object.
[HttpPost]
public ActionResult Create(CreateExpenseVm model)
{
var e=new Expense { CountryId=model.CountryId };
e.ExpenseDate = DateTime.Now;
dbContext.Expenses.Add(e);
dbContext.SaveChanges();
return RedirectToAction("Index");
}

Html.DropDownList razor

I'm new to MVC and C# and having hard time with a dropdown list.
What I'm trying to accomplish is to initialize my page with an object that keeps the settings.
(I read settings from XML file).
Here's what I have
public class StoreSettings
{
public String BackSrs2Path { get; set; }
public int NoLines { get; set; }
public String Requesturl { get; set; }
}
public class Store
{
public String StoreId { get; set; }
public String Address { get; set; }
public StoreSettings StoreSettings { get; set; }
}
and the Model for my view page is a list of Store
#model System.Collections.Generic.List<Control2.Models.Store>
#{
List<SelectListItem> selectList = new List<SelectListItem>();
foreach (var Store in Model)
{
SelectListItem i = new SelectListItem();
i.Text = Store.StoreId;
i.Value = Store.StoreId;
selectList.Add(i);
}
}
#using (Html.BeginForm())
{
SelectList list = new SelectList(selectList, "Value", "Text");
#Html.DropDownList("ddl", list, "select store", new { onchange = "this.form.submit();" });
}
}
By reading examples here managed to populate the dropdownlist from my model and postsback
but now i need to get only the selected object from the list and apply his seetings to the page to display it etc a message "you ve selected Store"+Storeid(the slected from dropdown)
Also this code is written in my cshtml page which isn't the best but couldn't figure how should I do it with ViewModel and dropdown list
Yes when I first started looking at the DropDownList Binding mechanisms of MVC I too had problems. What I'd like to do is suggest to you the following:
Create a Viewmodel and bind the entire view to the viewmodel... as follows:
public class VMStore
{
public VMStore()
{
ItemsInDropDown = new List<SelectListItem>(){
new SelectListItem{ Text="SomeValue", Selected=false, Value="SomeUniqueId"}
};
}
public String StoreId { get; set; }
public String Address { get; set; }
public StoreSettings StoreSettings { get; set; }
public string SelectedValue { get; set; }
public IEnumerable<SelectListItem> ItemsInDropDown { get; set; }
public void Post()
{
//This method will have the user selected value...
}
}
The view will bind fields like this:
#model WebApplication1.ViewModels.VMStore
#{
ViewBag.Title = "GetStore";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>GetStore</h2>
<div>
<h4>VMStore</h4>
<hr />
<dl class="dl-horizontal">
#Html.BeginForm(){
<dt>Select Store</dt>
<dd>#Html.DropDownListFor(p=>Model.SelectedValue, Model.ItemsInDropDown) </dd>
<dd><button type="submit">Submit</button></dd>
}
</dl>
</div>
The action methods will look like this:
public ActionResult GetStore()
{
return View();
}
[HttpPost]
public ActionResult GetStore(ViewModels.VMStore userdata) {
if (ModelState.IsValid)
{
userdata.Post();
}
return View(userdata);
}

DropdownList selected value not saved in database

I need big help from here i am new to Asp.net MVC 4 Application development , actually i faced a problem when i save my dropdownlist selected value in a database ,after i click my submit button.
I use Debug pointer to check values in a HTTP post object but it doesn't contain dropdownlist select value it always display null value in a division raw I need some expert advice to solve that problem i go through the several examples and try several times but still i haven't proper solution for that.
Model class:
public partial class tblEmployee
{
public int EmployeeId { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Nullable<System.DateTime> DateOfBirth { get; set; }
public Nullable<System.DateTime> DateOfJoin { get; set; }
public string Position { get; set; }
public string Office { get; set; }
public string Division { get; set; }
public Nullable<decimal> Salary { get; set; }
public virtual tblDivision Divisions { get; set; }
}
public partial class tblDivision
{
public int value { get; set; }
public string Division { get; set; }
public Nullable<int> SelectId { get; set; }
}
Controller class:
namespace EmpiteHrSystem.Controllers
{
public class EmployeeController : Controller
{
private EmpiteContext db = new EmpiteContext();
public ActionResult Create()
{
ViewBag.DivisionOptions = new SelectList(db.tblDivisions, "value","Division");
return View();
}
//
// POST: /Employee/Create
[HttpPost]
public ActionResult Create(tblEmployee tblemployee)
{
if (ModelState.IsValid)
{
try
{
db.Entry(tblemployee).State = EntityState.Added;
db.tblEmployees.Add(tblemployee);
db.SaveChanges();
}
catch (ArgumentException ae)
{
ModelState.AddModelError("", ae.Message);
}
return RedirectToAction("Index");
}
}
}
}
View:
#model EmpiteHrSystem.Models.tblEmployee
#{ ViewBag.Title = "Create"; Layout = "~/Views/Shared/_Layout.cshtml";}
#Html.EditorFor(model => model.EmployeeId)
#Html.ValidationMessageFor(model => model.EmployeeId)
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
#*#Html.EditorFor(model => model.Office)*#
#Html.DropDownList("DivisionOptions")
#Html.ValidationMessageFor(model => model.Division)
#Html.ActionLink("Back to List", "Index")
Your DivisionOptions drop down list is not being bound back to the model properly because it is the wrong name. Your model is looking for a property with the name Division while your drop down list is being bound to DivisionOptions. You have a few options.
Use a strongly typed helper
#Html.DropDownListFor(x=>x.Division, (SelectList)ViewBag.DivisionOptions)
Rename your currrent code and pass in the SelectList
#Html.DropDownList("Division", (SelectList)ViewBag.DivisionOptions)

Drop down list access data from database table stored in App_DA\ata

this is my model class
public class Model1
{
public string popcorn { get; set; }
public string pselectedItem { get; set; }
public IEnumerable items { get; set; }
}
this is my controller class:-
public class HomeController : Controller
{
private rikuEntities rk = new rikuEntities();
public ActionResult Index()
{
var model = new Model1
{
items = new[]
{
new SelectList(rk.emp,"Id","name")
}
}; return View(model);
}
public ActionResult viewToController(Model1 m)
{
string getSelectedName = m.popcorn;
return Content(getSelectedName);
}
}
this is my view;-
#model chetan.Models.Model1
#using (Html.BeginForm("viewToController", "Home"))
{
#Html.ValidationSummary(true)
emp
<div class="editor-field">
#Html.DropDownListFor(x => x.popcorn, new SelectList(Model.items))
</div>
</fieldset>
}
in my example i want to get values in Dropdownlist from database table named "emp" and after select a element of dropdownlist i want to use that element in Index action of Home controller. please check my code carefully and let me know what should i do ?
First in your model your model you need SelectList and not IEnumerable<SelectList>:
public class Model1
{
public string popcorn { get; set; }
public string pselectedItem { get; set; }
public SelectList items { get; set; }
}
and then in your view:
#Html.DropDownListFor(x => x.popcorn, Model.items)
The rest of your code seems fine.

Resources