ModelState validation not showing which fields are invalid [duplicate] - asp.net-core-mvc

This question already has an answer here:
ModelState.IsValid is false prior to validation
(1 answer)
Closed 5 years ago.
My ModelState validation is giving me very generic error messages, I would like to know exactly which fields are invalid.
As you can see the first two textboxes "Startup rate < 1 min" and "Startup rate 1-3 min" are both empty, but the modelstate validation messages only say "The value '' is invalid". I would like it to say which fields exactly are invalid.
I placed the following line in my view: <div asp-validation-summary="All"></div>
This is my controller action and my model with required attributes:
[HttpPost]
public async Task<IActionResult> EditSubtitleSetting(EditSubtitleSettingsModel model)
{
try
{
if (ModelState.IsValid)
{
await _subtitleSettingService.UpdateSubtitleSetting(model);
return RedirectToAction("Subtitling");
}
} catch (CustomException e)
{
foreach (var m in e.Messages)
{
ModelState.AddModelError(m.Key, m.Message);
}
}
return View(model);
}
public class EditSubtitleSettingsModel
{
public string Id { get; set; }
public string FromLanguage { get; set; }
public string ToLanguage { get; set; }
[Required(ErrorMessage = "Startup rate less than one minute is required")]
public decimal StartupRateLessThanOneMinute { get; set; }
[Display(Name = "Startup rate between one and three minutes")]
[Required(ErrorMessage = "Startup rate between one and three minutes is required")]
public decimal StartupRateBetweenOneAndThreeMinutes { get; set; }
[Required(ErrorMessage = "Startup rate between three and five minutes is required")]
public decimal StartupRateBetweenThreeAndFiveMinutes { get; set; }
[Required(ErrorMessage = "Price per subtitle is required")]
public decimal PricePerSubtitle { get; set; }
[Required(ErrorMessage = "Default rate for translators is required")]
public decimal DefaultRateTranslators { get; set; }
}
How can I have the validation message tell me which fields are invalid?

Apparantly, required attribute only works on nullable decimals. So I changed my model to only have nullable decimals, and now it properly shows the validation messages. So a very easy fix.
This is what my model now looks like:
public class EditSubtitleSettingsModel
{
public string Id { get; set; }
public string FromLanguage { get; set; }
public string ToLanguage { get; set; }
[Required(ErrorMessage = "Startup rate less than one minute is required")]
public decimal? StartupRateLessThanOneMinute { get; set; }
[Required(ErrorMessage = "Startup rate between one and three minutes is required")]
public decimal? StartupRateBetweenOneAndThreeMinutes { get; set; }
[Required(ErrorMessage = "Startup rate between three and five minutes is required")]
public decimal? StartupRateBetweenThreeAndFiveMinutes { get; set; }
[Required(ErrorMessage = "Price per subtitle is required")]
public decimal? PricePerSubtitle { get; set; }
[Required(ErrorMessage = "Default rate for translators is required")]
public decimal? DefaultRateTranslators { get; set; }
}

Related

MVC 5 Conditional Validation

