I have a class like this
public class PageReference {
[ScaffoldColumn(false)]
public string Id { get; set; }
public string Name { get; set; }
}
and in my model I use it like this
[Required]
public PageReference PageLink { get; set; }
the required attribute does not fire if I add it to the pagelink property, how can this be solved?
The validation attribute is evaluated by the model binder against the data supplied by the value provider (often posted form fields). If you're posting a form that does not include that field, the binder won't touch that property of the model and so won't evaluate the validation attributes.
I think there is no recursive validation support in asp.net mvc
Related
I'm writing an API and have a very simple model
public class CategoryModel
{
public int ID { get; set; }
[Required]
[StringLength(30)]
public string Name { get; set; }
public string Description { get; set; }
}
I don't want to enforce that the ID property is required if the model is coming in via a post action, but I do if it's a put action. Are there any validation attributes that allow for this or do I need to create a separate model for post and put?
I'm just learning this so I could be doing it wrong altogether so a point in the right direction would be appreciated!
Thanks!
We can do by use fluentvalidation library or create customer attribute
Public class UserMetdata
{
[Required]
[Display(Name="User ID")]
public int UserID { get; set; }
[Display(Name="User Name")]
public string UserName { get; set; }
}
I dont want to UserName to be shown in View. Its similar like creating not required Annotation. One solution is by deleting UserName form Class but i dont want that.
How can it be done using Data Annotation.
You could use ScaffoldColumnAttribute for that property
[ScaffoldColumn(false)]
public string UserName { get; set; }
This will work only when you let framework dynamically generate your views by calling #Html.DisplayForModel() or like, and you DO NOT have defined display template for that model at Views/Shared/DisplayTemplates or Views/ControllerName/DisplayTemplates. Otherwise, you should edit that display template and remove corresponding line from it
I have a Page object that contains a Metadata property like this
public class Page {
public int Id { get; set; }
public int ParentId { get; set; }
public Metadata Metadata { get; set; }
}
public class Metadata {
public string Slug { get; set; }
}
when I save my page I need to verify that no other page with the same parent has the same slug. I was thinking about using a validation attribute on the slug property but when I do that I'm not able to find the page object. What is the best approach of validating such things?
If you insist upon using data annotations validation attributes, you could get access to all of the properties by putting the attribute on the Page class rather than the Slug property.
However there is something better.
Suppose you have a viewModel:
public class CreatePersonViewModel
{
[Required]
public bool HasDeliveryAddress {get;set;}
// Should only be validated when HasDeliveryAddress is true
[RequiredIf("HasDeliveryAddress", true)]
public Address Address { get; set; }
}
And the model Address will look like this:
public class Address : IValidatableObject
{
[Required]
public string City { get; set; }
[Required]
public string HouseNr { get; set; }
[Required]
public string CountryCode { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string ZipCode { get; set; }
[Required]
public string Street { get; set; }
#region IValidatableObject Members
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
string[] requiredFields;
var results = new List<ValidationResult>();
// some custom validations here (I removed them to keep it simple)
return results;
}
#endregion
}
Some would suggest to create a viewmodel for Address and add some custom logic there but I need an instance of Address to pass to my EditorTemplate for Address.
The main problem here is that the validation of Address is done before the validation of my PersonViewModel so I can't prevent it.
Note: the RequiredIfAttribute is a custom attribute which does just what I want for simple types.
Would have been a piece of cake if you had used FluentValidation.NET instead of DataAnnotations or IValidatableObject which limit the validation power quite in complex scenarios:
public class CreatePersonViewModelValidator : AbstractValidator<CreatePersonViewModel>
{
public CreatePersonViewModelValidator()
{
RuleFor(x => x.Address)
.SetValidator(new AddressValidator())
.When(x => x.HasDeliveryAddress);
}
}
Simon Ince has an alpha release of Mvc.ValidationToolkit which seems to be able to do what you want.
Update
As I understand it, the 'problem' lies in the DefaultModelBinder class, which validates your model on the basis that if it finds a validation attribute it asks it if the value is valid (quite reasonable really!), it has no notion of hierarchy. In order to support your required functionality you'll have to write a custom model binder that binds and then validates, if required, as determined by your declarative markup.
If you do write such a class it may be a good candidate for MVC futures.
I’m using ASP.NET MVC3. I have a model that has one property that I don’t want to store in the database. Is there an attribute that I can put on the property to achieve this? Thanks.
public class Person
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[NotMapped]
public string FullName { get; set; }
}
The attribute are in the namespace System.ComponentModel.DataAnnotations
Just to add more options... this is why I prefer to keep my domain model separate from my view model. My view model often has additional fields necessary for rendering the view which does not belong in the domain model. The design I typically use is described pretty well here.