ASP.NET MVC bool value returned from the view is 1 or 0 - asp.net-mvc

I am using ASP.NET MVC, and I have some problems using a CheckBoxFor. Here is my problem:
I have the following code in the view:
#Html.CheckBoxFor(model => model.stade, new { #id = "stade" })
model.stade is of type bool. In my controller, I have:
//Editar
[HttpPost]
public ActionResult InvoiceType(int Id, string Name, string Code, string Stade)
{
clsInvoiceTypea Model = new clsInvoiceType();
Model.Id = Id;
Model.Name = Name;
Model.Code = Code;
Model.Stade = stade== "1" ? true : false;
return PartialView(Model);
}
I get an error, because when Model.Stade is submitted to the view the value is 1 or 0, and I get an error saying "Can not recognize the string as a valid Boolean", but if Model.stade is boolean why the model is submitted to the view like 0 or 1? How I can I resolve this?

Here goes my solution -
Let your Model be -
public class clsInvoiceTypea
{
public int Id { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public bool stade { get; set; }
}
Let your HttpGet Action be -
public ActionResult GetInvoice()
{
clsInvoiceTypea type = new clsInvoiceTypea();
return View(type);
}
And the corresponding view -
#model YourValidNameSpace.clsInvoiceTypea
#{
ViewBag.Title = "GetInvoice";
}
<h2>GetInvoice</h2>
#using (Html.BeginForm("SubmitData","Home",FormMethod.Post)) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>clsInvoiceTypea</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Code)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Code)
#Html.ValidationMessageFor(model => model.Code)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.stade)
</div>
<div class="editor-field">
#Html.CheckBoxFor(model => model.stade)
#Html.ValidationMessageFor(model => model.stade)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Let the following be your HttpPost Action -
[HttpPost]
public ActionResult SubmitData(clsInvoiceTypea model)
{
return View();
}
When you run the code, you will get following view -
When you select the checkbox and hit the create button, if you put a breakpoint on POST method and check the value, you will get true.

Related

Passing values from the view to the controller in MVC4

I'm trying to pass these textbox values to the controller:
#model DTOs.QuestionDTO
#{
ViewBag.Title = "AddQuestion";
}
<h2>AddQuestion</h2>
#using (Html.BeginForm("AddQuestionDB", "Exam"))
{
<fieldset>
<legend>Add Question</legend>
<div class="editor-label">
#Html.LabelFor(model => model.QuestionDes)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.QuestionDes , new { #id="question" , #name="question"})
#Html.ValidationMessageFor(model => model.QuestionDes)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Answer1)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Answer1 , new { #id="a1" , #name="a1"})
#Html.ValidationMessageFor(model => model.Answer1)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Answer2)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Answer2 , new { #id="a2" , #name="a2"})
#Html.ValidationMessageFor(model => model.Answer2)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Answer3)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Answer3 , new { #id="a3" , #name="a3"})
#Html.ValidationMessageFor(model => model.Answer3)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Answer4)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Answer4 , new { #id="a4" , #name="a4"})
#Html.ValidationMessageFor(model => model.Answer4)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Correct)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Correct , new { #id="correct" , #name="correct"})
#Html.ValidationMessageFor(model => model.Correct)
</div>
<p>
<input type="submit" value="Add" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to Login", "Login")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
this is how my controller method looks like:
public ActionResult AddQuestionDB(string question, string a1, string a2, string a3, string a4, string correct)
{
ViewBag.a1 = a1;
ViewBag.a2 = a2;
ViewBag.a3 = a3;
ViewBag.a4 = a4;
ViewBag.correct = correct;
return View();
}
And i have created a View to display this Viewbag variables... but these variables wont come up.
it seem to be that these variables are null..
#{
ViewBag.Title = "AddQuestionDB";
}
<h2>AddQuestionDB</h2>
<p>#Session["q"]</p>
<p>#ViewBag.question</p>
<p>#ViewBag.a1</p>
<p>#ViewBag.a2</p>
<p>#ViewBag.a3</p>
<p>#ViewBag.a4</p>
<p>#ViewBag.correct</p>
this is how my DTO looks like:
namespace DTOs
{
public class QuestionDTO
{
public int ID { get; set; }
public string QuestionDes { get; set; }
public string Answer1 { get; set; }
public string Answer2 { get; set; }
public string Answer3 { get; set; }
public string Answer4 { get; set; }
public int Correct { get; set; }
}
}
Can you please explain, how i should do this??
thank you!!!
Instead of -
public ActionResult AddQuestionDB(string question, string a1, string a2, string a3, string a4, string correct)
{
// Your custom code
return View();
}
have this code -
public ActionResult AddQuestionDB(QuestionDTO question)
{
// Use 'question' object here to get posted values.
return View();
}
I replicated your scenario in a small sample project on my local, here is the outcome when I debugged the code with breakpoint -
Html.EditorFor does not support setting attributes, which is why your original code wasn't working. The name attribute didn't match the parameter names in your controller action, so they were assigned null.
You can either use #ramiramilu's answer, or you could use TextBoxFor instead:
#Html.TextBoxFor(model => model.Correct , new { id="correct" , Name="correct"})
(Note that Name must be capitalized in order for this to work).
Example: https://dotnetfiddle.net/ZfzCaZ