Once again plethora of similar questions and none I can find to help me, or one I can understand.
My struggle is very simple actually. In a register form , I need to validate a few fields IF country selected from a drop down is a specific one. If not , no additional validations are needed. Let's say the country code needs to be "XX" in order to check the fields for things like length, integer or not etc.
I'm very new to MVC (less than a week) and after working with Webforms for a while, even something this simple confuses me. Anyway, here my code pieces
RegisterViewModel(only relevant fields included)
public class RegisterViewModel
{
//
[Required]
[Display(Name="Ülke")]
public string CountryCode {get; set;}
//
//[RegularExpression(#"^[0-9]*$")]
[Required]
[Display(Name = "Posta Kodu")]
public string PostCode { get; set; }
[Required]
[EmailAddress]
[Display(Name = "İrtibat E-Mail Adresi")]
public string Email { get; set; }
//regular expression and string length validations should work only if a certain country is selected
[Required]
[RegularExpression(#"^[0-9]*$")]
[StringLength(11, MinimumLength = 8, ErrorMessage = "Vergi Numarası hatalı.<br/> Lütfen kontrol ediniz.")]
[Display(Name = "Vergi No")]
public string TaxIdNo { get; set; }
//
[Required]
[Display(Name = "Firma Yetkilisi T.C. Kimlik Numarası")]
public string UserCitizenIdNo { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Firma Yetkilisi Email")]
public string UserEmail { get; set; }
[Required]
[Display(Name = "Firma Yetkilisi Tel. No.")]
public string UserPhoneNumber { get; set; }
//
}
The country dropdown
#Html.Bootstrap().DropDownListFor(t => t.CountryCode, MVCUtility.DataTableToListItem((DataTable)ViewBag.CountryList, "Code", "Name")).HtmlAttributes(new { #style = "width:100%;" })
I came across HasSelfValidation on a question but sadly noticed it is retired. How can I make these work inside an if-like construct?
PS: We set the dropdown to a specific value, I need to check if it's changed or not too.

Need to know how to pass a model for paypal transaction

I have a simple order form that I created in mvc and when they hit the submit button, I have the user redirected to paypal for payment and then they get redirected back to the original page. I'm trying to find out how to either pass the model information or save it somehow because after payment is complete, my program sends them an email with a copy of their receipt and successful purchase. How do I go about doing this? Please let me know if there is anything else you need to see. I'm still brand new to MVC and I'm trying to figure this all out.
Model
public class WritingAppModel
{
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[EmailAddress(ErrorMessage = "A Valid Email Address is Required.")]
[Required(ErrorMessage = "Email Address is Required.")]
public string Email { get; set; }
[Phone(ErrorMessage = "A Valid Phone Number is Required.")]
[Required(ErrorMessage = "Phone Number is Required.")]
public string PhoneNumber { get; set; }
[Required(ErrorMessage = "Subject is Required.")]
public string Subject { get; set; }
[Required(ErrorMessage = "Topic is Required.")]
public string Topic { get; set; }
[Required(ErrorMessage = "Document Type is Required.")]
public string DocumentType { get; set; }
[Required(ErrorMessage = "Urgency is Required.")]
public string Urgency { get; set; }
[Required(ErrorMessage = "Number of Pages is Required.")]
public Int16 NumberOfPages { get; set; }
[Required(ErrorMessage = "Requirements are Required.")]
[DataType(DataType.MultilineText)]
[StringLength(200)]
public string Requirements { get; set; }
[Required(ErrorMessage = "Writing Style is Required.")]
public string Style { get; set; }
[Required(ErrorMessage = "Spacing is Required.")]
public string Spacing { get; set; }
[Required(ErrorMessage = "Academic Level is Required.")]
public string AcademicLevel { get; set; }
[Required(ErrorMessage = "Number of Sources is Required.")]
public Int16 NumberOfSources { get; set; }
[Required(ErrorMessage = "Price is Required.")]
[Range(0.01, 10000.00, ErrorMessage = "Your quote is not complete because you haven't completed all of the steps.")]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:C}")]
public decimal Price { get; set; }
public string UnFormattedPrice
{
get
{
return this.Price.ToString();
}
}
[Required(ErrorMessage = "Currency is Required.")]
public string Currency { get; set; }
}

How to bind form with model data in MVC

here i have one model. now i want to buil form using html helper . so when index action will be called then i want to populate model data by hand and send the model to view.
here is my model data but the way i want to build form not being possible just due to lack of knowledge. so if possible help me
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
namespace MvcPractise.Models
{
public class Student
{
[Required(ErrorMessage = "First Name Required")] // textboxes will show
[Display(Name = "First Name :")]
[StringLength(5, ErrorMessage = "First Name cannot be longer than 5 characters.")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last Name Required")] // textboxes will show
[Display(Name = "Last Name :")]
[StringLength(5, ErrorMessage = "Last Name cannot be longer than 5 characters.")]
public string LastName { get; set; }
[Required(ErrorMessage = "DOB require")] // datepicker will show
[Display(Name = "DOB :")]
[DataType(DataType.Date)]
public DateTime Dob { get; set; }
[Required(ErrorMessage = "State Required")] // drodown will show
[Display(Name = "State :")]
public List<State> State { get; set; }
[Required(ErrorMessage = "City Required")] // drodown will show
[Display(Name = "City :")]
public List<City> City { get; set; }
[Required(ErrorMessage = "Language known Required")] // group of checkboxes will show
[Display(Name = "Language known :")]
public List<Language> Language { get; set; }
[Required(ErrorMessage = "Sex Required")] // group of radio button will show
[Display(Name = "Sex :")]
public List<Sex> Sex { get; set; }
[Required(ErrorMessage = "Computer Course Required")] // listbox will show
[Display(Name = "Computer Course Done :")]
public List<ComputerCourse> ComputerCourse { get; set; }
}
public class State
{
public string ID { get; set; }
public string Name { get; set; }
}
public class City
{
public string ID { get; set; }
public string Name { get; set; }
}
public class Language
{
public string ID { get; set; }
public string Name { get; set; }
}
public class Sex
{
public string ID { get; set; }
public string Type { get; set; }
}
public class ComputerCourse
{
public string ID { get; set; }
public string Type { get; set; }
}
}
1) for the first name & last name property i want to show textboxes
2) for the DOB property i want to show textbox with date picker
3) for the DOB property i want to show textbox with date picker
4) for the State/City property i want to show dropdown or combo
5) for the Language property i want to show group of checkboxes
6) for the Sex property i want to show 2 radio button for male & female
7) for the Computer Course property i want to show listbox
now write a index action method which will populate model with dummy data and generate UI.
when click on save button then model data will return back to action method called saved like
public ActionResult Save(Student s)
{
return View(s);
}
or
public ActionResult Save(StudentViewModel sv)
{
return View();
}
please help a newbie to learn things. thanks
Here is a good article about various types of model binding. It's not too long and demystifies the automatic binding and the manual way of doing it.
http://odetocode.com/blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx
Also I would agree that this Question is a little too broad in scope. I'll try to help a little. You can use the same method name for the get and post request (The one that loads the empty page is the get, and when you fill out the form you will "post" the form data back to the post method). You will want to specify which one is using http 'get' and which one is using 'post' and you can do so with by decorating your method with an attribute like this.
[HttpGet]
public ActionResult Create()//leave it empty youre about to make it
{
var model = new ObjectType();
return view(model); // pass the new model ( empty object ) to your view;
}
[HttpPost]
public ActionResult Create(ObjectType theObject){
//MVC will try to populate the values of properties
//of theObject if they match the names on your form elements
//save it in your database
}

