ASP.NET MVC要求正数作为输入,在模型中保存为否定 - 验证失败

Cri*_*scu 2 validation separation-of-concerns asp.net-mvc-3

我想建模一个'费用'对象,它有一个'Sum'(十进制)字段.在视图中,我想验证用户输入正值.

OTOH我想确保在DB中使用负值保存对象.

现在,模型看起来像这样:

//------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
    [...]
}
Run Code Online (Sandbox Code Playgroud)

问题是,MVC验证与对象的属性(不是POST的表单值)一起工作,看到负值并且无法验证.

我该怎么做才能解决这个问题?

它看起来像我没有分离关注点(验证用户输入与维护数据库完整性).

我应该使用视图模型来保存用户输入,然后从视图模型填充实际模型吗?听起来不像KISS ......

Cri*_*scu 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); }
    }
}
Run Code Online (Sandbox Code Playgroud)