MVC: Member and Member.Items.add(Item) doesn't get saved - asp.net

The item doesn't get saved. Only member gets saved.
When I debug [AcceptVerbs(HttpVerbs.Post)]
the information is empty in the Item. Why? How should I solve this?
When it goes to the post method of create, then the ITEM dosen't follow the member. and the ITEMS doesn't get saved. I debug the information and there are 0 Number items. Why doesn't it save Items also when I press the button.
Only the member item gets saved.
public class ClassifiedsFormViewModel
{
IClassifiedsRepository classifiedsRepository = new ClassifiedsRepository();
public Member Member { get; private set; }
public SelectList Municipalities { get; private set; }
public ClassifiedsFormViewModel(Member member)
{
Member = member;
Municipalities = new SelectList(classifiedsRepository.GetMunicipalities()
,"MunicipalityId", "Municipality1");
}
}
public ActionResult Create()
{
Member member = new Member();
Item item = new Item();
member.Items.Add(item);
return View(new ClassifiedsFormViewModel(member));
}
//
// POST: /Items/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Member member)
{
if (ModelState.IsValid)
{
try
{
classifiedsRepository.Add(member);
classifiedsRepository.Save();
return RedirectToAction("Create", new { id = member.MemberId });
}
catch
{
ModelState.AddModelErrors(member.GetRuleViolations());
}
}
return View(new ClassifiedsFormViewModel(member));
}
}

The member which is passed into the create function is actually databound from your form. In order to ensure that it works you have to have the elements on the form named the same as the properties in your member. So if you have something called memberName in Member you would need to name the field in the view the same thing.
<form ...
<input type="text" name="memberName"/>
...
</form>
Edit:
After reading your comments I'm still not 100% what you're looking to do. IF you want the member you've created to have an item then move the item creation code down to the second Create. What you have passes a member with an item through to a strongly typed view. The member with the item is never persisted so it won't come back to the controller and won't make it into the model.

public ActionResult Create()
{
Member member = new Member();
Item item = new Item();
member.Items.Add(item);
return View(new ClassifiedsFormViewModel(member));
}

Related

Asp.net Core Value from Selected Item in the SelectBox is 0

