submit a list become null in the post + MVC - asp.net-mvc

I have a ViewModel:
public class RegistrationViewModel
{
public string Country { get; set; }
public ConfigurationParamValue CountryParam { get; set; }
public string Civility { get; set; }
public ConfigurationParamValue CivilityParam { get; set; }
[FirstNameValidator(Category = "Registration", IsLocal = false )]
public string FirstName { get; set; }
public ConfigurationParamValue FirstNameParam { get; set; }
[LastNameValidator(Category = "Registration", IsLocal = false)]
public string LastName { get; set; }
public List<int> Days { get; set; }
public int SelectedDay{ get; set; }
public List<Month> Months { get; set; }
public Month SelectedMonth { get; set; }
public List<int> Years { get; set; }
public int SelectedYear { get; set; }
public DateTime BirthDate { get; set; }
}
I create a view with this viewmodel :
#model Registration.Front.Web.Models.RegistrationViewModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>RegistrationViewModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Country)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Country)
#Html.ValidationMessageFor(model => model.Country)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Civility)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Civility)
#Html.ValidationMessageFor(model => model.Civility)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.BirthDate)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.SelectedDay, new SelectList(Model.Days))
#Html.ValidationMessageFor(model => model.BirthDate)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Occupation)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Occupation)
#Html.ValidationMessageFor(model => model.Occupation)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ZipCode)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ZipCode)
#Html.ValidationMessageFor(model => model.ZipCode)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CGV)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CGV)
#Html.ValidationMessageFor(model => model.CGV)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Optin)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Optin)
#Html.ValidationMessageFor(model => model.Optin)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CNIL)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CNIL)
#Html.ValidationMessageFor(model => model.CNIL)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
this is My contoller:
public ActionResult Index()
{
List<int> listDays = new List<int>(){1, 2, 3};
return View(new RegistrationViewModel() { Days=listDays });
}
[HttpPost]
public ActionResult Index( RegistrationViewModel rvm)
{
if (ModelState.IsValid)
{ return RedirectToAction("Welcome"); }
return View(rvm);
}
public ActionResult Welcome()
{
return View();
}
My problem is in the post, the property Days of the viewmodel is null!!!!! How can i correct this?

in your View you are not rendering Days inside form
Render hidden fields inside form with name="Days" like
foreach(var day in #Model.Days)
{
<input type="hidden" name="Days" />
}
copy the above code and paste it after
<div class="editor-field">
#Html.EditorFor(model => model.CNIL)
#Html.ValidationMessageFor(model => model.CNIL)
</div>
Now,when you submit, the Days values will also submitted to the Post method and you will get values in Days List.

Related

Remote Validation working elsewhere

I have a user registration page where I implemented the remote validation concept for the Username. I basically want to keep each Username a unique value. I was able to achieve it, but now in the login page, when I type the username it prompts a message saying the Username is not available. This was meant just for the registration page and not the login page. Could someone please explain what is the mistake I am doing. I have a Model User which has a Username property; to which I am using the remote validation. I have an Action method called UserNameExsists which gets triggered for the remote validation. And the Registration view which utilities the validation. But the validation is being triggered for the login page as well. Is there a way I could set it up just for the Registration View?
Model:
public class User
{
public int ID { get; set; }
[Required]
[Remote("UserNameExists","User",ErrorMessage="Username not available")]
[Display(Name="User Name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[Display(Name="First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name="Last Name")]
public string LastName { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
[MinLength(10)]
[MaxLength(10)]
[Display(Name="Mobile No")]
public string PhoneNum { get; set; }
}
Controller: (Name is User)
//Remote Validation
public JsonResult UserNameExists(string username)
{
bool user = db.Users.Any(p => p.UserName == username) ? false : true;
return Json(user,JsonRequestBehavior.AllowGet);
}
View:
Registration page view
#model HindiMovie.Models.User
#{
ViewBag.Title = "Register";
}
<link href="~/Content/Site.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<h2>Register</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>User</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNum)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNum)
#Html.ValidationMessageFor(model => model.PhoneNum)
</div>
<p>
<input type="submit" value="Register" />
<input type="reset" value="Clear" />
</p>
</fieldset>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Login page View:
#model HindiMovie.Models.User
#{
ViewBag.Title = "Login";
}
<h2>Login</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
<fieldset>
<legend>User</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<p>
<input type="submit" value="Sign in" />
</p>
</fieldset>
}
#Html.ValidationMessage("LogOnError")
<div>
#Html.ActionLink("Create account", "Register","User")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
You are using the same model for the Login and the Registration page, so you get the same validation on both pages.
Create a ViewModel for each view and put your validation attributes there.
That way you can differentiate between the validations for each page.

Cannot convert lambda expression to type 'string' because it is not a delegate type MVC