ASP.NET MVC 4 Create method has null object

I have problem with creating object but I don't know why. I have null object in parameter in Post Create method and in ModelState I get this error:
{System.InvalidOperationException: The parameter conversion from type
'System.String' to type 'BlanskoMenu.Models.ActionOffer' failed
because no type converter can convert between these types. at
System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo
culture, Object value, Type destinationType) at
System.Web.Mvc.ValueProviderResult.UnwrapPossibleArrayType(CultureInfo
culture, Object value, Type destinationType) at
System.Web.Mvc.ValueProviderResult.ConvertTo(Type type, CultureInfo
culture) at
System.Web.Mvc.DefaultModelBinder.ConvertProviderResult(ModelStateDictionary
modelState, String modelStateKey, ValueProviderResult
valueProviderResult, Type destinationType)}
These are my methods in controller:
//
// GET: /Action/
public ActionResult Index()
{
var offers = _repository.GetAllActionOffers();
return View(offers);
}
//
// GET: /Action/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Action/Create
[HttpPost]
public ActionResult Create(ActionOffer action)
{
try
{
if (ModelState.IsValid)
{
_repository.CreateActionOffer(action);
return RedirectToAction("Index");
}
return View(action);
}
catch
{
return View(action);
}
}
This is my ActionOffer model:
public class ActionOffer
{
[Key]
public int Id { get; set; }
public string Text { get; set; }
public string Title { get; set; }
public string ImagePath { get; set; }
[DataType(DataType.Date)]
public DateTime StartDate { get; set; }
[DataType(DataType.Date)]
public DateTime EndDate { get; set; }
}
And this is my Create view:
#model BlanskoMenu.Models.ActionOffer
#{
ViewBag.Title = "Vytvořit akční nabídku";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Vytvořit akční nabídku</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Akční nabídka</legend>
#Html.HiddenFor(model => model.Id)
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Text)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Text)
#Html.ValidationMessageFor(model => model.Text)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ImagePath)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ImagePath)
#Html.ValidationMessageFor(model => model.ImagePath)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.StartDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.StartDate)
#Html.ValidationMessageFor(model => model.StartDate)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EndDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EndDate)
#Html.ValidationMessageFor(model => model.EndDate)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Thanks for help
Try changing
public ActionResult Create(ActionOffer action)
to
public ActionResult Create(ActionOffer actionOffer)

InvalidOperationException in Razor View with MVC4

I'm trying to build a flashcard application to learn MVC4. A Set contains Cards, and a Card contains Sides (to facilitate one or many-sided cards).
I have the following viewModel for Card Creation:
public class CreateCardViewModel
{
[HiddenInput(DisplayValue = false)]
public int SetId { get; set; }
[Required]
public ICollection<Side> Sides { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime DateCreated { get; set; }
[Required]
public bool IsReady { get; set; }
}
And the following actions defined for Create:
[HttpGet]
public ActionResult Create(int setId)
{
var model = new CreateCardViewModel();
// attach card to current set
model.SetId = setId;
// create a new Side
var side = new Side() {Content = "Blank Side"};
// Add this to the model's Collection
model.Sides = new Collection<Side> { side };
return View(model);
}
[HttpPost]
public ActionResult Create(CreateCardViewModel viewModel)
{
if (ModelState.IsValid)
{
var set = _db.Sets.Single(s => s.SetId == viewModel.SetId);
var card = new Card {Sides = viewModel.Sides};
set.Cards.Add(card);
_db.Save();
}
return View(viewModel);
}
In the view, I'm trying to start by displaying the Side that I created in the Controller, and allowing the user to edit it. I get "InvalidOperationException: Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions." when I try to run with the following markup in the view:
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>CreateCardViewModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.SetId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SetId)
#Html.ValidationMessageFor(model => model.SetId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DateCreated)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.DateCreated)
#Html.ValidationMessageFor(model => model.DateCreated)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.IsReady)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.IsReady)
#Html.ValidationMessageFor(model => model.IsReady)
</div>
// OFFENDING CODE
#foreach (var side in Model.Sides)
{
#Html.EditorFor(model => model.Sides.ElementAt(side.SideId))
}
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
How can I let the user edit the existing Side when creating a card?
Instead of using ElementAt(), just use the normal [] index operator:
#Html.EditorFor(model => model.Sides[side.SideId])

ICollection from ViewModel showing up as null, modelstate is not valid in MVC4

