Passing wrong model to dictionary - c#

First post here, so i'm sorry if this post is not very good!
I am currently building a web application using asp.net, and ran in to this problem:
The model item passed into the dictionary is of type 'Daily_Planner.Models.DayPlanPartialview', but this dictionary requires a model item of type 'Daily_Planner.Models.Group'
It seems like I am having a problem with passing on the right model. I am using several partial views and I am afraid that I may be using my models wrong, however I can not find out what it is. I have tried giving some adequate information, however if you need more I will be more than willing to post more of the code.
Partial view _GroupManage:
#model IEnumerable<Daily_Planner.Models.Group>
<select>
#foreach (var item in Model)
{
<option value="#item.Id">#item.GroupName</option>
}
</select>
Partial view _layout:
#if (Request.IsAuthenticated)
{
#Html.ActionLink("Daily Planner", "Index", "Home", new { area = "" }, new { #class = "navbar-brand" })
}
else
{
#Html.ActionLink("Daily Planner", "Login", "Account", new { area = "" }, new { #class = "navbar-brand" })
}
#if (Request.IsAuthenticated)
{
{ Html.RenderPartial("_GroupManage"); }
#Html.Partial("_LoginPartial")
}
Model:
namespace Daily_Planner.Models
{
public class DayPlanPartialview
{
public DayPlan displayComments { get; set; }
public Group groupM { get; set; }
public IEnumerable<Daily_Planner.Models.DayPlan> ListofComments { get; set;}
public IEnumerable<Daily_Planner.Models.Group> groupmanage{ get; set; }
}
HomeController
namespace Daily_Planner.Controllers
{
public class HomeController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
private DayPlanPartialview pv = new DayPlanPartialview();
[Authorize]
public ActionResult Index()
{
// Add list of comments with newest comment first // .Take(10).ToList(); will only show the last 10 posts
pv.ListofComments = db.DayPlans.OrderByDescending(x => x.DateCreated).ToList();
return View(pv);
}
[HttpPost]
[Authorize]
public ActionResult Index(DayPlanPartialview dayP)
{
dayP.displayComments.ApplicationUserId = User.Identity.GetUserId();
dayP.displayComments.DateCreated = DateTime.Now;
db.DayPlans.Add(dayP.displayComments);
db.SaveChanges();
pv.ListofComments = db.DayPlans.ToList();
return RedirectToAction("");
}
#model IEnumerable<Daily_Planner.Models.Group>
<select>
#foreach (var item in Model)
{
<option value="#item.Id">#item.GroupName</option>
}
</select>

Related

How to pass collection from view to controller in asp.net MVC4

I want to pass a collection of skills id from my view to controller action, i have a dropdownlist of SKILLS :
<select name="skills">
<option value="0">Java</option>
<option value="1">C++</option>
<option value="2">Fortran</option>
<option value="3">ASP</option>
</select>
i want that user can select many skills from dropdown and store their value in a collection ,i.e an array, and then post that array to action in controller as follow [employee and skills have a manytomany relationship]:
[HttpPost]
public ActionResult AddEmp(Employee emp ,IEnumerable<Skills> skills )
{
DBCtx db=new DbCtx();
db.employees.Add(emp);
var emp_id=db.SaveChanges();
var employee=db.employees.Find(emp_id);
foreach(item in skills)
{
var skill = db.skills.Find(item);
employee.skills.Add(skill);
}
db.SaveChanges();
return View();
}
How can i achieve this ,thanks in advance ....
You have quite few options on front end . Razor, Angular, Jquery... To simplfy things in following example i have used Razor view. I dont think you need to pass Skills as a strongly type object as you only need Id of selected Skills . Also in the example i have the skills list static / hard coded into razor view, ideally it should be bound from backend.
Saying that lets assume our Employee View Model as it follows
public class EmployeeViewModel
{
public EmployeeViewModel()
{
SelectedSkills=new List<int>();
}
public int Id { get; set; }
public string Name { get; set; }
public List<int> SelectedSkills { get; set; }
}
public class Skills
{
public int Id { get; set; }
public string Name { get; set; }
}
Then our Controller (EmployeeController.cs) would be .(please ignore the EF logic after data is bound to class)
public class EmployeeController : Controller
{
public ActionResult Index()
{
return View("Employee",new EmployeeViewModel());
}
[HttpPost]
public ActionResult AddEmp(EmployeeViewModel employee)
{
var idOfEmployee=AddEmployee(employee);
foreach (var item in employee.SelectedSkills)
{
AddSkill(idOfEmployee,item);
}
return View("Employee");
}
private void AddSkill(int idOfEmployee, int skillId)
{
// your EF logic
}
private int AddEmployee(EmployeeViewModel emp)
{
// your EF logic, get your id of the inserted employee
return 0;
}
}
Then our Employee.cshtml view could be
#using System.Web.UI.WebControls
#using WebApplication4.Controllers
#model WebApplication4.Controllers.EmployeeViewModel
#{
ViewBag.Title = "Employee";
}
<h2>Employee</h2>
#{var listItems = new List<Skills>
{
new Skills { Id = 0,Name="Java" },
new Skills { Id = 1,Name="C++" },
new Skills { Id = 2,Name="Fortran" }
};
}
#using (Html.BeginForm("AddEmp", "Employee"))
{
#Html.TextBoxFor(m => m.Name, new { autofocus = "New Employee" })
<br/>
#Html.ListBoxFor(m => m.SelectedSkills,
new MultiSelectList(listItems, "Id", "Name",#Model.SelectedSkills)
, new { Multiple = "multiple" })
<input type="submit" value="Submit" class="submit"/>
}

