Passing values from the view to the controller in MVC4 - asp.net-mvc

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

Related

DropDownListFor in MVC 4

I am having a hard time to show dropdownlist for in the view, the values will be populated from database. I am using MS SQL Server as the database.
I want to show a drop down list in ApplyingFor which will be populated from database.
Please help me out.
This is the Model
public class CandidateProfile
{
[Display(Name = "Candidate Name")]
[Required(ErrorMessage = "Provide a Name", AllowEmptyStrings=false)]
[DataType(DataType.Text)]
public string CandidateName { get; set; }
[Required(ErrorMessage = "Provide Your Address",AllowEmptyStrings = false)]
[Display(Name = "Address")]
[DataType(DataType.MultilineText)]
public string Address { get; set; }
[Display(Name = "Phone Number")]
[Required(ErrorMessage = "Provide a Phone Number")]
[RegularExpression("^([07][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 8[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 9[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])$", ErrorMessage = "Enter Valid Mobile Number")]
public string PhoneNumber { get; set; }
[Display (Name = "Email-Id")]
[Required(ErrorMessage="Provide an email-id")]
[EmailValidator]
public string EmailId { get; set; }
[Display (Name = "Applying For")]
public string **ApplyingFor** { get; set; }
[Display (Name = "Experience")]
[Required(ErrorMessage = "")]
public int Experience { get; set; }
[Display (Name = "Present Location")]
[Required(ErrorMessage = "")]
public string PresentLocation { get; set; }
}
public class ApplyingPositions
{
public IEnumerable<ApplyingPositions> ApplyingPosition { get; set; }
}
public class ApplyingPosition
{
public int APId { get; set; }
public string Designation { get; set; }
}
This is the View:
#model Recruitment.Models.CandidateProfile
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>CandidateProfile</legend>
<div class="editor-label">
#Html.LabelFor(model => model.CandidateName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CandidateName)
#Html.ValidationMessageFor(model => model.CandidateName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNumber)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumber)
#Html.ValidationMessageFor(model => model.PhoneNumber)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmailId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmailId)
#Html.ValidationMessageFor(model => model.EmailId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ApplyingFor)
<div class="editor-field">
#Html.EditorFor(model => model.ApplyingFor)
#Html.ValidationMessageFor(model => model.ApplyingFor)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Experience)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Experience)
#Html.ValidationMessageFor(model => model.Experience)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PresentLocation)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PresentLocation)
#Html.ValidationMessageFor(model => model.PresentLocation)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
You need to pass the List of Options from your controller to view. So, before returning View
var listOfPositions = new List<ApplyingPosition>();
listOfPositions = //Call the service to populate the listOfPositions from Database here
ViewBag.PositionsList = new SelectList(listOfPositions, "APId", "Designation");
In your view instead of #Html.EditorFor(model => model.ApplyingFor)
#Html.DropDownListFor(m => m.ApplyingFor, (SelectList)ViewBag.PositionsList, "Select")
populate lstApplyingFor (list) form your DB. and in your controller
ViewBag.ApplyingFor = new SelectList(lstApplyingFor, "Id", "Name");
and in view:-
#Html.DropDownList(m => m.ApplyingFor,"ApplyingFor", "--Select--")
First-
1) You need to create the source for dropdown as-
var listForApplyingFor= db.Table.Select(o=> new SelectListItem{
Value=o.ID,
Text= o.Text
}).ToList();
ViewBag.ItemsApplyingFor= listForApplyingFor
.Cshtml View-
#Html.DropdownListFor(m=>m.ApplyingFor, new SelectList(ViewBag.ItemsApplyingFor,"Value","Text"),"Select...", htmlAttributes:new{ })
Let me know if it helps.

ASP.NET MVC bool value returned from the view is 1 or 0

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.

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)

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

DateTime required in ModelState, however never set to be

I have a DateTime field in my form. For whatever reason, everytime I submit the form ModelState comes back as invalid and a message that my date time field (called PostDate) is required, even though in the view model I don't have the required attribute set.
Does anyone know why this would be happening as I'm going around in circles trying to figure it out.
Here is the view model
public class BlogViewModel
{
[Required]
public string Title { get; set; }
[Required]
public string Content { get; set; }
public bool Published { get; set; }
public DateTime PostDate { get; set; }
}
Here is the controller actions
public ActionResult Create()
{
return View();
}
//
// POST: /Admin/Blog/Create
[HttpPost]
[ValidateInput(false)]
public ActionResult Create(BlogViewModel model)
{
if(ModelState.IsValid)
{
model.Content = HtmlSanitizer.SanitizeHtml(model.Content);
Services.BlogService.CreateBlogPost(model.Title, model.Content, User.Identity.Name);
return RedirectToAction("Index");
}
return View(model);
}
Here is the View
#using Payntbrush.Infrastructure.Mvc.Extensions
#model Payntbrush.Presentation.Demo.MVC3.Areas.Admin.Models.BlogViewModel
#Html.Resource(Html.ScriptTag("Areas/Admin/js/plugins/wysiwyg/jquery.wysiwyg.js"), ResourceType.Js)
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm((string)ViewBag.Action, "Blog", FormMethod.Post, new { Id = "BlogEditor" }))
{
#Html.ValidationSummary(true)
<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.Content)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.Content, new { #class = "wysiwyg blog-editor" })
#Html.ValidationMessageFor(model => model.Content)
</div>
<div class="editor-label">
Time of post (Only set this if you want to make a post appear to have been published at a different date.)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.PostDate, new{#class="datetimepicker"})
#Html.ValidationMessageFor(model => model.PostDate)
</div>
<div class="editor-label">
Published (Check to make this post live on the site)
</div>
<div class="editor-field">
#Html.CheckBoxFor(model => model.Published)
#Html.ValidationMessageFor(model => model.Published)
</div>
<p>
<input class="large awesome" type="submit" value="Create" />
#Html.ActionLink("Cancel", "Index", "Blog", null, new { #class = "large awesome cancel-button" })
</p>
}
<div>
</div>
If you leave the corresponding field empty your model will be invalid because DateTime is a value type. You should use a nullable DateTime if you want to allow empty values:
public DateTime? PostDate { get; set; }

Resources