DropDownListFor Razor with List<string> - asp.net-mvc

using (Html.BeginForm("Add", "Test", new { profil = Model.SelectedProfil }, FormMethod.Post))
{
#Html.DropDownListFor(m => m.SelectedProfil, new SelectList(Model.Profils.Select(x => new { Value = x, Text = x }),"Value","Text"))
<button type="submit">Add</button>
}
Profils = List of string
SelectedProfil = string
SelectedProfil is always null to the controller on post

Simply
using (Html.BeginForm("Add", "Test", FormMethod.Post))
#Html.DropDownList("profil", new SelectList(Model.Profils.Select(x => new { Value = x, Text = x }),"Value","Text")))
[HttpPost]
public ActionResult Add(string profil)
{
....
}

Related

The parameters dictionary contains a null entry for parameter 'messageId' MVC

This error appears when I'm training to post reply message and insert it in Replies Table using message id , I think the problem from the View when the id is calling
#using (Html.BeginForm("ReplyMessage", "Messages", FormMethod.Post, new
{ id = "form-reply-message", messageId = #ViewBag.MessageId }))
Any idea what I should change
Controller Get Method:
public ActionResult ReplyMessage(int? Id, int? page)
{
MessageReplyViewModel vm = new MessageReplyViewModel();
if (Id != null)
{
var replies = dbContext.Replies.Where(x => x.MessageId == Id.Value).OrderByDescending(x => x.ReplyDateTime).ToList();
if (replies != null)
{
foreach (var rep in replies)
{
MessageReplyViewModel.MessageReply reply = new MessageReplyViewModel.MessageReply();
reply.MessageId = rep.MessageId;
reply.Id = rep.Id;
reply.ReplyMessage = rep.ReplyMessage;
reply.ReplyDateTime = rep.ReplyDateTime;
reply.MessageDetails = dbContext.Messages.Where(x => x.Id == rep.MessageId).Select(s => s.MessageToPost).FirstOrDefault();
reply.ReplyFrom = rep.ReplyFrom;
vm.Replies.Add(reply);
}
}
else
{
vm.Replies.Add(null);
}
ViewBag.MessageId = Id.Value;
}
return View(vm);
Controller PostMethod :
[HttpPost]
[Authorize]
public ActionResult ReplyMessage(MessageReplyViewModel vm, int messageId)
{
if (vm.Reply.ReplyMessage != null)
{
Models.Reply _reply = new Models.Reply();
_reply.ReplyDateTime = DateTime.Now;
_reply.MessageId = messageId;
_reply.ReplyMessage = vm.Reply.ReplyMessage;
dbContext.Replies.Add(_reply);
dbContext.SaveChanges();
}
return RedirectToAction("Index", "Message");
View :
#using (Html.BeginForm("ReplyMessage", "Messages", FormMethod.Post, new { id = "form-reply-message", messageId = #ViewBag.MessageId }))
{
if (!ViewData.ModelState.IsValid)
{
#Html.ValidationSummary(true)
}
#Html.HiddenFor(model => model.Reply.MessageId);
#Html.TextAreaFor(p => p.Reply.ReplyMessage, new { #rows = 2, #class = "form-control" })
#Html.ValidationMessageFor(model => model.Reply.ReplyMessage)
<input type="submit" class="btn btn-primary btn-success" value="Reply" id="btn-reply-message">
}
You may have to bind it using [FromQuery] attribute here:
public ActionResult ReplyMessage(MessageReplyViewModel vm, [FromQuery("messageId")] int messageId)
{
........
}
This attributes reads the values after the "?" operator in the URL. Hopefully it will help!

PartialView data not posting back to controller

I am loading the partial view based on dropdownlist value as suggested in the following links. I am able to show partial View and enter values in textboxes. But when I postback, I am unable to get values in Controller. I am getting all other values except this partial view values
Render Partial View Using jQuery in ASP.NET MVC
div id="divFloorPlans"></div>
$('#ddlFloorPlans').change(function () {
var numberOfFloorPlans = $(this).val();
var data = { "id": numberOfFloorPlans };
$.ajax({
url: "FloorPlans",
type: "POST",
data: data, //if you need to post Model data, use this
success: function (result) {
$("#divFloorPlans").html("");
$("#divFloorPlans").html(result);
}
});
});
#model IList<ViewModels.FloorPlan>
#for (int i = 1; i <= Model.Count; ++i)
{
<div class="col-md-12" >
<div class="col-md-2" >
#Html.DropDownListFor(m => m[i - 1].Bedrooms, ViewData["Bedrooms"] as List<SelectListItem> })
</div>
<div class="col-md-2" >
#Html.DropDownListFor(m => m[i - 1].Bathrooms, ViewData["Bathrooms"] as List<SelectListItem> })
</div>
<div class="col-md-3" >
#Html.TextBoxFor(m => m[i - 1].MinPrice})
#Html.TextBoxFor(m => m[i - 1].MinPrice })
</div>
<div class="col-md-3">
#Html.TextBoxFor(m => m[i - 1].MinSqFt, new { #placeholder = "From" })
#Html.TextBoxFor(m => m[i - 1].MaxSqFt, new { #placeholder = "To"})
</div>
</div>
}
My Model looks like this.
public class ItemEditVM
{
public FloorPlan FloorPlan { get; set; }
public IList<FloorPlan> ListFloorPlans { get; set; }
}
My Controllers
//Partial View Returning Controller
[HttpPost]
public ActionResult FloorPlans(int id)
{
var model = new ItemEditVM();
model.NumOfFloorplans = id;
model.ListFloorPlans = new List<FloorPlan>();
for (int i = 0; i < id; i++)
{
model.ListFloorPlans.Add(new FloorPlan { FloorPlanName = "", Bathrooms = "", Bedrooms = "", MaxPrice = "", MinPrice = "", MaxSqFt = "", MinSqFt = "" });
}
return View("FloorPlan", model.ListFloorPlans);
}
//Create Controller
[HttpPost]
public ActionResult Create(ItemEditVM model)
{
if (ModelState.IsValid)
{
}
}
You partial views model is IList<FloorPlan> which is generating controls with
<input name="[0].MinPrice" ..>
<input name="[1].MinPrice" ..>
which would post back to IList<FloorPlan> model, but your method parameter is ItemEditVM model. You need to the partial view model to be #model ItemEditVM
In the GET method
return View("FloorPlan", model);
and in the view
#model ItemEditVM
#for (int i = 1; i <= Model.ListFloorPlans.Count; ++i)
{
....
#Html.TextBoxFor(m => m.ListFloorPlans[i - 1].MinPrice})
....
}
which will generate the correct name attributes for binding to your model
<input name="ListFloorPlans[0].MinPrice" ..>
<input name="ListFloorPlans[1].MinPrice" ..>

Selected value for dropdownlistfor in mvc4

I have created a ViewBag selectlist in Edit action and set the value to be selected as:
ViewBag.Doors = new SelectList(
new[]
{
new {ID = 1, Name="1-Door"},
new {ID = 2, Name="2-Doors"},
new {ID = 3, Name="3-Doors"},
new {ID = 4, Name="4-Doors"},
new {ID = 5, Name="5-Doors"},
new {ID = 6, Name="6-Doors"},
new {ID = 7, Name="7-Doors"}
},
"ID", "Name", advert.Doors);
But in the view the value for the dropdown is not selected by default.
My view code is:
#Html.DropDownListFor(model => model.Doors, (SelectList)ViewBag.Doors, "--Select--")
#Html.ValidationMessageFor(model => model.Doors)
The property Doors will be numeric 1,2,3,..
How will I do it using Annonymous type in ViewBag ?
Overload
Controller Action Method
public ActionResult DropDownListFor()
{
ViewBag.Doors = new SelectList(
new[]
{
new {Value = 1,Text="1-Door"},
new {Value = 2,Text="2-Door"},
new {Value = 3,Text="4-Door"},
new {Value = 4,Text="4-Door"},
new {Value = 5,Text="5-Door"},
new {Value = 6,Text="6-Door"},
new {Value = 7,Text="7-Doors"}
}, "Value", "Text", 7);
return View();
}
View
#Html.DropDownList("Doors")
How will I do it using SelectListItem?
Action Method
[HttpGet]
public ActionResult DropDownListFor()
{
List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem { Text = "Action", Value = "0" });
items.Add(new SelectListItem { Text = "Drama", Value = "1" });
items.Add(new SelectListItem { Text = "Comedy", Value = "2",
Selected = true });
items.Add(new SelectListItem { Text = "Science Fiction", Value = "3" });
ViewBag.MovieType = items;
return View();
}
View
#using (Html.BeginForm("Action", "Controller", FormMethod.Post))
{
#Html.DropDownList("MovieType")
}
How will I do it using View Model?
View
#using (Html.BeginForm("Action", "Controller", FormMethod.Post))
{
#Html.DropDownListFor(m => m.Id, Model.DDLList, "Please select");
}
Action Method
[HttpGet]
public ActionResult DropDownListFor()
{
return View(new Models.Dropdown());
}
View Model
public class Dropdown
{
public string Id { get; set; }
public List<SelectListItem> DDLList
{
get
{
return new List<SelectListItem>()
{
new SelectListItem
{
Text = "1-Door",
Value = "1",
Selected = true
},
new SelectListItem
{
Selected = false,
Value = "2",
Text = "2-Door"
}
};
}
}
}

problems with html helper method

I can't figure out how to send a parameter from a dropdownlist to my model. Could someone please show me an example of how to do this?
As always you start by defining a model:
public class MyViewModel
{
public string SelectedValue { get; set; }
public SelectList Items
{
get
{
return new SelectList(new[]
{
new SelectListItem { Value = "1", Text = "item 1" },
new SelectListItem { Value = "2", Text = "item 2" },
new SelectListItem { Value = "3", Text = "item 3" },
}, "Value", "Text");
}
}
}
Controller:
public class HomeController: Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// You will get the selected value inside model.SelectedValue here
// => do something with it
....
}
}
Strongly typed view:
<% using (Html.BeginForm()) { %>
<%= Html.DropDownListFor(x => x.SelectedValue, Model.Items) %>
<input type="submit" value="OK" />
<% } %>
public ActionResult Edit(int id)
{
Affiliate affiliate = affiliateRepository.GetAffiliate(id);
List<SelectListItem> StateList = new List<SelectListItem>();
SelectListItem item;
Dictionary<string, string> dictState = S127Global.Misc.getStates();
foreach (KeyValuePair<string, string> k in dictState)
{
item = new SelectListItem();
item.Text = k.Value;
item.Value = k.Key;
StateList.Add(item);
}
item = new SelectListItem();
item.Text = " - Select State - ";
item.Value = "";
StateList.Insert(0, item);
//create new select list with affiliate.state as the selected value in ViewData
ViewData["State"] = new SelectList(StateList.AsEnumerable(), "Value", "Text",affiliate.State);
return View(affiliate);
}
code for view
<div class="editor-label">
<%: Html.LabelFor(model => model.State) %>
</div>
<div class="editor-field">
<%: Html.DropDownList("State")%>
<%: Html.ValidationMessageFor(model => model.State) %>
</div>