C# ASP.NET MVC - Model gets nulled on POST

I've been struggling with this problem for a while now and I can't find any solution on that solves it for me.
I'm trying to add a string to my model in a view, however when the model gets returned to my HttpPost everything is null except for the string that I'm trying to fill
My model looks like this
namespace WhatsUp.Models {
public class ChatModel
{
public Account user { get; set; }
public Contact contact { get; set; }
public Chat chatA { get; set; }
public Chat chatB { get; set; }
public string newMessage { get; set; }
public ChatModel() { }
public ChatModel(Account user, Contact contact, Chat chatA, Chat chatB)
{
this.user = user;
this.contact = contact;
this.chatA = chatA;
this.chatB = chatB;
}
}
}
My controller looks like this
namespace WhatsUp.Controllers
{
public class ChatsController : Controller
{
IMessageRepository repository = new DbMessageRepository();
IContactRepository contactRepository = new DbContactRepository();
IAccountRepository accountRepository = new DbAccountRepository();
IChatRepository chatRepository = new DbChatRepository();
// GET: Chats
public ActionResult Index()
{
return View();
}
public ActionResult Chat(int contactId)
{
Account user = accountRepository.GetAccount(User.Identity.Name);
Contact contact = contactRepository.GetContact(contactId);
Chat chatA = chatRepository.GetChat(user.id, contact.accountId ?? default(int));
if(chatA == null)
{
chatRepository.CreateChat(user.id, contact.accountId ?? default(int));
}
Chat chatB = chatRepository.GetChat(contact.accountId ?? default(int), user.id);
if(chatB == null)
{
chatRepository.GetChat(user.id, contact.accountId ?? default (int));
}
ChatModel chatModel = new ChatModel(user, contact, chatA, chatB);
return View(chatModel);
}
[HttpPost]
public ActionResult Chat(ChatModel chatModel)
{
repository.SendMessage(new Message(0, chatModel.newMessage, chatModel.chatA.Id));
ModelState.Clear();
return View(chatModel);
}
}
}
And my view
#using WhatsUp.Models
#model ChatModel
#{
ViewBag.Title = "Chat";
}
<h2>Chat with #Model.contact.name</h2>
<div id="chatWindow" style="overflow-y:auto; overflow-x:hidden; height:500px;">
<script>
var element = document.getElementById('chatWindow');
element.scrollTop = element.offsetHeight
</script>
</div>
#using (Html.BeginForm())
{
#Html.TextAreaFor(x => x.newMessage, new { #class = "form-control"})
<input type="submit" value="Send" class="btn btn-primary" />
}
Always use a ViewModel for that kind of things. Follow this steps:
First, create a ViewModel that will contain your message and the chat ids.
Second, ake the ids as a hidden field in your view.
Last thing is, in your POST action, to make sure to get each Chat instance via their id before sending the message.

MVC4 get list of checkboxes in controller