I have the following viewModel:
public class CreateCardViewModel
{
[HiddenInput(DisplayValue = false)]
public int SetId { get; set; }
[Required]
public ICollection<Side> Sides { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime DateCreated { get; set; }
[Required]
public bool IsReady { get; set; }
}
And the following actions defined for Create:
[HttpGet]
public ActionResult Create(int setId)
{
var model = new CreateCardViewModel();
// attach card to current set
model.SetId = setId;
// create a new Side
var side = new Side() {Content = "Blank Side"};
// Add this to the model's Collection
model.Sides = new Collection<Side> { side };
return View(model);
}
[HttpPost]
public ActionResult Create(CreateCardViewModel viewModel)
{
if (ModelState.IsValid)
{
var set = _db.Sets.Single(s => s.SetId == viewModel.SetId);
var card = new Card {Sides = viewModel.Sides};
set.Cards.Add(card);
_db.Save();
}
return View(viewModel);
}
When I try to create a new card, the Sides property of the viewModel is null, so the ModelState is coming up as null. I can't quite figure out why that initial Side isn't getting passed with the model.
My View looks like this:
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>CreateCardViewModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.SetId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SetId)
#Html.ValidationMessageFor(model => model.SetId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DateCreated)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.DateCreated)
#Html.ValidationMessageFor(model => model.DateCreated)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.IsReady)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.IsReady)
#Html.ValidationMessageFor(model => model.IsReady)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
There's nothing in your View that is bound to the Sides property of your ViewModel. Without anything in the form to hold the value of that property, it will be null when model binding occurs. You'll need to somehow capture the Side in your form - how are you adding to/removing from this property? Via user interaction that should take place on the form?
Try adding a second argument on Create() of type ICollection<Side> and see if that gets anything passed to it.

EF database-first generated form won't validate

I've just created a new controller, along with its CRUD forms, etc, with a database-first EF model/entity.
Its throwing a number of validation errors on save, but since the form has validators, I don't see why this would be so.
For reasons that are beyond me, I'm not getting any validation to happen at all. It just goes right in to the saveChanges() call, which promptly fails.
Here's the edit form:
#model StatementsApplication.DAL.StatementTask
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>StatementTask</legend>
<div class="editor-label">
#Html.LabelFor(model => model.sInitials)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.sInitials)
#Html.ValidationMessageFor(model => model.sInitials)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.dtCompleted)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.dtCompleted)
#Html.ValidationMessageFor(model => model.dtCompleted)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.sGroupLabel)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.sGroupLabel)
#Html.ValidationMessageFor(model => model.sGroupLabel)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.nGroupSequence)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.nGroupSequence)
#Html.ValidationMessageFor(model => model.nGroupSequence)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.sTaskType)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.sTaskType)
#Html.ValidationMessageFor(model => model.sTaskType)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.sTaskLabel)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.sTaskLabel)
#Html.ValidationMessageFor(model => model.sTaskLabel)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.nTaskSequence)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.nTaskSequence)
#Html.ValidationMessageFor(model => model.nTaskSequence)
</div>
#Html.HiddenFor(model => model.ID)
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
and here's the generated model:
namespace StatementsApplication.DAL
{
using System;
using System.Collections.Generic;
public partial class StatementTask
{
public int StmtBatchID { get; set; }
public string sInitials { get; set; }
public Nullable<System.DateTime> dtCompleted { get; set; }
public string sGroupLabel { get; set; }
public double nGroupSequence { get; set; }
public string sTaskType { get; set; }
public string sTaskLabel { get; set; }
public double nTaskSequence { get; set; }
public int ID { get; set; }
public virtual StatementBatch tblStmtBatch { get; set; }
}
}
and here's the controller bits...
//
// GET: /StatementTask/Edit/5
public ActionResult Edit(int id = 0)
{
StatementTask statementtask = db.StatementTasks.Find(id);
if (statementtask == null)
{
return HttpNotFound();
}
ViewBag.StmtBatchID = new SelectList(db.StatementBatches, "ID", "sStatus", statementtask.StmtBatchID);
return View(statementtask);
}
//
// POST: /StatementTask/Edit/5
[HttpPost]
public ActionResult Edit(StatementTask statementtask)
{
if (ModelState.IsValid)
{
try
{
db.Entry(statementtask).State = EntityState.Modified;
db.SaveChanges();
}
catch (Exception ex) {
throw ex;
}
return RedirectToAction("Index");
}
ViewBag.StmtBatchID = new SelectList(db.StatementBatches, "ID", "sStatus", statementtask.StmtBatchID);
return View(statementtask);
}
Its a matter of some confusion for me as to why sInitials is throwing 'required' validation errors, as well as why sGroupLabel is throwing length validation errors.
Thanks
a) your model has no data validation annotations. As such, MVC doesn't do any validation, because you're not telling it what to validate.
b) You don't mention what you are submitting. Are you just submitting an empty form?
it appears that Data Annotations will resolve this issue
[Required(AllowEmptyStrings = true)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public object Note { get; set; }
via http://fendy-huang.blogspot.com/2011/04/how-to-pass-empty-string-in-entity.html

Resources