Get checkbox names ASP.NET Core - c#

I want to take only selected checkboxes. I tried this.
<input class="form-check-input" type="checkbox" name="Box" value="LDL" />
<label for="Box">LDL</label><br>
<input class="form-check-input" type="checkbox" name="Box" value="LDL" />
<label for="Box">LDL</label><br>`enter code here`
<input class="form-check-input" type="checkbox" name="Box" value="HDL" />
<label for="Box">HDL</label><br>
<div class="button-holder d-flex justify-content-center">
<button type="submit" class="btn btn-success">Send</button>
</div>
This is the Action
[HttpPost]
public IActionResult SendTest(ListParams listParams)
{
}
This is the DTO
public class CheckboxParams
{
public string Box { get; set; }
public bool IsChecked { get; set; }
}
public class ListParams
{
public ListParams()
{
this.AllCheckedParams = new List<CheckboxParams>();
}
public List<CheckboxParams> AllCheckedParams { get; set; }
}

In asp.net core, Model binding looks through the sources for the name pattern prefix.property_name. If nothing is found, it looks for just property_name without the prefix. Besides, the nested array matches the [index].property_name or property_name[index].property_name.
In your code, the name of the checkbox could not match the property in ListParams model. The correct way should be AllCheckedParams[index].box.
But for your scenario, your model design is not correct. The browser will only send the selected checkbox to the backend by default when form submit. If you choose the first two or last two(anyway,that is to say the index should be consecutive) checkbox, it works well. If you choose the first and third checkbox, it does not work any more. Because the name of them is AllCheckedParams[0].box and AllCheckedParams[2].box. They are not consecutive index of the array, so only the first checkbox could be matched and passed to the backend.
The correct way is that just change your backend received data like below:
[HttpPost]
public IActionResult SendTest(string[] box)
{
}
If you still want to use the model, you need change the model like below:
public class ListParams
{
public List<string> Box { get; set; }
}
Controller:
[HttpPost]
public IActionResult SendTest(ListParams listParams)
{
}

The HtmlHelper class provides two extension methods to generate a element in an ASP.NET MVC view. They are as follows:
CheckBox()
CheckBoxFor()
for creating form in razor page you can use
#model Student
#Html.CheckBoxFor(m => m.isActive)
The Html.CheckBox() is a loosely typed method which generates a with the specified name, isChecked boolean, and HTML attributes.
#Html.CheckBox("isActive", true)

Related

How do I bind Html.DevExtreme().LookupFor list to model

I am using DevExtreme.LookupFor to show dropdown list and select an object element to my model
But always I got null to model property..
uisng asp.net core
This is my dropdownlist :
<div class="form-inline">
<label asp-for="Prop" class="control-label"></label>
<div class="form-inline formGroup">
#(Html.DevExtreme().LookupFor(m => m.Prop)
.DataSource(d => d.RemoteController()
.LoadUrl("/looks/Getlist"))
.DisplayExpr("Description")
.Width("100%")
.Value(Model.Prop)
)
</div>
<span asp-validation-for="Prop" class="text-danger"></span>
</div>
This is my mode :
#model Main.Vals.Code.Models.PropModule
This is the relevant important part for my question :
public class PropModule
{
// List
[Display(Name = "PARAMS")]
public Prop Prop { get; set; }
}
When Im using action I go to
<form class="formEntity" asp-controller="Cont" asp-action="Action">
In this action When I look on Modle.Prop Its show null also when I chose a variable
public IActionResult Action(PropModule Modle)
{
....
}
UI Picture of the dropdown list for example :
I
What I do wrong? Tell me if I miss any important information
I think you will need to add a
.ValueExpr("Whatever-your-key-is")
to the lookup, and this is what gets passed to the code-behind, so this should look like
public IActionResult Action(int key)
{
// lookup prop depending on key
}
The key has to be something that can be serialized (e.g. int, string, guid, etc.)
cheers

Passing multiple checkbox values to deeper level of model .net mvc