EF4 MVC3 model state validation

Using this model:
public class Cases
{
//case data model for call center
//implement lists for all related child tables too
[Key]
public int CasesID { get; set; }
public string CaseNumber { get; set; }
[Required(ErrorMessage = "Customer is Required")]
public int CustomerID { get; set; }
public virtual Customer Customer { get; set; }
[MaxLength(50)]
public string UserName { get; set; } //get user name from the aspnet membership
[Required(ErrorMessage = "Case Category is Required")]
public int CaseCategoryID { get; set; }
[Required(ErrorMessage = "Technician is Required")]
public int TechnicianID { get; set; }
public virtual Technician Technicians { get; set; }
[Required(ErrorMessage = "Engine Model is Required")]
public int EngineModelID { get; set; }
public virtual EngineModel EngineModel { get; set; }
[MaxLength(50)]
public string BMSWorkorder { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "Status is Required")]
public string CaseStatus { get; set; }
[MaxLength(50)]
public string OpenedBy { get; set; }
[Required(ErrorMessage = "Opened Date is Required")]
[DataType(DataType.DateTime)]
public DateTime? OpenedDate { get; set; }
[MaxLength(50)]
public string ClosedBy { get; set; }
[DataType(DataType.DateTime)]
public DateTime? ClosedDate { get; set; }
[MaxLength(50)]
[Required(ErrorMessage="Caller First Name is Required")]
public string CallerFirstName { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "Caller Last Name is Required")]
public string CallerLastName { get; set; }
[MaxLength(100)]
public string AdditionalContact { get; set; }
[MaxLength(10)]
[Required(ErrorMessage = "Qualified is Required")]
public string Qualified { get; set; }
public string Description { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "ESN is Required")]
public string ESN { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "Mileage is Required")]
public string Mileage { get; set; }
[DataType(DataType.Date)]
public DateTime? DateInService { get; set; }
[MaxLength(50)]
public string ESTR { get; set; }
[MaxLength(50)]
[Required(ErrorMessage = "EDS is Required")]
public string EDS { get; set; }
[MaxLength(50)]
public string GensetSerialNumber { get; set; }
[MaxLength(50)]
public string GensetModelNumber { get; set; }
//child Case Notes records
public virtual ICollection<CaseNotes> CaseNotes { get; set; }
//child case attachment records
public virtual ICollection<Attachment> Attachments { get; set; }
//child case complaint records
public virtual ICollection<CaseComplaint> CaseComplaint { get; set; }
//tracking fields
public DateTime? CreatedOn { get; set; }
[MaxLength(50)]
public string CreatedBy { get; set; }
public DateTime? ModifiedOn { get; set; }
[MaxLength(50)]
public string ModifiedBy { get; set; }
}
I am wondering why even though only some of the properties are marked required, the modelstate does not get set valid unless all properties have values when saving.
Am I doing something wrong?
EDIT
Here are my razor elements for the dropdownlist fields in question:
#Html.DropDownList("Qualified", String.Empty)
#Html.ValidationMessageFor(model => model.Qualified)
#Html.DropDownList("EngineModelID", String.Empty)
#Html.ValidationMessageFor(model => model.EngineModelID)
#Html.DropDownList("CaseCategoryID", String.Empty)
#Html.ValidationMessageFor(model => model.CaseCategoryID)
The EngineModelID and CaseCategoryID properties must be nullable integers on your view model if you want to allow empty values. Oooops, you are not using view models.
ASP.NET MVC automatically makes non-nullable types required. You could disable this explicitly in your Application_Start:
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
But if you want to do the things properly you should use view models.
The following is absolutely horrible:
#Html.DropDownList("CaseCategoryID", String.Empty)
I guess you have stuffed a SelectList in a ViewBag.CaseCategoryID so the CaseCategoryID does 2 things at the same time: it represents a list and a selected scalar value.
With view models you would use the strongly typed version of those helpers:
#Html.DropDownListFor(x => x.CaseCategoryID, Model.CaseCategories)
where CaseCategories will be an IEnumerable<SelectListItem> property on your view model that the controller would populate.

