2

I want to model an 'Expense' object that has a 'Sum' (decimal) field. In the view, I want to validate that the user enters a positive value.

OTOH I want to make sure I save the object with a negative value in the DB.

Right now, the model looks like this:

//------The model-------
public class Operation {
    [Range(typeof(decimal), "0.0001", "79228162514264337593543950335")]
    public virtual decimal Sum { get; set; }
    [...]
}
public class Expense : Operation
{
    public override decimal Sum
    {
        get
        {
            return base.Sum;
        }
        set
        {
            base.Sum = - Math.Abs(value);
        }
    }
}

//------In the controller-------
[HttpPost]
public ActionResult CreateExpense(Expense operation, int[] SelectedTags)
{
    return CreatePost(operation, SelectedTags);
}
private ActionResult CreatePost(Operation operation, int[] SelectedTags)
{
    if (ModelState.IsValid)  //  <-- this fails
    [...]
}

The problem is, the MVC validation works with the object's properties (not the POST'ed form values), sees the negative value and fails to validate.

What should I do to fix this?

It looks to me like I'm not separating concerns (validate user input vs maintain database integrity).

Should I use a view model to hold the user input and then populate the actual model from the view model? Doesn't sound like KISS...

4

2 に答える 2

5

継承されたクラスのプロパティに個別の検証属性を指定すると、うまくいくことがわかりました。

もっと簡単なことは考えられません。

モデルは次のようになります。

public class Operation {
    public virtual decimal Sum { get; set; }
}
public class Income : Operation
{
    [Range(typeof(decimal), "0.0001", "79228162514264337593543950335")]
    public override decimal Sum
    {
        get { return base.Sum; }
        set { base.Sum = Math.Abs(value); }
    }
}

public class Expense : Operation
{
    [Range(typeof(decimal), "-79228162514264337593543950335", "-0.0001")]
    public override decimal Sum
    {
        get { return base.Sum; }
        set { base.Sum = - Math.Abs(value); }
    }
}
于 2012-07-24T00:14:09.387 に答える