Check Box Value Passed In FormCollection MVC Form - c#

I have a FormCollection being passed back to a controller, which is processed, however, the value passed back if its true is 'true,false' but if it's unchecked it's just 'false'. My field uses iChecks.
My object that is being built is as follows:
field.IsSelected = Convert.ToBoolean(form["Field.IsChecked"]);
What would be the best method to get the correct value?

I would suggest doing :
form["Field.IsChecked"].Contains("true")
Which already returns a bool so you dont have to convert.
OR
You could go:
Convert.ToBoolean(form["Field.IsChecked"].Split(',').First());
or
Convert.ToBoolean(form["Field.IsChecked"].Split(',')[0]);

It would be better to use the Model Binder for this purpose, it is the right way for doing this nowadays, you can simply add a boolean property to your model class, and then use the checkbox helper of MVC.
public class YourViewModel
{
public bool IsChecked { get; set; }
}
And your ActionMethod:
public async Task<ActionResult> Index(YourViewModel viewModel)
{
field.IsSelected = viewModel.IsChecked;
}
And your view something like this:
#using (Html.BeginForm("Index", "YourController", FormMethod.Post))
{
<div>
#Html.CheckBox("IsChecked")
</div>
<input type="submit" value="Submit" />
}

This worked for me
Convert.ToBoolean(form["Field.IsChecked"].Split(',').First());

Related

How to access and change an HTML control's value in an ASP.NET MVC action without returning to the view?

Is it possible to set an HTML control's value directly from the action in ASP.NET?
I'm used to UWP app development and the way we do this is to simply select the control by name and just set it's value to whatever we want it to be, is there a similar way of doing that?
I've created a simple POC.
CS:
[HttpPost]
public ActionResult Index(TestViewModel model)
{
for (int i = 0; i < model.Counter; i++)
{
Thread.Sleep(1000);
// lblCounter should take the counter's value here, maybe something like lblCounter.Text = i.ToString(); :P
}
return View();
}
View:
#model LiveCounterPOC.Models.TestViewModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.TextBoxFor(p=>p.Counter);
<input type="submit" value="Start Counter" />
}
<label id="lblCounter"></label>
Model:
public class TestViewModel
{
public int Counter { get; set; }
}
I know I have to use an ajax function, but i'm not sure when to call it or what is should it be.
Thanks
You can't access the View controls from within the action method in MVC, this is not how MVC works.

pass multiple values/parameters from view to mvc controller shorter way

Im new to MVC.. and started to grasp it. I am wondering whether there's a shorter way to pass parameters from view to mvc controller. I am creating a search box with possible conditions.
here's the sample code in the view
#using (Html.BeginForm("Action", "Controller", FormMethod.Get))
{
<p>
Find by fname: #Html.TextBox("fname", ViewBag.CurrentFilter as string)
<br/>
Find by lname: #Html.TextBox("lname", ViewBag.CurrentFilter as string)
<br/>
By Area Code : #Html.TextBox("AreaCode")
<br/>
#Html.DropDownList("StateCD", new SelectList(ViewBag.State))
<br/>
<input id="Button1" type="submit" value="Search"/>
</p>
}
in my controller
public async Task<ActionResult> Action(string id, string sortorder, string statecd,int? page,string country,string areacode,string city,string zip,string z)
{
}
is there a way to shorten that parameter like as an object or concatenated values?
You can create a class to represent your search filter and use that as the action method parameter type.
public class SearchVm
{
public strng StateCd { set;get;}
public string AreaCode { set;get;}
public string Zip { set;get;}
// Add other needed properties as well
}
and use that as the param
public async Task<ActionResult> Search(SearchVm model)
{
// check model.AreaCode value etc..
// to do : Return something
}
When the form is submitted Default Model binder will be able to map the posted form data to properties of the method parameter object, assuming your form field name's match with the class property names

ASPNET MVC 5 Html helper Action method view results input id missing (sometimes..) Possible Bug?