ASP.NET MVC3 Eager Client-Validation, FluentHTML and Nested ViewModels

I'm using FluentHTML (from MvcContrib) to layout my HTML mark-up. I want to use eager unobtrusive client-validation provided by jquery.validate library. I got everything working correctly except for properties of nested ViewModels. Example:
public class RegisterPageViewModel
{
[Required(ErrorMessage = "First Name cannot be empty.")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last Name cannot be empty.")]
public string LastName { get; set; }
[Required(ErrorMessage = "Email cannot be empty.")]
[RegularExpression(#"^\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Invalid Email Format.")]
public string Email { get; set; }
[Required(ErrorMessage = "Password field cannot be empty.")]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required(ErrorMessage = "You have to confirm your password.")]
[Compare("Password", ErrorMessage = "Passwords must match.")]
[DataType(DataType.Password)]
public string PasswordConfirm { get; set; }
[Required]
public AddressDto Address { get; set; }
public bool TermsOfUse { get; set; }
[Required(ErrorMessage = "Nickname is required")]
public string Nickname { get; set; }
public string MiddleName { get; set; }
[Required(ErrorMessage = "Birthdate is required")]
public string Birthdate { get; set; }
public string Phone { get; set; }
[Required(ErrorMessage = "Mobile number is required")]
public string Mobile { get; set; }
public string RakimMelieh { get; set; }
public string ReferralNickname { get; set; }
}
It works perfectly for ALL of the properties except for those inside the Address property, although I decorated the properties of the AddressDto with validation attributes as well:
public class AddressDto
{
public int Id { get; set; }
[Required(ErrorMessage = "Address Name is required.")]
public string Name { get; set; }
public string Country { get; set; }
public string District { get; set; }
public string City { get; set; }
public string Area { get; set; }
[Required(ErrorMessage = "Address Details are required.")]
public string Details { get; set; }
public bool IsDefault { get; set; }
}
The same thing happens for other view models as well where there are nested view models inside them. One thing I noticed when inspecting the input fields FireBug is that they always have the valid class on them, even when they're not really valid (according to the annotations decorating their properties).
Any thoughts how I can solve this problem?

Resources