A few similar questions have been asked before but my use case is a bit different.
So this is my model:
public class YourModel
{
public string[] Suburb { get; set; }
}
And my view:
<input name="Suburb" type="checkbox" value="sydney" /><span>sydney</span>
<input name="Suburb" type="checkbox" value="melbourne" /><span>melbourne</span>
Controller:
public ActionResult AdvancedSearch(YourModel s)
{
// logic
}
So MVC is smart enough to retrieve the multiple checkbox values to put them in the Suburb array in YourModel model. I can inspect all values there. But my use case is that the YourModel is just the nested model inside another model MyModel:
public class MyModel
{
//other properties
public YourModel m { get; set; }
}
So now how do I make MVC post the checkbox values to a deeper model MyModel.YourModel? I have tried #Html.CheckBoxFor and #Html.CheckBox but neither of them worked.
Right now my work around is to add a temporary array placeholder in the outside model and then assign all the data to the inside model when available, but that is definitely not ideal.
You need to use add MyModel
<input name="m.Suburb" type="checkbox" value="sydney" /><span>sydney</span>
<input name="m.Suburb" type="checkbox" value="melbourne" /><span>melbourne</span>
In Razor, you don't have to define the name of the top-most Model, only the names of the properties of inner models:
<input name="m.Suburb" type="checkbox" value="sydney" /><span>sydney</span>
<input name="m.Suburb" type="checkbox" value="melbourne" /><span>melbourne</span>
However, I'd strongly suggest you to change that m name to something more significant.

Obtaining list of objects from client side in asp.net core 2.0

I'm new to asp.net core. I've been reading and I know now how to submit data on a form as an object to the code behind, through post methods. That's fine. But how about sending a list of objects? What I would need to do would be (in this example it would be for an hotel management room types and rate types) something like a grid where I have a list of room types, where each one has a list of rate types. How can I do this? as I've done it, I can pass through the name of the room type (only as one object, though) but not any rates.
I have it like this (models):
public class RateType
{
public string Name { get; set; }
public bool IsActive { get; set; }
}
public class RoomType
{
public string Name { get; set; }
public List<RateType> Rates { get; set; } = new List<RateType>();
}
In the HomeController:
public IActionResult RoomConfig()
{
return View(room);
}
[HttpGet]
public ViewResult SaveRoomConfig()
{
return View("RoomConfig");
}
[HttpPost]
public ViewResult SaveRoomConfig(RoomType room)
{
return View("RoomConfig");
}
And in the view:
#model RoomType
#{
ViewData["Title"] = "RoomConfig";
}
<h2>#Model.Name</h2>
<form class="p-a-1" asp-action="SaveRoomConfig" method="post">
#foreach (var item in Model.Rates)
{
<label asp-for="Name">#item.Name </label>
<input class="form-control" asp-for="Name" />
<input asp-for="#item.IsActive" type="checkbox" />
}
<button type="submit">Send</button>
</form>
So, I send an initial object with some pre-defined values just for testing and they are shown on the page. But then, when I click "send" I can only send the first object (makes sense, since I only have an object parameter, so it will send only the first one. Still, I tried putting a list of RoomType's to see what it did but it shows count as zero. So, how can I do it? Pass a list of objects with another list of objects (nested). Is this possible? It doesn't make sense to make to only have the possibility to pass one and only single object.
Ok, I realized why it wasn't working. I was doing everything right, except for the fact that I was binding items to an empty list which, by definition, didn't have any items. So, instead of a 'foreach', I wrote a 'for' statement, in order to get to the index. That way, I binded the object to the position on the list, instead of a non-existing object. Like this:
#model RoomType
#{
ViewData["Title"] = "RoomConfig";
}
<form class="p-a-1" asp-action="SaveRoomConfig" method="post">
<input asp-for="Name" />
#for (int i=0;i< Model.Rates.Count;i++)
{
<div class=" form-control">
<label asp-for="#Model.Rates[i].Name">#Model.Rates[i].Name </label>
<input asp-for="#Model.Rates[i].Name" />
<input asp-for="#Model.Rates[i].IsActive" type="checkbox" />
</div>
}
<button type="submit">Send</button>
</form>
Of course, if anyone has a better way to do this I'm all ears. :)

bind field value within period

I have a modelView that contains an Object, similar to this
public class ExampleModelView
{
public T object { get; set; }
public ExampleModelView()
{
//...
}
}
To get that in my view I use
#Html.TextBoxFor(model => model.object.attribute1)
So the above line returns a html with a period, which is giving me problems, like this
<input class="form-control"
id="object_attribute1"
name="object.attribute1"
type="text" value="..."
aria-required="true"
aria-invalid="false">
When I submit the form I'm not being able to bind the field value like this
public ActionResult Cadastrar([Bind(Include = "attribute1")] ExampleModelView t)
{
//...
}
or those other ways
public ActionResult Cadastrar(ExampleModelView t)
{
//...
}
public ActionResult Cadastrar([Bind(Prefix= "object.attribute1")] ExampleModelView t)
{
//...
}
So, if I change TextBoxFor to TextBox I can bind the object, but not my whole modelView.
What should I do in this case?
EDIT
Changed above LabelFor to TextBoxFor.
Question
How do I bind the attributes with the period?

