Core Data: Predicate-based validation - ios

I'm working on managed object validation. So far I'm done with property-level validation. Now I'm meditating above inter-property validation. I could do it by one big if-else control flow but wondering if there is more elegant option.
I've found NSValidationPredicateErrorKey with
For predicate-based validation, key for the predicate for the
condition that failed to validate.
in documentation.
Somehow I sense this could be my pick, but I've found nothing on this topic. I searched official documentation, SO, reputable blogs, Core Data book by Marcus S. Zarra.
So what is predicate-based validation? Does it even exist? Is it even relevant if not documented? What are the use cases? If inter-propery validation, what is the example?

Simply override validateForInsert and validateForUpdate in your managed object subclasses to implement inter-property validation, as shown in the documentation to be found here (with code example).
The "predicate-based" validation can be achieved via the rich managed object API. Each NSManagedObject has an associated NSEntityDescription (a property called entity). Via this you can get to the NSPropertyDescription of each property. Property descriptions in turn have a property called validationPredicates, an array of NSPredicates for validation. Please note that these are read-only and they are primarily used for informing the error objects in case of validation errors. Also, to my understanding, they cannot always describe adequately the validation happening in the overrides mentioned above.
In summary, this error key you found is not really an indication that there is a generic, predicate-based way of specifying validation constraints. Instead you will have to override the above methods in the managed object classes.

Related

Unacceptable type of value for to-one relationship: property = "list"; desired type = AbstractList; given type = List;

I have been struggling with this stupid error for a full day now! As the error shows, it rejects the assignment because the "given type" is different than the desired type. This is wrong since AbstractList is a parent entity for List! I tried the following:
Re-generation of all core data entities classes from the model.
Casting to AbstractList (which sounds silly but the error is stupid and vague in the first place!).
How can I fix this?
As it turns out, I made a mistake when creating the core data stack. I am using a singleton to manage core data with an interface that supports CRUD operations. The bug was simply creating a new stack everytime I perform an operation! Yes, it's a stupid mistake same as the stupid error. I better go now and write my tests to make sure this class is robust enough.

ASP.NET MVC Model Validation Error Localization Context

