Hi I have following in my Asp.net MVc Model
TestModel.cs
public class TestModel
{
public double OpeningAmount { get; set; }
[Required(ErrorMessage="Required")]
[Display(Name = "amount")]
[Range(0 , double.MaxValue, ErrorMessage = "The value must be greater than 0")]
public string amount { get; set; }
}
Now from my controller "OpeningAmount " is assign .
Finaly when I submit form I want to check that "amount" must be greater than "OpeningAmonut" . so want to set Range dynamically like
[Range(minimum = OpeningAmount , double.MaxValue, ErrorMessage = "The value must be greater than 0")]
I do not want to use only Jquery or javascript because it will check only client side so possible I can set Range attribute minimum dynamically than it would be great for.
Recently there's been an amazing nuget that does just that: dynamic annotations and it's called ExpressiveAnnotations
It allows you to do things that weren't possible before such as
[AssertThat("ReturnDate >= Today()")]
public DateTime? ReturnDate { get; set; }
or even
public bool GoAbroad { get; set; }
[RequiredIf("GoAbroad == true")]
public string PassportNumber { get; set; }
There's no built-in attribute which can work with dependence between properties.
So if you want to work with attributes, you'll have to write a custom one.
Se here for an example of what you need.
You can also take a look at dataannotationsextensions.org
Another solution would be to work with a validation library, like (the very nice) FluentValidation .
Related
I have checked for possible solutions to this and haven't been able to get any meaningful solution. I am working on an ASP.NET Web API project and I have a controller route with the below method signature:
[HttpPost("cimgAirtimeVending/{msisdn}")]
public async Task<ActionResult<ResponseObject>> CIMGAirtimeVending([FromBody] CIMGBillPaymentRequest _cimgAirtimeBillPaymentRequest, [Required, RegularExpression(#"\d{13}")] string msisdn)
CIMGBillPaymentRequest is a DTO with validations defined on each property as follows:
public class CIMGBillPaymentRequest
{
[Required, RegularExpression(#"\w+"), StringLength(30)]
public string RequestId { get; set; }
[Required, StringLength(10, MinimumLength = 10), RegularExpression(#"\d+")]
public string DebitAccount { get; set; }
/* [Required, RegularExpression(#"\w+")]
public string Narration { get; set; } */
[Required]
public bool IsFees { get; set; }
public List<Charge> Charges { get; set; }
[Required, RegularExpression(#"[\w-]+")]
public string ProductId { get; set; }
[Required, Range(1, 100, ErrorMessage = "Enter valid ChannelId")]
public int ChannelId { get; set; }
// [Required, Range(100, 100000, ErrorMessage = "Enter valid Amount (>=100)")]
public decimal Amount { get; set; }
[Required, RegularExpression(#"\w+")]
public string CustomerReference { get; set; }
}
public class Charge
{
// [StringLength(10, MinimumLength = 10), RegularExpression(#"\d{10,}")]
[RegularExpression(#"\w+")]
public string Account { get; set; }
public decimal Fee { get; set; }
}
The strange thing is, it appears not all the validation works. If isFees is removed from the DTO, it should return a Required validation error, but that does not happen. The validation is completely ignored. This does not happen with the ProductId property. A Required validation error is returned if it is not included in the DTO
Another issue I had was with the Account property in the Charge class. If you look at the line commented above it, you will see I am using a Regex validation RegularExpression(#"\d{10,}")] i.e. to ensure that it is a string of at least 10 digits. However, this validation is completely ignored and I had to use [RegularExpression(#"\w+")].
Any idea what the issue is and possible solution?
Take a look at the documentation here.
"The RequiredAttribute attribute specifies that when a field on a form is validated, the field must contain a value. A validation exception is raised if the property is null, contains an empty string (""), or contains only white-space characters."
"If the MVC data model or entity partial class contains a field that is annotated with the RequiredAttribute attribute, but the page does not contain the property, an error is not raised. Validation occurs only for fields that are submitted to the server."
If you leave out the property entirely then the required validation will not trigger. It will only trigger when explicitly called with null, empty string or string with only whitespace. Therefore I'm assuming the required check on some other fields namely the struct fields also don't work, however when you then check for a range, like with the ChannelId property it will validate the range. The issue here is that a struct can never be null. This means the RequiredAttribute won't work on bool, int, decimal, etc. fields.
In this case when not providing anything for IsFees will set the property with the value default(bool) the default value for a bool is false.
As for the Account field, look at the documentation here
"You apply the RegularExpressionAttribute attribute to a property when you need to validate values for the property against a regular expression. The regular expression enables you to specify very precisely the format of valid values. The Pattern property contains the regular expression. If the value of the property is null or an empty string (""), the value automatically passes validation for the RegularExpressionAttribute attribute. To validate that the value is not null or an empty string, use the RequiredAttribute attribute."
When providing null, or an empty string to a field with RegularExpressionAttribute it will pass the check. This means, for your Account field you need to use [Required, RegularExpression(#"\d{10,}")].
Is there any data annotation for the allowed values in ASP.NET MVC Core? Since there is no enum in SQL server I am not able to migrate my class with enum field in it to the database. I want to give possible/allowed values to the field in the class. Is there any way to do this?
public class Employee
{
[Key]
public int ID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Status { get; set; }
}
I want to provide Active and Inactive as the only possible values to the Status field.
you can also do this using a regular expression as below:
[Required]
[RegularExpression("Active|Inactive", ErrorMessage = "Invalid Status")]
public string Status { get; set; }
More details can by found here
As #ps2goat mentioned, you could use a check constraint on your database. However, for the model coming into the API you probably still want to provide validation there. Ideally you will do what you can, within reason, to prevent bad data from ever getting to the data layer. You don't mention whether you're using an n-tier architecture, or if your controller is directly referencing the data model. Either way, I believe this custom attribute can be used either at the API layer or on the entity model.
This is a good answer that explains how to create a custom validation attribute. It's an old answer, but it still applies to .Net Core. And here is an answer for a custom validation attribute in .Net Core. It basically looks like this:
public class EmployeeStatusAttribute : ValidationAttribute
{
private string[] _allowedValues;
public EmployeeStatusAttribute(string[] allowedValues)
{
_allowedValues = allowedValues;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var employee = value as Employee;
if (_allowedValues.Contains(employee.Status))
{
return ValidationResult.Success;
}
return new ValidationResult(`{employee.Status} is not a valid status`);
}
}
Then in your model:
public class Employee
{
...
[EmployeeStatus("Active", "Inactive")]
public string Status { get; set; }
...
}
I am new to ASP.NET MVC and am trying to validate a text-box. Basically, if user inputs less than 2 or a non number how can I get the error to display. Here's the tutorial I am trying to follow.
I have my code below.
Create View:
<%= Html.ValidationSummary()%>
<%= using (HtmlBeginForm()){%>
<div class="half-col">
<label for="Amount">Amount:</label>
<%= Html.TextBox("Amount")%>
<%= Html.ValidationMessage("Amount", "*")%>
</div>
Create Controller:
[AcceptVerbs (HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude ="ID")] Charity productToCreate)
{
//Validation
if (productToCreate.Amount < 2)
ModelState.AddModelError("Amount, Greater than 2 please");
return View(db.Donations.OrderByDescending(x => x.ID).Take(5).ToList()); //Display 5 recent records from table
}
Model:
public class Charity
{
public int ID { get; set; }
public string DisplayName { get; set; }
public DateTime Date { get; set; }
public Double Amount { get; set; }
public Double TaxBonus { get; set; }
public String Comment { get; set; }
}
Error:
CS1501 No overload for method 'AddModelError' takes 1 CharitySite
You are adding the error to your modelstate incorrectly. You can read more about the ModelStateDictionary on the MSDN
AddModelError takes 2 parameters, so you would want:
ModelState.AddModelError("Amount", "Greater Than 2 Please.");
Having said that, you can use attributes to validate your model properties so you don't have to write all of that code by hand. Below is an example using the Range attribute. The RegularExpression attribute could also work. Here is an MSDN article containing information about the different types of attributes.
public class Charity
{
public int ID { get; set; }
public string DisplayName { get; set; }
public DateTime Date { get; set; }
[Range(2, Int32.MaxValue, ErrorMessage = "The value must be greater than 2")]
public Double Amount { get; set; }
public Double TaxBonus { get; set; }
public String Comment { get; set; }
}
Also as a side note, the tutorial you are following is for MVC 1&2. Unless you HAVE to use / learn that. I would recommend following the tutorial for MVC 5 here.
Change this line:
ModelState.AddModelError("Amount, Greater than 2 please");
to:
ModelState.AddModelError("Amount ", "Amount, Greater than 2 please");
The first parameter is the member of the model being validated; it can be an empty string just to indicate an error not associated to a field. By specifying the Amount field, internally it uses that to highlight the erroring field (the control should have input-validation-error CSS class added to it) if you are using all of the client-side validation pieces.
ModelState.AddModelError takes 2 arguments, not 1. Link to MSDN ModelStateDictionary.AddModelError Method.
ModelState.AddModelError("Amount", "Greater than 2 please");
if (productToCreate.Amount < 2)
ModelState.AddModelError("Amount", "Greater than 2 please");
I am working on a MVC Razor project that needs some more complex input validations. We are using ViewModels to remove all access to the data model from the controller without going through a logic layer. What we need to solve is how to do the following types of validations:
User selected date is after another date value:
// Read Only for user
public DateTime StartDate { get; set; }
// Must be after StartDate
public DateTime OccurredAt { get; set; }
Sum of user inputs for N (variable) fields do not exceed the value of another field.
// Read only for user
public double StartingAmount { get; set; }
// Sum of these fields must be less than starting amount
public double AmountTransfered { get; set; }
public double AmountLosses { get; set; }
public double AmountSampled { get; set; }
// Validation Check
if (StartingAmount - (AmountTransfered + AmountLosses + AmountSampled) > 0)
isValid = true;
I am new to MVC, and most validation things I find on Google are from 2010 and are loaded with JavaScript to do custom implementations.
I am hoping that there are newer mechanisms to perform compound validation using attributes to define what fields are related. I suspect that the solution for both of these will be very similar, just a different set of parameters and data types.
I apologize in advance if this seems like a stupid question but after doing quite a bit of searching around I either can't put the right pieces together or simply haven't found the right answer. Anyways, I've got this model:
public class Resort
{
public int ID { get; set; }
public String Name { get; set; }
public int BlackDiamond { get; set; }
public int BlueSquare { get; set; }
public int GreenCircle { get; set; }
public int TerrainPark { get; set; }
}
And I've got a view that creates TextBoxes as the input for each of those variables. What I need to do is set up some JQuery validation to ensure that each TextBox has a value in it, and more specifically that the TextBoxes for the int has numbers in it.
After doing a little research I'm just not sure how I can even go about setting up the script for the view or if I should rely on Data Annotations in the model?? Any help is appreciated even if it is simply to point me in the right direction of research, I am here to learn. Thank you.
If it's a required field, add the RequiredAttribute to the field:
[Required]
public int BlackDiamond { get; set; }
If you also want a custom message, add it to the attribute:
[Required(ErrorMessage="Please enter a number")]
public int BlackDiamond { get; set; }
If you want built-in jQuery validation, make sure you use the strongly-typed helper:
#Html.TextBoxFor(m => m.BlackDiamond) // you can also use EditorFor
You will need to also include script references to the UnobtrusiveValidation and jQuery Validate plugins to get the automatic validation.
Just FYI, this seems like a good place to start, if you are unfamiliar with validation in MVC: http://msdn.microsoft.com/en-us/VS2010TrainingCourse_ASPNETMVC3FormsandValidation
EDIT: Just to make this answer a bit more complete, as noted in the comments: to see the error messages associated with each control, you need to add the validation helpers: #Html.ValidationMessageFor(m => m.BlackDiamond)