So I have managed to populate a select box using SelectList(...) and ViewData[...]. The items show up in the select box and I can select an item. The text for the select box is the category Name and the Value is the MenuCategoryID. I then save the value linked to the text in the MenuCategoryId property in the model. The issue is that when the user selects an item it seems to save the value as 0, it then passes that in the model to the post request in the controller. Every other value in the model is fine and correct, it is just the value retrieved from the select box.
This is my GET Request:
public async Task<IActionResult> Create()
{
List<MenuCategoryViewModel> Categories = await _Context.MenuCategories.ToListAsync();
ViewData["Categories"] = new SelectList(Categories, "MenuCategoryId", "Name");
return View();
}
This is my SelectBox:
<select asp-for="MenuCategoryId" class="form-control" asp-items="ViewBag.Categories"></select>
This is my MenuCategoryId property:
[Required]
public int MenuCategoryId { get; set; }
This is my POST request:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("MenuItemId,Name,Description,MenuCategoryID")] MenuItemViewModel menuItem)
{
if (ModelState.IsValid)
{
_Context.Add(menuItem);
await _Context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(menuItem);
}
I tested your code, i changed this part of code in the Create Method:
[Bind("MenuItemId,Name,Description,MenuCategoryID")
For:
[Bind("MenuItemId,Name,Description,MenuCategoryId")
MenuCategoryId equals to property in the MenuItemViewModel class.
It works fine.

Multiple models in same view in asp.net mvc 4

I'm using asp.net mvc 4 & Entity Framework 6 to make a website where after user login, the table records will show & the ID of the user will show as Session. But when I run, after login, I get this error, Object reference not set to an instance of an object. I've made a custom model where two DbSet from seperate EF6 models are attached. My code is below,
Custom Model
public class MkistatVsUserLogin
{
public sample_1 sample_1 { get; set; } //Login Model
public IEnumerable<mkistat> mkistats { get; set; } //Table Model
}
Controller
[HttpPost]
public ActionResult Login(sample_1 id)
{
if (ModelState.IsValid)
{
var uservar = db.sample_1.Where(a => a.boid.Equals(id.boid)).FirstOrDefault();
if (uservar != null)
{
Session["UserBOID"] = uservar.boid.ToString();
return RedirectToAction("UserLogin");
}
}
var mkimodel = new MkistatVsUserLogin { mkistats = dsedb.mkistats.ToList() };
return View(id);
return View(mkimodel);
}
View
#model ABCoLtd.Models.MkistatVsUserLogin
#if (Session["UserBOID"] != null)
{
<li>Welcome, <b>#Session["UserBOID"].ToString()</b></li>
}
<a class="btn btn-default" href="#Url.Action("UserLogout", "Home")">Log Out</a>
#foreach (var item in Model.mkistats)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.MKISTAT_ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.MKISTAT_PHONE_NO)
</td>
</tr>
}
Is there something wrong with my code? If it is then please give me a solution. All I want is to use both models at the same view where user login model will be used in Session & table model to list all the records.
Remove bellow line
return View(id);
and in your return View line also mention View or ActionMethod name
return View("ViewName",mkimodel)
In your action method, Use Session to pass ID
Session["UserID"] = id;
You can use the same in your View as :
<html>
-----Your CODE
<body>
------Your CODE
#Session["UserID"]
------Your CODE
</body>
</html>
You can create a ViewModel to handle :
namespace ABCoLtd.ViewModels
{
public class LoginVM
{
public MkistatVsUserLogin MkistatVsUserLogin {get;set;}
public int Id {get;set;}
}
}
and in action pass this way:
var mkimodel = new MkistatVsUserLogin { mkistats = dsedb.mkistats.ToList() };
LoginVM vm = new LoginVM();
vm.MkistatVsUserLogin = mkimodel ;
vm.Id = id;
return View(vm );
and in View set model to LoginVM:
#model ABCoLtd.ViewModels.LoginVM
UPDATE:
you already have a viewmodel didnt noticed that, you just need to do this:
var mkimodel = new MkistatVsUserLogin
{
mkistats = dsedb.mkistats.ToList(),
sample_1 = id
};
return View(nkimodel);
After login you are directly redirecting your user to an action and that action you have not mentioned here.And that action whose view you have shown is an strongly typed view which expects a list of MkistatVsUserLogin. But, I think you are not passing that list, so Model property of view will remain null and that will be causing an error of object reference. Please check this issue.
I got it. I just made another method in controller for viewing table with user session.
[HttpPost]
public ActionResult Login(sample_1 id)
{
if (ModelState.IsValid)
{
var uservar = db.sample_1.Where(a => a.boid.Equals(id.boid)).FirstOrDefault();
if (uservar != null)
{
Session["UserBOID"] = uservar.boid.ToString();
return RedirectToAction("UserLogin");
}
}
return View(id);
}
public ActionResult UserLogin()
{
if(Session["UserBOID"] != null)
{
var mkimodel = new MkistatVsUserLogin { mkistats = dsedb.mkistats.ToList() };
return View(mkimodel);
}
else
{
return RedirectToAction("Login");
}
}

show details view in mvc 3

HI i am new to mvc so if anyone can help me will be great
basically i just want to display a partiular item details, my code
private sneakerEntities
_sneaker_categoryDataModel = new sneaker_info.Models.sneakerEntities();
public ActionResult Index()
{
IList<sneaker> Releases = _sneaker_categoryDataModel.sneakers.ToList<sneaker_info.Models.sneaker>();
return View("Releases", Releases);
}
//
// GET: /Home/Details/5
public ActionResult Details (int id)
{
return View();
}
You need to find it from Repository and display in your strongly typed view
public ActionResult Details (int id)
{
Sneaker snkr=_sneaker_categoryDataModel.sneakers.Find(id);
return View(snkr);
}
In Details.cshtml
#model Sneaker
//all view related code
private sneakerEntities
_sneaker_categoryDataModel = new sneaker_info.Models.sneakerEntities();
public ActionResult Index()
{
IList<sneaker> Releases = _sneaker_categoryDataModel.sneakers.ToList<sneaker_info.Models.sneaker>();
// populate your IList with values here
return View("Releases", Releases);
}
After this Add a View By right clicking on this Action.
You will have a view Created which will have the First line as
#model IList<sneaker>
if not change it to this. Now write this syntax to retrieve values from each item of the list
#foreach(var data in Model)
{
//#data.Whatever
#data.Name
}

Passing multiple dropdownlist items between pages

I use Asp.Net MVC. I have 4 dropdownlist in my page.
1- Car Company (40 items)
2- Model (30 items)
3- Year (20 items)
4- Engine(20 items)
when user select this item go to details page.In details page i want fill ddl and select item user was selected.
I have some ideas about this but i am not sure its right way.
1- post dropdownlist to controller and return back to detail page
2- write dropdownlist to cookie
or any other ideas ?
Create a view model like this
public class FilterVM
{
public List<SelectListItem> Makes{ set;get;}
public int SelectedMake { set;get;}
public List<SelectListItem> Models { set;get;}
public int SelectedModel { set;get;}
public List<SelectListItem> Years{ set;get;}
public int SelectedYear { set;get;}
public List<SelectListItem> Engines{ set;get;}
public int SelectedEngine { set;get;}
public FilterVM()
{
Makes=new List<SelectListItem>();
Models=new List<SelectListItem>();
Years=new List<SelectListItem>();.
Engines=new List<SelectListItem>();
}
}
Now in your GET action
public ActionResult Search()
{
var vm=new FilterVM();
vm.Makes=LoadMakesFromSomewhere();
return View(vm);
}
private List<SelectListItem> LoadMakesFromSomewhere()
{
var lst=new List<SelectListItem>();
lst.Add(new SelectListItem { Value="1", Text="Ford"});
lst.Add(new SelectListItem { Value="2", Text="Honda"});
return lst;
}
And in your view which is strongly typed to your FilterVM. We will write some javascript to handle the change event of the dropdowns so that it will read the selected item value and send an ajax request to get the content for the next dropdown .
#model FilterVM
#using(Html.BeginForm())
{
<label>Make</label>
#Html.DropDownListFor(s=>s.SelectedMake,Model.Makes,"Select")
<label>Make</label>
#Html.DropDownListFor(s=>s.SelectedModel,Model.Models,"Select")
<label>Make</label>
#Html.DropDownListFor(s=>s.SelectedYear,Model.Years,"Select")
<label>Make</label>
#Html.DropDownListFor(s=>s.SelectedEngine,Model.Engines,"Select")
<input type="submit" />
}
<script type="text/javascript">
$(function(){
//code to load Models dropdown when user selects Make
$("#SelectedMake").change(function(){
var items="";
$.getJSON("#Url.Action("GetModels","Car")/"+$(this).val(),function(res){
$.each(function(index,item){
items+="<option value='"+item.ID+'>"+item.Name+"</option>";
});
$("#SelectedModel").html(items);
});
});
//Write other dropdown filling code like above
});
</script>
Now you should have a GetModels method which accepts the Selected Make's ID and returns the models in JSON format.
public ActionResult GetModels(int id)
{
var modelList=repositary.GetModelsFromMakeID(id);
return Json(modelList,JsonRequestBehaviour.AllowGet);
}
Your JSON which you are returning should look something like this (and ID and Name in each item.
[
{
"ID": 4,
"Name": "Accord"
},
{
"ID": 5,
"Name": "CRV"
}
]
Write the change event handler for other dropdowns also. Finally when the user posts the form, you can check the SelectedMake,SelectedModel,SelectedYear property values.
[HttpPost]
public ActionResult Search(FilterVM model)
{
check for model.SelectedMake, model.SelectedYear etc..
//to do : Get result and show in a view/redirect.
}
You can use ViewBag,ViewData or TempData object to hold such values

ASP.NET MVC passing query result from controller to view

How to print the result of query in View page for ASP.NET MVC?
My code is:
public ActionResult Index()
{
var list = from m in db.MenuTables
select m.MenuName;
return View(list);
}
Now what should i write to print the result of this query in View Page?
Personally, I would get in the habit of having ViewModels and then strongly typing your View, to that model.
The model will expose ONLY THE DATA you want to display. Nothing more, nothing less. So let's assume you want to display the Name, Price and some other meta data.
Pseudo-code:
//View Model
public class MenuItem
{
public string Name { get; set; }
public decimal Price { get; set; }
public bool IsVegetarian { get; set; ]
}
public class IndexViewModel
{
public IList<MenuItem> MenuItems { get; set; }
public string MaybeSomeMessage { get; set; }
}
//in Controller
public ActionResult Index()
{
// This gets the menu items from your db, or cache or whatever.
var menuItemsFromDb = GetMenuItems();
// Let's start populating the view model.
IndexViewModel model = new IndexViewModel();
// Project the results to your model.
IList<MenuItems> menuItems = null;
if (menuItemsFromDb != null)
{
model.MenuItems = (from menuItem in menuItemsFromDb
select new MenuItem() {
Name = menuItem.Name,
Price = menuItem.Price,
IsVegetarian = menuItem.IsVegetarian
}).ToList();
}
// Anything else...
model.MaybeSomeMessage = "Hi There!";
return View(model);
}
//in View
#model IndexViewModel
<h3>#Model.MaybeSomeMessage</h3>
<ul>
#foreach(var item in Model.MenuItems)
{
<li>#item.Name - $ #item.Price</li>
}
</ul>
etc..
Note I've skipped some error checking, etc.
The point: only pass what you need.
At first, you may think this is much more code than is necessary. The best answer I can suggest to that thought, is that in the long run, you'll thank yourself for getting in the habit of this because the view should only ever know about the exact data it requires.
Nothing more, nothing less. Sending the least amount of data means you have a very light and simple view which will make your support/debugging much better. Next, you'll be able to unit test your controllers with a lot more intelligence and smarts, when you get to that.
Assuming that list is an IEnumerable of strings (i.e. that MenuName is a string).
In your view, accept the model IEnumerable<string>
#model IEnumerable<string>
and then enumerate it
#foreach( string s in Model )
{
<div>
#s
</div>
}
The first thing you want to do is call ToList() or else you could possibly be executing the same SQL query multiple times.
public ActionResult Index()
{
var list = (from m in db.MenuTables
select m.MenuName).ToList();
return View(list);
}
Secondly, I wouldn't just pass up a full list like that. You should create a ViewModel. That will allow you to pass up more data later on with a smaller effort.
public ActionResult Index()
{
var model = new IndexModel();
model.Tables = db.MenuTables.ToList();
model.AnotherValue = "MENUS";
return View(model);
}
Now we are on the view, you will need to set the model and iterate the table.
#model IndexModel
<h3>#Model.AnotherValue</h3>
<ul>
#foreach( var table in Model.Tables) {
<li>#table.Name<li>
}
</ul>
public ActionResult Index()
{
var list = from m in db.MenuTables
select m.MenuName;
return View(list);
}
//In View
#model IEnumerable<ProjectName.models.MenuTables>
#foreach(var item in Model)
{
#item.Field_Name
}

Resources