Calidus
Calidus

Reputation: 1404

Dynamic Data Annotations by Object Instance MVC4

I have the following class named QuoteDimensions(I slimmed it down for posting a question). I would like to set the range of Height and Width when the object is created based on the valve of eid. I made a two custom range attribute class to get the desired mins and maxs from a database. This solution doesn't work because I can't(or don't know how to) cast the value of a run time variable to a constant.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;


   public partial class QuoteDimension
    {
        private const int Eid=0;  ///constants don't work this way
        public QuoteDimension(int eid)
        {
           Eid= eid; ///constants don't work this way
        //dostuff
        }
        [Required]
        public int ID { get; set; }
        [Required]
        public int Quote_ID_FK { get; set; }
        [Required]
        [CustomRangeAttributeHeight(Eid)]
        public Double Height { get; set; }
        [Required]
        [CustomRangeAttributeWidth(Eid)]
        public Double Width { get; set; }


}

public class CustomRangeAttributeWidth : RangeAttribute
{
    public static int Eid;

    public CustomRangeAttributeWidth(int eid)
        : base(getmin(), getmax())
    {
        Eid = eid;
    }
    private static double getmax()
    {
        QuoteDatabaseEntities db = new QuoteDatabaseEntities();
        double temp = (from ed in db.EnclosureDimensions
                       where ed.Enclosure_ID_FK == Eid
                       select ed.WidthMax).Single();

        consta
        return temp;
    }
    private static double getmin()
    {
        QuoteDatabaseEntities db = new QuoteDatabaseEntities();
        double temp = (from ed in db.EnclosureDimensions
                       where ed.Enclosure_ID_FK == Eid
                       select ed.WidthMin).Single();

        return temp;
    }

}
public class CustomRangeAttributeHeight : RangeAttribute
{
    private static int Eid;
    public CustomRangeAttributeHeight(int eid)
        : base(getmin(), getmax())
    {
        Eid = eid;
    }
    private static double getmax()
    {

        QuoteDatabaseEntities db = new QuoteDatabaseEntities();
        double temp = (from ed in db.EnclosureDimensions
                       where ed.Enclosure_ID_FK == Eid
                       select ed.HeightMax).Single();
        return temp;
    }
    private static double getmin()
    {
        QuoteDatabaseEntities db = new QuoteDatabaseEntities();
        double temp = (from ed in db.EnclosureDimensions
                       where ed.Enclosure_ID_FK == Eid
                       select ed.HeightMin).Single();
        return temp;
    }

}

I looked into creating a custom metadataprovidor but I don't think that will solve my problem.

Since I can't seem to get this way working my other idea was to create a QuoteDimensions interface, then create multiple classes which implement the interface and hard code the range in each class. That way kinds stinks because I can't just change a a max or min in a database to effect the website.

Any thoughts or suggestions would be every helpful. Thank you.

Upvotes: 1

Views: 547

Answers (1)

Andrei
Andrei

Reputation: 56688

Constants cannot be changed at runtime. In fact their value is resolved and every occurrence of a constant is substituted with its value during compilation process. That is why what you a re trying to do is impossible.

I would say that the easiest way for you here is to make Eid a readonly field:

private readonly int Eid;

public QuoteDimension(int eid)
{
   Eid = eid;
}

public QuoteDimension(int eid) : this(0)
{
}

and implement IValidatableObject in your QuoteDimension class:

public class TemplateNameModel : IValidatableObject
{
    //definition of the class

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // check for conditions here
        yield return new ValidationResult("Validation message.");
    }
}

This might require refactoring of your custom attributes into other form of validators, but will allow you to change their parameters at runtime.

Upvotes: 4

Related Questions