To recreate the issue I'm having I've set up two simple controller actions, two views and a view model:
MultiForms Action (in the form controller class)
public class FormController : Controller
{
[HttpGet]
public ActionResult MultiForms()
{
return View("MultiForms");
}
// ...
MultiForms.cshtml - Razor View
#Html.Action("MyFormGet", "Form")
Notice in the action method I call the controller method that returns the form partial view.
MyFormGet Action
[HttpGet]
public PartialViewResult MyFormGet()
{
var viewModel = new MyFormViewModel();
ViewData.TemplateInfo.HtmlFieldPrefix = Guid.NewGuid().ToString().Replace("-", "_");
return PartialView("MyForm", viewModel);
}
View Model
public class MyFormViewModel
{
public string TextInput1 { get; set; }
}
MyForm.cshtml - Razor View
#model Mvc5App.Controllers.MyFormViewModel
#using (Html.BeginForm("MyFormPost", "Form", FormMethod.Post))
{
<br />
#Html.TextBoxFor(m => m.TextInput1)
}
When I point my browser at /Form/MultiForms I get the output I expect:
<input type="text" value="" name="e166fa0d_46fe_40d4_a970_73c52a35f224.TextInput1" id="e166fa0d_46fe_40d4_a970_73c52a35f224_TextInput1">
Then I refresh the page and the output becomes this:
<input type="text" value="" name="48edc339_69ad_4b9b_9583_198038beab45.TextInput1">
Where did the id attribute go? Is this a bug in ASPNET MVC5 or have I done something wrong with this setup?
Thanks to #demo I think I figured out when the id doesn't show up...
If the id starts with a digit(or underscore) it will not render. So this GUID will render:
f3b1a447_3786_4472_9dfe_14c3ae8aae24
But this one will not:
1c26ce3d_5c71_408a_aae2_7be414f1d383
The solution for the above seems to be prefixing with something like this:
FOO_1c26ce3d_5c71_408a_aae2_7be414f1d383
And the problems go away.

ModelView data not passed from View to Controller

My problem is that strongly typed data passed from my Controller to my view comes out empty (all it's properties are null).
I would also like to bind selected value in radiobuttons (marked as QUESTION2) to model property "GivenAnwser" but it doesn't seem to work either.
Type passed around is a ViewModel
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
QuestionViewModel question = Manager.GetQuestion();
return View(question);
}
[HttpPost]
public ActionResult Index(QuestionViewModel question,Anwser givenAnwser)
{
//QuestionViewModel is returned but all it's properties are null.
return View(question);
}
}
VIEW
#model Quiz.ViewModels.QuestionViewModel
#{
ViewBag.Title = "Home Page";
}
#Html.Label("Question:")
#if (Model.CorrectAnwser != null)
{
//some code
}
#Html.DisplayFor(model => model.Question.Text)
//I have tried with Hidden fields and without them
#Html.HiddenFor(model => model.Question)
#Html.HiddenFor(model => model.Anwsers)
#using (Html.BeginForm("Index", "Home"))
{
foreach (var anwser in Model.Anwsers)
{
//QUESTION 2
<input type="radio" name="givenAnwser" value="#anwser" />
<label>#anwser.Text</label>
<br />
}
<input type="submit" value="Check!" />
}
QuestionViewModel
public class QuestionViewModel
{
public QuestionViewModel()
{
this.Anwsers = new List<Anwser>();
}
public Question Question { get; set; }
public List<Anwser> Anwsers { get; set; }
public Anwser GivenAnwser { get; set; }
public bool CorrectAnwser { get; set; }
}
EDIT:
ModelState contains an error:
"The parameter conversion from type 'System.String' to type 'Quiz.Models.Anwser' failed because no type converter can convert between these types."
<input type="radio" name="givenAnwser" value="#anwser" />
this line is setting a complex type "#answer" as the value of the radio button.
this might just do a ToString() of the type during rendering.
When you post it back, MVC might be trying to convert this string value back to
Quiz.Models.Anwser
and failing.
you should probably render
<input type="radio" name="givenAnwser" value="#anwser.SomeBooleanValue" />
p.s. also, why not use the Html Extension to render the radio button.
You can't bind a complex type (Question) to a Hidden field. You would need to bind to the separate child properties.
Also, for the answers, don't use a foreach, use a for loop. Like:
#for(var i=0;i<Answers.Count;i++)
{
<input type="radio" name="#Html.NameFor(a=>a.Answers[i].answer.Value)" value="#Model.Answers[i].anwser.Value" />
}
or
#for(var i=0;i<Answers.Count;i++)
{
#Html.RadioButtonFor(a=>a.Answers[i].answer,Model.Answers[i].answer.Value)
}
Although, that may not be correct either because Answers is a collection of a complex type as well, and you didn't share it's definition.
All in all, I don't think you really need (or want) to post back the entire Model back anyhow. Why not just post back the question ID, and the selected Answer?

Failed to pass routeValues to an action from partial view

I wanna add search functionality in my MVC application. This functionality should be available for all pages. So, I added it into the shared layout.
The only problem I have is that I'm not able to pass the routValues to the Search action in spite of I'm creating a new Form inside the partial view.
Target action:(performs the search)
[HttpPost]
public ActionResult Search(SearchModel keyword)
{
// keyword is always null
return RedirectToAction("SearchResult", keyword.keyword);
}
public class SearchModel { public string Keyword { get; set; } }
The Partial View:
#model DocuLine.Models.SearchModel
#using (Html.BeginForm("Search", "Home", FormMethod.Post))
{
#Html.EditorFor(model => model.Keyword)
<input type="submit" value="Search" />
}
Try
public ActionResult Search(SearchModel model)
Why the class is defined as Keyword and then view SearchResult you pass it as a keyword (lower case first letter)?
1 UpdateModel
You can update the class SearchModel with the method UpdateModel to check if you can make the correct assignment.
2 FormCollection
You can try to receive as parameter in the method Search form data (FormCollection) and check if you get what you require.
Finally, I solve it. The problem is that the SearchModel parameter name is keyword and it should be anything except keyword becuase there's already an html control is rendered with this name.
To solve it, it should only be named with another name:
public ActionResult Search(SearchModel model)
{
// model now has a value.
}

Categories