Posting a list of complex objects in MVC with Razor

SCENARIO:
First of all, sorry for my english.
What I'm trying to do is posting trough form-POST the following object:
public class AppConfigViewModelInput
{
public string Setting { get; set; }
public string Value { get; set; }
}
to the following method:
[HttpPost]
public ActionResult Index(List<AppConfigViewModelInput> listOfAppConfigToUpdate)
{ ... }
But this input-object is constructed by only two properties of the view-object that I use to show the data on my razor page:
public class AppConfigViewModel : AppConfigViewModelInput
{
public string Description { get; set; }
public string ConfigType { get; set; }
public int ViewOrderInWebAdmin { get; set; }
public string ViewSpecialBackgroundColor { get; set; }
}
I was reading a lot of questions and blogs (check out SO References in the question). Finally I could get the following code for my razor page (I only post the form-code section):
#model List<PGWebAdmin.Models.AppConfigViewModel>
#{
var itemCnt = 0;
}
#foreach (var item in Model)
{
itemCnt++;
<input type="hidden" name="AppConfigViewModelInput.Index" value="#itemCnt" />
<input type="text" class="input-sm form-control" value="#item.Value" name="AppConfigViewModelInput[#itemCnt].Value"/>
<input type="text" name="AppConfigViewModelInput[#itemCnt].Setting" value="#item.Setting"/>
}
and the form is created by:
#using (Html.BeginForm("Index", "AppConfig",
FormMethod.Post, new { #class = "navbar-form navbar-right", role = "search" }))
{
QUESTION:
I could send the data, I'm checking with the dev tool the following information:
that is posted to the method, and the method is hit, but the value of the parameter is null:
I tested and corrected and tried several ways to do this but this is the far away I could get, and I can't understand what's happening.
I'm doing something wrong? Why I'm still getting null?
Any help will be preciated.
Thanks!
REFERENCES:
MVC post a list of complex objects
How can I post a list of items in MVC
Posting to a list<modeltype> MVC3
You need the change the name of the parameter to match what you are sending in the "name" field.
ie change your post controller:
[HttpPost]
public ActionResult Index(List<AppConfigViewModelInput> AppConfigViewModelInput)
{ ... }
Try this? It's maybe not the best answer but it should work for your purposes.
[HttpPost]
public ActionResult Index(AppConfigViewModelInput[] listOfAppConfigToUpdate)
{ ... }
And the html like this ..
#model List<PGWebAdmin.Models.AppConfigViewModel>
#{
var itemCnt = 0;
}
#foreach (var item in Model)
{
itemCnt++;
<input type="text" class="input-sm form-control" value="#item.Value" name="listOfAppConfigToUpdate[#itemCnt].Value"/>
<input type="text" name="listOfAppConfigToUpdate[#itemCnt].Setting" value="#item.Setting"/>
}
I removed the top input of index.. i don't see where it fits in. You can convert the array to a list inside your Index method.
I dont see the reason you send the AppConfigModelInput.Index, i think that might be your problem. The message you send should not contain data that is not part of the model
Your input file names are wrong ! Since your HttpPost action expects a collection of AppConfigViewModel. You don't really need the AppConfigViewModelInput. prefix for your input field names. For model binding to work, Your input field names should be like
<input type="hidden" name="[0].Index" value="" />
<input type="hidden" name="[1].Index" value=" />
Also make sure your form elements are in a form tag.
The below should work.
#model List<PGWebAdmin.Models.AppConfigViewModel>
#{
var itemCnt = 0;
}
#using (Html.BeginForm())
{
foreach (var item in Model)
{
<input type="hidden" name="[#itemCnt].Index" value="#itemCnt" />
<input type="text" value="#item.Value" name="AppConfigViewModelInput[#itemCnt].Value"/>
<input type="text" name="[#itemCnt].Setting" value="#item.Setting"/>
itemCnt++;
}
<input type="submit" value="Save" class="btn btn-default" />
}

Categories

Resources