I have a MVC4 application with unobstrusive javascript client-side validation. This is working fine except for decimal validation. I am encoutering some strange and annoying behaviour.
The decimal validation only allows numbers with three numbers after the decimal separator. However i want this to work with two numbers after the separator (or just any number is fine as it should do by default if i'm correct).
so 1.222 is valid and 1.22 and isn't while i wan't it to be valid. (1.2222 is neither valid).
in my view i have a normal:
#Html.TextBoxFor(x => x.BasePrice)
my model:
[Required]
public decimal BasePrice { get; set; }
and my controller:
ProductVM model = new ProductVM()
{
BasePrice = product.BasePrice
};
product is an Entity Framework 4 entityobject
I've also tried putting;
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
in my model. But this doesn't work either. It has no effect.
I've never seen any behaviour like this when working with MVC. I have no idea where to look. Any clues?
I still don't know what the problem is, but I fixed it with a little bit dirty workaround:
$.validator.methods.number = function (value, element) {
if(!isNaN(parseFloat(strValue)))
{
return true;
}
return false;
}
by overriding the client side decimal validation. just added this in a script block in my _layout.cshtml.
server side validation will ensure the security is still ok by complete validation.
Related
I'm coding an application using CQRS. I have my commands and my commandHandler. I do tests my commands handlers. But...should you recommend testing commands? What's the best strategy? Should I test all validation possibilities? How do you guys do?
using System;
using Flunt.Notifications;
using Flunt.Validations;
using Todo.Domain.Commands.Contracts;
namespace Todo.Domain.Commands
{
public class CreateTodoCommand : Notifiable, ICommand
{
public CreateTodoCommand() { }
public CreateTodoCommand(string title, string user, DateTime date)
{
Title = title;
User = user;
Date = date;
}
public string Title { get; set; }
public string User { get; set; }
public DateTime Date { get; set; }
public void Validate()
{
AddNotifications(
new Contract()
.Requires()
.HasMinLen(Title, 3, "Title", "Please, describe better your task!")
.HasMinLen(User, 6, "User", "Invalid User!")
);
}
}
}
should you recommend testing commands?
How often do you change commands?
How likely are you to introduce a mistake when changing a command?
How expensive is it for this mistake to escape into a release?
How expensive is it to test?
Commands are out near the input boundary, and one of the common problems that we have near the input boundary is parsing some general purpose data structure to ensure that it satisfies our bespoke constraints.
Does parsing need to be tested? Well, it is logic (more than one possible outcome), so it is certainly a candidate to consider.
Chances are: you don't have particularly specific answers to the questions above. In that case, I would err on the side of introducing tests: because the tests give you a way to collect data, which over time will improve your answers.
I have a question about (Clientside?) validation of datafields.
My model has a decimal property
public decimal CalculatedWork { get; set; }
If I try to insert a decimal value like 20,00 I get an error "Value has to be numeric".
If I insert 20, everything is fine and when refreshing, 20,00 is shown.
How can I get this work?
I tried This DataFormatString and this DecimalModelBinder but nothing works.
The DecimalModelBinder isn't even hit.
What can I do or where is my fault?
In my code-first entity framework sql database I have a decimal value specified as 18,3.
Database object:
public decimal? Kolhalt { get; set; }
In OnModelCreating I have
modelBuilder.Entity<Skada>().Property(o => o.Kolhalt).HasPrecision(18, 3);
In the database the value is specified as Kolhalt (decimal(18, 3), null)
If I enter a value directly in the database I get three decimals, but when I insert or update a value with EntityFramework it is truncated to 2 decimal places.
With Sql server profiler I can see that EF specifies 2 decimals for the stored value:
[Kolhalt] = #14 ... #14 decimal(18,2) ... #14=5.12
(The entered value was 5.123).
So for some reason EF truncates the values sent to the database when I call SaveChanges().
Do I have to specify the number of decimals someplace else to get it right in SaveChanges()?
Best regards,
Henrik
I had a similar problem in a project. Oddly, when I changed my model from decimal? to decimal it started working. I also found a configuration setting TruncateDecimalsToScale which can be added:
public class DbContextConfiguration : DbConfiguration
{
public DbContextConfiguration()
{
var providerInstance= SqlProviderServices.Instance;
SqlProviderServices.TruncateDecimalsToScale = false;
this.SetProviderServices(SqlProviderServices.ProviderInvariantName, SqlProviderServices.Instance);
}
}
I'm developing a Login View in MVC5.
I would like to set at the ViewModel level a DataAnnotation to state the the field does NOT accept empty spaces.
Is there a Data Annotation in MVC (something like [NoSpaces] that can be used to NOT allow a string field to contain "spaces" ?
How about this:
[RegularExpression(#"^\S*$", ErrorMessage = "No white space allowed")]
Well, the simplest but robust thing I can think of is to look at how existing code works, or how existing data annotation work.
For example, let's look at the System.ComponentModel.DataAnnotations.StringLengthAttribute class.
Here's the definition only (just to keep short):
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class StringLengthAttribute : ValidationAttribute
{
public StringLengthAttribute(int maximumLength);
public int MinimumLength { get; set; }
public override string FormatErrorMessage(string name);
public override bool IsValid(object value);
}
}
So I would simply copy the original implementation source code from GitHub and customize it to my needs. For example, to obtain a signature like this (if I understood correctly and this is what you wanted):
public StringLengthAttribute(int maximumLength, int minLength = 0, allowEmptySpaces = true);
For more in-depth info, I would also read the Microsoft docs on the ValidationAttribute class, which is your base class for custom validation data annotations.
EDIT:
I would NOT rely on Regular Expressions to validate data in cases where I just need to exclude empty strings or strings containing only white space(s), because Regular Expressions are very expensive to process (and require a lot of memory allocation, because of an expression compiler, a state machine, etc.).
If this is convenient for anyone, I got pass this issue by doing this on the client:
//trim each form input
var $form = $("#myForm");
$form.find("input:text").each(function(){
var $self= $(this);
$self.va($self.val().trim());
});
//then validate before submit
if($form.valid()){ $form.submit(); }
// on the server ModelState.Isvalid does verify each item with [Required] and won't accept only white spaces from an input (but this means additional roundtrip to server and it's not always convenient)
i have an action and want to do some simple check on param
ActionResult Test([Range(0,10)] int i)
{
// ModelState.IsValid is always true, i want it to be false if i > 10 or i < 0
}
anyway to fix this or work around it or any alternatives provided by MVC?
I thought of just checking the data annotation attribute definition before giving you some alternate options. I surprised to see that the AttributeUsage is defined in such that you can apply to the method parameters as well and unfortunately it not worked as i tried myself. Though I'm not sure why they have allowed this parameter to method parameters (I see it's valid but not working)
Regarding alternate options you could try this,
public ActionResult Test(int i)
{
var rangeAttr = new RangeAttribute(0, 10);
if(!rangeAttr.IsValid(i))
ModelState.AddModelError(i.ToString(), rangeAttr.FormatErrorMessage("i"));
}
You could create your own error if its outside that range and that would make IsValid false.
So for example you could do something like
if(i < 0 || i > 10)
ModelState.AddModelError("Range", "Invalid Range");
I believe that should work.
well in mvc the most appropriate way to do it in you model simply put a attribute
[Range(0,10)]
public int yourproperty{ get; set; }
read this
http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-6