views:

44

answers:

2

I'm trying to setup data annotation validation for an object in my model and it has a special need. I have to essentially take some extra properties that I'm adding and combine them to get the value of a real property. For example I have a base object:

Task {
    public DateTime? Due
}

But my form has the fields of:

Task.DueDate
Task.DueTimeHour
Task.DueTimeMinute
Task.DueTimePostfix

So I tried:

Task {
    public string DueDate
    public string DueTimeHour
    public string DueTimeMinute
    public string DueTimePostfix
}

Which works, but I then want the model to automatically populate the value of Due with the parsed value of all the other ones. I don't know how to do that.

I would have to override the getter/setters of Due in the metadata buddy class, but that class wouldn't be aware of the extra properties I've given to the original class. Plus I have a feeling that if I mess with those I will have problems retrieving real values from the database.

So I'm hoping that someone here may have an idea on how I can accomplish what I want. If I'm going about it completely wrong I would appreciate being guided back on the right path.

Thanks in advance for any suggestions!

UPDATE

So, I might have found a solution for the first part by having both the original class and the metadata buddy class extend from another base class which contains all the properties. Thus both classes see the properties and can use them.

Now, I'm having a hard time setting the value for the Due property based off of the other properties. Help would be appreciated on this front.

+1  A: 

You just have to override the get/set of your extra properties:

public string DueDate {
  get {return Due.Date.ToShortDateString();}
  set { Due.Date = DateTime.Parse(value); }
}
public string DueTimeHour{
  get {return Due.Hours}
  set { Due.Hours = Int32.Parse(value); }
}
...

Or i missed something ?

olifozzy
You might be on to something. The extra properties, `DueDate`, `DueTimeHour`, `DueTimeMinute` and `DueTimePostfix` are only filled during POST where I want to stitch them together to form `Due`. So, that's the only time they'll be used. When I'm reading data back out of the database it should go into the normal flow where I'm only working with `Task.Due`.
Alex
Ok, so I tried your solution and as good as it looks, it doesn't work because `DateTime.Date` is a read-only property, thus I can't manipulate it. I need have to create a full DateTime object based on the values I may have in the other properties.
Alex
A: 

So, I figured it out at the expense of only a couple of hours of sleep. Here's my final code version that works for anyone who may have the same issues in the future:

public partial class Task {
    public DateTime DueDate {
        get {
            return (DateTime.Now);
        }
        set {
            this.Due = value;
        }
    }

    [Range(0, 23)]
    public byte DueTimeHour {
        get {
            return (0);
        }
        set {
            if (this.Due.HasValue) {
                this.Due = DateTime.Parse(this.Due.Value.ToShortDateString() + " " + value + ":00:00");
            };
        }
    }

    [Range(0, 59)]
    public byte DueTimeMinute {
        get {
            return (0);
        }
        set {
            if (this.Due.HasValue) {
                this.Due = DateTime.Parse(this.Due.Value.ToString("M/d/yyyy h") + ":" + value + ":00");
            };
        }
    }

    public string DueTimePostfix {
        get {
            return (string.Empty);
        }
        set {
            if (this.Due.HasValue) {
                this.Due = DateTime.Parse(this.Due.Value.ToString("M/d/yyyy h:m") + " " + value);
            };
        }
    }
}

Ultimately, I had to add a get to make it work, which makes me curious. I was hoping to get by with just the set on each property because I was already manipulating the Due value in there, but it wouldn't work without the get. Maybe someone can explain that one to me?

Alex