I know there is a lot of topics like this one, but I cant find the answer.
In code:
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>TabelaModel</legend>
#Html.HiddenFor(model => model.ID)
<div class="editor-label">
#Html.LabelFor(model => model.Druzyna)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Druzyna)
#Html.ValidationMessageFor(model => model.Druzyna);
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LiczbaMeczy)
</div>
<div class="editor-field">
#Html.TextBox(model => model.LiczbaMeczy)
#Html.ValidationMessageFor(model => model.LiczbaMeczy)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LiczbaGoliStrzelonych)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LiczbaGoliStrzelonych)
#Html.ValidationMessageFor(model => model.LiczbaGoliStrzelonych)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
Compiler is throwing an exception in line:
#Html.TextBox(model => model.LiczbaMeczy)
I have put a System.Linq, System.Data.Entity in model, in view, in controller, but still nothing. It's working when i replace #Html.TextBox into #Html.EditorFor, but i really would like to avoid this. My model class:
namespace GridViewTest.Models
{
public class TabelaModel
{
public int ID { get; set; }
public string Druzyna { get; set; }
[Required (ErrorMessage="*")]
public string LiczbaMeczy { get; set; }
[Required(ErrorMessage = "*")]
public int LiczbaGoliStrzelonych { get; set; }
}
}
Could You help me ?
You need to use TextBoxFor (not TextBox):
#Html.TextBoxFor(model => model.LiczbaMeczy)
That will take the lambda expression.

ASP.NET MVC: Values are null when they reach the Controller

So I have the following Controller:
[HttpPost]
public ActionResult CreateSupport(CreateSupport model)
{
if (ModelState.IsValid && (model.Description != null))
{
model.CreatedById = UserId;
model.ModifiedById = UserId;
}
return View(model);
}
I have the following view:
#using (Html.BeginForm("CreateSupport", "Support", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend></legend>
<div class="editor-label">
#Html.LabelFor(model => model.Subject, new Dictionary<string, object>() { { "class", "req" } })
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Subject)
#Html.ValidationMessageFor(model => model.Subject)
</div>
<div class="support-form-left">
<div class="editor-label">
#Html.LabelFor(model => model.BrowserInfo, new Dictionary<string, object>() { { "class", "req" } })
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.BrowserInfo)
#Html.ValidationMessageFor(model => model.BrowserInfo)
</div>
</div>
<div class="support-form-right">
<div class="editor-label">
#Html.LabelFor(model => model.DatabaseVersion, new Dictionary<string, object>() { { "class", "req" } })
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.DatabaseVersion)
#Html.ValidationMessageFor(model => model.DatabaseVersion)
</div>
</div>
<div class="clearFloat"></div>
<div class="editor-label">
#Html.LabelFor(model => model.Description, new Dictionary<string, object>() { { "class", "req" } })
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<div class="actionButtons">
<button id="btnCancel" class="myButtonCancel">Cancel</button>
<input type="submit" value="Submit" class="myButton" />
</div>
#if (ViewBag.SuccessMessage != null)
{
<div>
<label style="color: red;">#ViewBag.SuccessMessage</label>
</div>
}
</fieldset>
}
Here's the Model:
public class CreateSupport : SupportTicket
{
public CreateSupport()
{
ProductList = new List<Product>();
ProductVersionsList = new List<ProductVersion>();
EnviromentList = new List<InstallationEnvironment>();
content = new Content();
}
[Required]
[UIHint("tinymce_jquery_full"), AllowHtml]
public string Description { get; set; }
[Required]
[DisplayName("Browser version Info.")]
public string BrowserInfo { get; set; }
[Required]
[DisplayName("Database Version")]
public string DatabaseVersion { get; set; }
public Content content { get; set; }
}
The problem is that the values that reach the Controller are NULL even if you enter some value in them.
You should check your browser's developer tools to see if the form is properly posting its values. If it isn't, you should do two things:
A) Disabled javascript to see if there is a script that is interfering with the POST (typically either by disabling or clearing fields)
B) Ensuring your markup is valid using the W3C markup validation service
For input fields use
#Html.EditorFor(x => x.Subject)
For display fields use
#Html.DisplayFor(x => x.Subject)

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)

Override Default MVC Editor Templates Not Working

I've been unable to get default editor templates to work in my MVC 4 Razor web application. I've been unable to find any clues. I want to override String, Password, etc. I've tried UIHints in my model (even though you shouldn't have to for default editor templates), ensured I'm using EditorFor in my view and have placed the Editor Templates under ~/Views/Shared/EditorTemplates. I'm stuck. Any help would be appreciated. Thanks!
public class LoginModel
{
[Required(AllowEmptyStrings = false)]
[StringLength(128)]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required(AllowEmptyStrings = false)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
[HiddenInput()]
public Guid UserEmailAddressId { get; set; }
[HiddenInput()]
public bool IsVerified { get; set; }
}
Part of my view where I'm binding to my model...
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>RegisterModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PrimaryEmailAddress)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PrimaryEmailAddress)
#Html.ValidationMessageFor(model => model.PrimaryEmailAddress)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ConfirmPassword)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ConfirmPassword)
#Html.ValidationMessageFor(model => model.ConfirmPassword)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CultureId)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.CultureId, (IEnumerable<SelectListItem>)ViewBag.Cultures, " -- Select -- ", null)
#Html.ValidationMessageFor(model => model.CultureId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TimeZoneId)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.TimeZoneId, (IEnumerable<SelectListItem>)ViewBag.TimeZones, " -- Select -- ", null)
#Html.ValidationMessageFor(model => model.TimeZoneId)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
In the Password.cshtml file under ~/Views/Shared/EditorTemplates/Password.cshtml
#Html.Password("", ViewData.TemplateInfo.FormattedModelValue, new { #class = "k-textbox" })
THE EDITOR IS WORKING
Turns out I was looking at the wrong View. The actual View was using #Html.TextBoxFor which is why the Default Editor Template for the password was not rendering. You need to use #Html.EditorFor to invoke the default editor template.

Resources