0

I am implementing a custom data annotation and in the main model it works correctly, but when I put the data annotation in the partial metada the validation does not find this data annotation.

my code is as follows:

public partial class register
{
    public int id { get; set; }
    public long idPerson { get; set; }
    public string other { get; set; }
}

public partial class register_Metadata
{
    [MyAttributeOne("val1")]
    public int id { get; set; }

    [MyAttributeOne("val1")]
    public long idPerson { get; set; }

    public string other { get; set; }
}

The namespace of the two classes is the same.

On the other hand I have a class where I link the two partial classes.

[MetadataType(typeof( register_Metadata))]
public partial class register
{
}

When I validate the field with customized metadata, the propierties function always has 0 results

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var properties = this.GetInvolvedProperties(validationContext.ObjectType);
        var numberOfRequiredFields = RequireFromGroupAttribute.GetNumberOfRequiredFields(validationContext.ObjectType, this.Selector);

        var values = new List<object> { value };
        var otherPropertiesValues = properties.Where(p => p.Key.Name != validationContext.MemberName).Select(p => p.Key.GetValue(validationContext.ObjectInstance));
        values.AddRange(otherPropertiesValues);

        if (values.Count(s => !string.IsNullOrWhiteSpace(Convert.ToString(s))) >= numberOfRequiredFields)
        {                
            return ValidationResult.Success;
        }

        return new ValidationResult(this.GetErrorMessage(numberOfRequiredFields, properties.Values), new List<string> { validationContext.MemberName });
    }

private Dictionary<PropertyInfo, string> GetInvolvedProperties(Type type)
    {
        return type.GetProperties()
                   .Where(p => p.IsDefined(typeof(RequireFromGroupFieldAttribute)) &&
                               p.GetCustomAttribute<RequireFromGroupFieldAttribute>().Selector == this.Selector)
                   .ToDictionary(p => p, p => p.IsDefined(typeof(DisplayAttribute)) ? p.GetCustomAttribute<DisplayAttribute>().Name : p.Name);
    }

I have changed the data annotation to the main class and then in the properties function I have the two parameters to evaluate. However when I put them in the metadata class it does not work.

Geo
  • 309
  • 4
  • 22
  • Stop using `MetadataTypeAttribute` - In mvc you use a view model –  May 05 '18 at 07:08
  • 1
    If I stop using `MetadataTypeAttribute` then the partial class Metadata does not work. I have seen an example where, apart from the namespace, I told you that the names of the classes have to be the same, so I have conflicts with the repeated names. In my case the main class is generated automatically when importing the model and the metadata is for the data-annotation. It has always worked well for me, but using a custom data annotation is when I do not recognize this data annotation in the metadata class. – Geo May 07 '18 at 08:26
  • You use view models, not partial classes –  May 07 '18 at 08:37
  • If I use a viewmodel for this class, will I have to map field by field? However now I use in the viewmodel only the imported class of the model. – Geo May 07 '18 at 09:05
  • 1
    Yes you need to map from your data model to the view model and vice versa in the POST method (which is standard, and you can always use tools such as [automapper](https://automapper.org/). I do not understand what you mean by _use in the viewmodel only the imported class of the model_ (I hope you are not using data models in a view model) –  May 07 '18 at 09:08
  • Thanks for the help, I have done it in viewModel and it works correctly with [AutoMapper](https://automapper.org/). From what you told me previously, it is not a good practice to use the class generated by the model in the viewmodel. As a good practice, you would always have to create a class that is a copy of the one generated by the model and work with the new one? But what would be a good practice for this type of case? – Geo May 07 '18 at 11:47

0 Answers0