First of all, I have to say that I understand how Data Annotation -based Model Validation works in ASP.NET MVC4 and I have it successfully implemented with DataAnnotationsModelValidatorProvider. So I don't need assistance on setting it up.
But when it comes down to HtmlHelpers, I'm struggling with trying to figure the context of the error message. And by saying context, I mean which error we're talking about. Which Attribute returned the error?
What I can get, is the Key for the error and the current ErrorMessage but programmatically, there's nothing, that at least I'm aware of, that would communicate which error we're talking about. Whether it was Required attribute or some other attribute, there's not way that I can find how to distinguish them.
Let's open the scenario a little bit. I have custom HtmlHelpers to render ContentEditable elements. For example Html.ContentEditableValidationMessageFor(m => m.firstName);. It will output something like this:
<span contenteditable="true" data-valmsg-for="firstName" data-valmsg-replace="Please provide first name" class="field-validation-error">Please provide first name</span>
Now, I do have a jQuery plugin to handle and persist the changes in the contenteditable element and it will persist them into the backend. However, the UI has nothing that would say which error message we're talking about. Humans can easily see it's the RequiredAttribute, but programmatically there's no data to differentiate it from some MinLengthAttribute for example.
In this scenario, if I would simply use the data-valmsg-for="firstName" as the key for the localization, that'd return the same error message for all the errors concerning the same property.
To Round it Up
What would be the Best Practise, when ModelState is available, to emit a unique ID for ModelError? Considering I'm using ASP.NET MVC4 and DataAnnotationsModelValidatorProvider.
I can think of tons of ways to "Hack it Together" but I would like to use the ModelState and whatever MVC provides. If it all goes down to writing a custom ModelValidatorProvider, then I'm all open for it. As long as it is the best and most sustainable way of going about it. I'm all for Doing More Now and Less Later than Hacking it Now and Hacking it Forever to Keep It Working
Can you give some context around the need to know which rule triggered the validation error, could it be a case of you trying to do something you shouldn't have too?
In general I use FluentValidation (http://fluentvalidation.codeplex.com/wikipage?title=mvc) in place of Data Annotation validation for many reasons, de-cluttering models, unit testing validation logic, allowing vastly more complex validation that include business logic. If your free to use 3rd party libraries I'd give it a look as it has always solved any validation problems I've had in the past.
It lets you write c# code that deals with your model validation via a fluent API. It has an MVC extension that wires everything up for you so other than creating the models validation class there is little impact from then on. An example for your code snippet above would be...
RuleFor(modelname => modelname.FirstName).NotEmpty().WithMessage("lease provide first name");
Even implementing ModelValidatorProvider will not help, it is just a mechanism to provide ModelValidators based on Model Metadata. When during model binding process in a controller action ModelValidators are being invoked the result is just ModelValidationResult which only contains MemberName and a text Message.
I think there is a dirty way to find out which ModelValidator is failed by checking the error message like this:
var modelErrors = ModelState.Where(m => m.Value.Errors.Count > 0).Select(m => new { Name=m.Key , Errors=m.Value.Errors});
by checking ErrorMessage of Errors for each key in modelErrors against ValidatorProvider error messages you can find out the error belongs to which Validator.

How to enforce unique-field validation in MVC

I am in the way building some MVC Application and I really love the Data Annotations support in MVC. The build in support is good enough to enforce simple validation checkup. I wonder, how to implement unique-field validation using custom data-annotation ? For example, I have a view model that need the user to register a new login name, is there way to check (using Model.IsValid) whether the name is not existed before calling the db submit?
You could write your own validator attribute to check the database I guess or you could load all the data in and checkagainst that.
I'd be more inclined to simply attempt to write to the database and have the unique constraint in the table. If you get back an error indicating that there is a duplicate insert error then you simply show that to the user.
I wouldn't be looking to read ahead and check myself.
EDIT
I guess you could also do the check in the code that does the insert. You could do a read and if none is found then insert.
If you do find a duplicate, you could add to the models validation violation rules and return it so that the error would appear in the validation summary on the page.
Create your own Attribute which inherits from ValidationAttribute(the base for all the validation attributes in the DataAnnotations namespace). Override the IsValid method with a check for user id uniqueness.

Combine DataAnnotations Validation with complex business rules

I understand annotating class properties with the basic required and minimum length and getting all the benefits of the asp.net mvc server side and client side validation.
However does anyone have a link that shows how you combine this 'base' validation with more complex business rules. How would I run business rule functions, such as for example, has the customer ordered anything in the last year (database hit required) and still use the same DataAnnotation and mvc validation plumbing?
Goal : Don't want two ways of generating and outputting validation methods.
From http://msdn.microsoft.com/en-us/library/dd901590%28VS.95%29.aspx:
To create customized validation checks, you can either create a class that derives from the ValidationAttribute class or create a method that performs the validation check and reference that method when applying the CustomValidationAttribute to the data member. When you create a class that derives from ValidationAttribute, override the IsValid method to provide the logic for your customized validation check.
There appears to be example code there.
Data Annotation run before your action is invoked. Then, regardless whether the validation succeded or not, the action is still called. If the DA detected invalid data, your ModelState will be invalid.
Once here, you can still do any validation you want, for your business rules, as you would normally do without the data annotation, if you want to. In your action, you can add errors to the ModelState even if the Data Annotation validation passed.
In this case, you add your errors with ModelState.addError, and those errors are added to any error provided by the DA. So in your View it doesn't matter where the error comes from.
Or, if your rules are general, you can write your own annotation tags. The Data Annotation thing is distributed with its source, so you have full control on it.
You could use VAB (Application Validation Block) from the Enterprise Library 5 of Microsoft that actually based on the DataAnnotations class but u do your complex bussiness logic very easily through configuration...
i'd suggest you check it out...
Have a look at following article, where you can use DataAnnotations Multiple Times On Same Field, Compare N number of properties and N number of values....
http://www.codeproject.com/KB/validation/MultipleDataAnnotations.aspx

Custom validation summary

I'm using the UpdateModel method for validation. How do I specify the text for the error messages as they appear in the validation summary?
Sorry, I wasn't entirely clear. When I call UpdateModel(), if there is parsing error, for example if a string value is specified for a double field, a "SomeProperty is invalid" error message is automatically added to the ModelState.
How do I specify the text for said automatically generated error message?
If I implement IDataErrorInfo as suggested, it's error message property gets called for every column, regardless of whether the default binder deems it valid or not.
I'd have to reimplement the parse error catching functionality that I get for free with the default binder.
Incidentally, the default "SomeProperty is invalid" error messages seem to have mysteriously dissappeared in the RC. A validation summary appears and the relevant fields are highlighted but the text is missing! Any idea why this is?
Thanks again and I hope all this waffle makes sense!
This tutorial is a good example of the IDataErrorInfo technique - it makes adding validation parameters easy by adding them as attributes directly to the properties of the model classes.
These examples also may help - slightly different approaches to validating.
Additionally, this creative idea (which also implements IDataErrorInfo) may be a help to you.
Implement IDataErrorInfo on your model.

Resources