MVC - Problem with DataBinding to a Collection using a Custom Template

I am trying to bind to a Model that has a collection property, specifically a List. For the purposes of this example, this represents a list of user roles:
public class RolesModel
{
private List<SelectListItem> _Roles = null;
public string Name { get; set; }
public List<SelectListItem> Roles
{
get {
if (_Roles == null) { _Roles = new List<SelectListItem>(); }
return _Roles;
}
set { _Roles = value; }
}
}
I am binding this to a strongly-typed view via the following Controller:
public class TestController : Controller
{
RolesModel myModel = new RolesModel();
[HttpGet]
public ActionResult Edit()
{
myModel.Name = "Joe Bloggs";
myModel.Roles = new List<SelectListItem>
{
new SelectListItem { Value = "1", Text = "Member", Selected = true },
new SelectListItem { Value = "2", Text = "Manager", Selected = true },
new SelectListItem { Value = "3", Text = "Administrator", Selected = false }
};
return View(myModel);
}
[HttpPost]
public ActionResult Edit(RolesModel m)
{
// !!! m.Roles is always empty !!!
return View("Results", m);
}
}
This then invokes the following view:
#model MyProject.WebUI.Models.RolesModel
#using (Html.BeginForm())
{
<p>
#Html.LabelFor(m => m.Name)
#Html.EditorFor(m => m.Name)
</p>
<div>
#Html.EditorFor(m => m.Roles, "CheckBoxList")
</div>
<p>
<input type="submit" value="Save" />
</p>
}
Note the template specific call to my custom editor template in '/Views/Shared/EditorTemplates/CheckBoxList.cshtml' this looks like this:
#model List<System.Web.Mvc.SelectListItem>
<h3>Type: #Html.LabelFor(m => m)</h3>
<ul>
#for (int i = 0; i < Model.Count; i++)
{
<li>
#Html.CheckBoxFor(m => m[i].Selected)
#Html.LabelFor(m => m[i].Selected, Model[i].Text)
#Html.HiddenFor(m => m[i].Value)
</li>
}
</ul>
The idea being that each SelectListItem is represented by the Html rendered by the loop.
The first part of the process appears to work correctly, The form is presented as expected and you can update the 'Name' text box and the check/uncheck the checkboxes.
The problem is that when the form is posted back to the controller, the Roles collection is never populated.
I'm new to MVC and thought that the framework actually re-constructed the model data from the post via the enforced form element naming convention. I'm obviously missing an important point and I'm hoping someone can point me in the right direction.
Thanks, and apologies for the long post.
Here's how you could proceed:
#model MyProject.WebUI.Models.RolesModel
#using (Html.BeginForm())
{
<p>
#Html.LabelFor(m => m.Name)
#Html.EditorFor(m => m.Name)
</p>
<div>
<ul>
#Html.EditorFor(m => m.Roles)
</ul>
</div>
<p>
<input type="submit" value="Save" />
</p>
}
and inside the EditorTemplate (/Views/Shared/EditorTemplates/SelectListItem.cshtml):
#model System.Web.Mvc.SelectListItem
<h3>Type: #Html.LabelFor(m => m)</h3>
<li>
#Html.CheckBoxFor(m => m.Selected)
#Html.LabelFor(m => m.Selected, Model.Text)
#Html.HiddenFor(m => m.Value)
</li>
Notice the simplification of the editor template. It no longer takes a List<SelectListItem> as model but simply a SelectListItem. It will automatically be invoked for each element of the Roles collection so that you don't need to write any loops. Just follow the conventions.
I would also simplify your view model like this:
public class RolesModel
{
public string Name { get; set; }
public IEnumerable<SelectListItem> Roles { get; set; }
}
and your controller:
public class TestController : Controller
{
public ActionResult Edit()
{
var myModel = new RolesModel
{
Name = "Joe Bloggs",
Roles = new[]
{
new SelectListItem { Value = "1", Text = "Member", Selected = true },
new SelectListItem { Value = "2", Text = "Manager", Selected = true },
new SelectListItem { Value = "3", Text = "Administrator", Selected = false }
}
};
return View(myModel);
}
[HttpPost]
public ActionResult Edit(RolesModel m)
{
// m.Roles should be correctly bound
return View("Results", m);
}
}

Resources