I have a list of checkboxes generated in the View using the following code:
using (Html.BeginForm("UpdateItems", "Home", FormMethod.Post)) {
foreach (myProject.Models.item t in ViewBag.Items)
{
<div>
#Html.CheckBox("chkT", t.selected, new { id = "chkT" + t.id })
#Html.Label(t.description)
</div>
}
<button type="submit" class="mfButton" value="SaveItemss">Save Changes</button>
}
What I need to is to be able to get the values of these generated checkboxes in the controller. So far I have the following:
public ActionResult UpdateItemss(List<bool> chkT)
{
return View();
}
However this being a boolean only give me true or false and the id of the values to which they belong. Is there a way get the name/value pair?
Thanks
Rather than using ViewBag, I would use strongly typed view. I would create a model and add the lists as property. My Models should look like:
public class Test
{
public int Id { get; set; }
public List<Item> Items { get; set; }
}
public class Item
{
public int Id { get; set; }
public bool Selected { get; set; }
public string Description { get; set; }
}
In the controller I am passing the model with dummy data:
public ActionResult Index()
{
Test model = new Test()
{
Id = 1,
Items = new List<Item>()
{
new Item {Id = 1, Selected = false, Description = "Item1"},
new Item {Id = 2, Selected = false, Description = "Item2"},
new Item {Id = 3, Selected = false, Description = "Item3"}
}
};
return View(model);
}
In my View I am using for loop to generate list of Items:
#model MVCTest.Models.Test
#using (Html.BeginForm("UpdateItems", "Home", FormMethod.Post)) {
#Html.HiddenFor(m=>m.Id)
for (int i = 0; i < Model.Items.Count; i++)
{
<div>
#Html.HiddenFor(m=>m.Items[i].Id)
#Html.CheckBoxFor(m=>m.Items[i].Selected, new {id = "checkbox_" + i} )
#Html.DisplayFor(m=>m.Items[i].Description)
</div>
}
<button type="submit" class="mfButton" value="SaveItemss">Save Changes</button>
}
In the controller I am catching the posted model and find all Items inside its Items property:
[HttpPost]
public ActionResult UpdateItems(Test model)
{
if (model != null)
{
// You can access model.Items here
//Do whatever you need
}
return View(model);
}
I would suggest to read this blog: ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries.

Knockout and InitializeViewBag method (MVC)

Visual studio doesn't understand method InitializeViewBag("Simple list") from example below.
How does it make? Does this method exist?
Why in this example, it is used : Example
Model
public class SimpleListModel
{
public string ItemToAdd { get; set; }
public List<string> Items { get; set; }
public void AddItem()
{
Items.Add(ItemToAdd);
ItemToAdd = "";
}
}
Razor
#using PerpetuumSoft.Knockout
#model KnockoutMvcDemo.Models.SimpleListModel
#{
var ko = Html.CreateKnockoutContext();
}
#using (ko.Html.Form("AddItem", "SimpleList", null, new { id = "myform" }))
{
<span>New item:</span>
#ko.Html.TextBox(m => m.ItemToAdd).ValueUpdate(KnockoutValueUpdateKind.AfterKeyDow n)
<button type="submit" #ko.Bind.Enable(m => m.ItemToAdd.Length >
}
Controller
public class SimpleListController : BaseController
{
public ActionResult Index()
{
InitializeViewBag("Simple list");
var model = new SimpleListModel { Items = new List<string> { "Alpha", "Beta", "Gamma" } };
return View(model);
}
public ActionResult AddItem(SimpleListModel model)
{
model.AddItem();
return Json(model);
}
}
Looking at the source code for BaseController in github, I can see that InitializeViewBag method is defined there. That's how SimpleListController has access to it. If you have that same exact implementation of BaseController and the method is still not recognised, I would think it's something annoying, like an extra bracket here or there, or a duplicate BaseController somewhere else.

ASP.NET MVC - Modelbinding with Dropdownlist

Is it possible to have a single view model with a list that is used for a dropdownlist and also get the selected value of the dropdownlist from the view model when I post a form?
If so, how can I do this?
Sure, as always start by defining your view model:
public class MyViewModel
{
public int? SelectedItemValue { get; set; }
public IEnumerable<Item> Items { get; set; }
}
public class Item
{
public int? Value { get; set; }
public string Text { get; set; }
}
then the controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
// TODO: Fill the view model with data from
// a repository
Items = Enumerable
.Range(1, 5)
.Select(i => new Item
{
Value = i,
Text = "item " + i
})
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// TODO: based on the value of model.SelectedItemValue
// you could perform some action here
return RedirectToAction("Index");
}
}
and finally the strongly typed view:
<% using (Html.BeginForm()) { %>
<%= Html.DropDownListFor(
x => x.SelectedItemValue,
new SelectList(Model.Items, "Value", "Text")
) %>
<input type="submit" value="OK" />
<% } %>

Categories