I'm iterating a list to set the values for multiple Html.CheckBoxFor controls, but after submitting the form, I get a null value for the model itself in the controller parameter. Should I replace Html.CheckBoxFor with Html.HiddenFor for instance, the whole model binding works and FunctionViewModel is passed to the controller properly.
Model
public class FunctionViewModel
{
//... (this class is huge)
public MeasuringViewModel MeasuringViewModel { get; set; }
}
Classes used by the model
public class MeasuringViewModel
{
//... (this class is also huge)
public List<BatchItem> BatchToCancel { get; set; }
}
public class BatchItem
{
public bool IsCancel { get; set; }
public VMeasuringService VMeasuringService { get; set; }
public BatchItem(VMeasuringService vMeasuringService)
{
IsCancel = false;
VMeasuringService = vMeasuringService;
}
}
Controller
[HttpPost]
public ActionResult CancelBatch(FunctionViewModel viewModel)
{
// viewModel is null should I use CheckBoxFor
return View();
}
Form
#using (Html.BeginForm("CancelBatch", "Services", FormMethod.Post, new { Area = "Functions", #id = "cancelForm" }))
{
for(int i = 0; i < Model.MeasuringViewModel.BatchToCancel.Count; i++)
{
#Html.CheckBoxFor(m => m.MeasuringViewModel.BatchToCancel[i].IsCancel)
}
<input type="submit" id="btSubmit" title="Post" alt="Post" value="Post" />
}
So, what's wrong with it?
You get null because none of the control ids matching with your model properties, Check by Inspecting your html in browser that, is control ids generated by Razor are matching with your model properties?
secondly in this situation where you cannot give specific ids to your controls then you can get your control value in your controller action using FormCollection like given bellow:
[HttpPost]
public ActionResult CancelBatch(FormCollection fc)
{
// viewModel is null should I use CheckBoxFor
return View();
}
Related
I have problem i dont now how to fix it.
I have ViewModel
public class CartOrderViewModel
{
public Cart Carts;
public Order Orders;
public string name;
}
in CartController method
public async Task<IActionResult> Index()
{
CartOrderViewModel vm = new CartOrderViewModel
{
Carts = _cart,
Orders = new Order() { User = applicationUser },
};
return View(vm);
}
View Index from CartController
#using (Html.BeginForm("Test", "Cart", FormMethod.Post))
{
#Html.TextBoxFor(m => m.name)
<input type="submit" value="Submit" />
}
and in my method Test in CartController i dont see ViewModel CartOrderViewModel
[HttpPost]
public IActionResult Test(CartOrderViewModel test)
{
string komentarz = test.name;
return View();
}
Model: test in null.
Please help me. Thx a lot
How to send form from Index View from CartController my ViewModel CartOrderViewModel
example Model.Order.name ??
Why my name from CartOrderViewModel dont sent to method Test from index View ?
printscreen
enter image description here
Why my name from CartOrderViewModel dont sent to method Test from index View ?
ASP.NET binds to properties, not fields. Change all of the public fields in class CartOrderViewModel to be mutable properties with { get; set; }.
Like so:
public class CartOrderViewModel
{
public Cart? Carts { get; set; }
public Order? Orders { get; set; }
public String? Name { get; set; }
}
Don't forget to add validation attributes, such as [Required], as per your project's needs.
I have a model passed from controller to view in my asp.net mvc5 website. Then I show the dropdownlist using the model and I want to pass an id back when submitting the form. Here is my model :
public class SiteDirectionModel
{
public int id { get; set; }
public string name { get; set; }
}
Then in the model, I use a List<SiteDirectionModel> to which I add new instances of each item I need. I fill up both these lists and then pass my model to the view.
#model List<SiteDirectionModel>
#using (Html.BeginForm("GetSiteRF", "Create", FormMethod.Post))
{
#Html.DropDownListFor(x => x.name,new SelectList(Model.name,"Sites"));
<input type="button" value="Selectionner" class="btn btn-primary"/>
}
Then how to retrieve the ids for each name ? And how to pass it as a parameter to my controller? Such that I would have :
public ActionResult GetSiteRF(int id)
{
int newId = id;
//Call method to searchId ...
return View("CreateADUser");
}
I have given how to bind and get value from dropdown. Please use your own BL in this.
Your model should be like this.
public class Something
{
public int Id { get; set; }
public string Name { get; set; }
}
public class SiteDirectionModel
{
public SelectList MyDropDown { get; set; }
public int SelectedValue { get; set; }
}
You BL should be like this.
public List<Something> GetListofSomething()
{
//your logic.
}
Your Get method should be like this.
public ActionResult MyGetMethod()
{
SiteDirectionModel model = new SiteDirectionModel();
model.MyDropDown = new SelectList(GetListofSomething(), "key_field_name", "value_field_name", "default_value");
}
Then finally HTML
#Html.DropDownListFor(x => x.SelectedValue,Model.MyDropDown)
I have a model that contains a List of Milestone, I want that list to be populated (inside the model) with a given set of Textboxes in the webpage.
public class Project
{
public string ProjectNumber { get; set; }
public IList<Parameter> Parameters;
public IList<Milestone> MilestoneList = new List<Milestone>();
}
And inside my Html.BeginForm("Edit", "Home", FormMethod.Post, new { Project = Model })) I have the following TextBox.
#for (int i = 0; i < Model.MilestoneList.Count; i++)
{
<td style="align-content: center;">#Html.TextBoxFor(model=>model.MilestoneList[i].Value)</td>
}
My problem in my controller below the milestonelist is always null in model Project
[HttpPost]
public ActionResult Edit(Project project)
{
helper.CreateProject(project, System.Web.HttpContext.Current.User.Identity.Name);
return View();
}
So how should I program so the list inside the model will be populated through TextBoxes?
Your using fields in the model, not properties, so the DefaultModelBinder cannot set the value. Change you model to
public class Project
{
public string ProjectNumber { get; set; }
public IList<Parameter> Parameters { get; set; }
public IList<Milestone> MilestoneList { get; set; }
}
and initialize the collection in in the controller.
I'm rendering a PartialView via an Action on my controller.
This is sending a model to the partial which then populates a sub-list for each parent that the partial goes into.
Some of the parent objects don't have children.
I need to capture an Id from the model in the partial to link the sub-list into an Accordion control.
How do I prevent a null reference exception when the child model is empty?
Is there any way to send the ID direct from the Action?
Current attempt...
#using BootstrapSupport
#model IEnumerable<WhatWorks.ViewModels.FamilyListViewModel>
#{ if (string.IsNullOrEmpty(Model.FirstOrDefault().familyId.ToString()))
{
do something...
}
else
{
int modelIndex = Model.FirstOrDefault().familyId;
Controller Action
public ActionResult Index(int Id)
{
var model = GetDisplay(Id).OrderBy(i => i.dob).AsEnumerable();
return PartialView("_family", model);
}
Main View
var family = model.GetIdValue();
<div class="accordion" id="#Html.Raw("accordion")#family.Values.FirstOrDefault()#Html.Raw("_b")">
#Html.Action("Index", "Family", new { Id = family["Id"] })
</div>
ViewModel
public partial class FamilyListViewModel
{
public int Id { get; set; }
public int familyId { get; set; }
public string name { get; set; }
etc...
}
Then do this :
#{ if (Model.Count() >0 )
{
do something...
}
I have a List in my ViewModel I parse to the View
List<BoolSetting>
BoolSetting:
public class BoolSetting
{
public BoolSetting(string displayName, bool value)
{
DisplayName = displayName;
Value = value;
}
public string DisplayName { get; set; }
public bool Value { get; set; }
}
I then want to print a checkbox for all the items in my list, so the list is in the ViewModel the view uses
#foreach(var boolSettingList in Model.BoolSettingList)
{
<div>
#Html.CheckBox(boolSettingList.DisplayName, boolSettingList.Value)
#boolSettingList.DisplayName
</div>
}
The problem is when I post this then my Model have not saved the updated settings (The bool values) in the List in my ViewModel and therefore the object is empty.
I could do
foreach (var VARIABLE in userSettingConfigViewModel.BoolSettingList)
{
VARIABLE.Value = (bool)Request.Form[VARIABLE.DisplayName];
}
But this viewmodel will have many lists and some of them will have the same names! So that will cause conflicts
So is there a way to foreach print all my bools and then make MVC figure out to put the data back into the List object after? I cant get CheckBoxFor to work as it wants an expression and I cant figure out a way to itterate through my list that way
Can I maybe fix it with Templates, by making a template for BoolSetting and maybe List ?
Start by fixing your view model and removing the custom constructor or the default model binder won't be able to instantiate it and you will have to write custom model binders and stuff:
public class BoolSetting
{
public string DisplayName { get; set; }
public bool Value { get; set; }
}
public class MyViewModel
{
public List<BoolSetting> Settings { get; set; }
}
Then write a controller action that will populate your view model:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Settings = new[]
{
new BoolSetting { DisplayName = "name 1", Value = true },
new BoolSetting { DisplayName = "name 2", Value = false },
new BoolSetting { DisplayName = "name 3", Value = true },
}.ToList()
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
then a view (~/Views/Home/Index.cshtml) in which you simply use editor templates and don't write any foreach loops or weakly typed html helpers such as Html.CheckBox. By using editor templates you will ensure that all input fields will have correct names so that the default model binder is able to fetch their values into the view model during the postback:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.EditorFor(x => x.Settings)
<button type="submit">OK</button>
}
and finally the corresponding editor template for the view model which will be rendered for each element of the collection (~/Views/Home/EditorTemplates/BoolSetting.cshtml):
#model BoolSetting
<div>
#Html.CheckBoxFor(x => x.Value)
#Html.LabelFor(x => x.Value, Model.DisplayName)
#Html.HiddenFor(x => x.DisplayName)
</div>