MVC ViewModel,使用带有一些标记为required的属性的VM,这取决于它是GET还是POST

本文关键字:属性 VM 取决于 POST 还是 GET 记为 ViewModel MVC required | 更新日期: 2023-09-27 18:03:16

我经常发现自己手动修复模型状态的验证,因为在post和get期间视图模型中需要的一些字段不一致。

假设我有这个视图模型:

public class RestaurantMenuName_ViewModel
{        
    public Int64 RestaurantMenuNameId { get; set; }
    public Int64 OwnerId{ get; set; }
    public string MenuNameCategory { get; set; }
    public string CategoryDescription { get; set; }
    public bool IsFormSaved { get; set; }
} 

GET请求期间,控制器/操作只需要验证字段RestaurantMenuNameId和OwnerId。当调用动作RestaurantMenuName时,查询字符串值是RestaurantMenuNameId和OwnerId。模型状态验证将在以下位置完成:

  • RestaurantMenuNameId
  • OwnerId

POST请求期间,控制器/动作将要求字段的模型状态验证:

  • RestaurantMenuNameId
  • OwnerId
  • MenuNameCategory
  • CategoryDescription

这是我正在谈论的不一致的问题,一个解决方案可以使用一个ViewModel的Get请求和一个Post,但这可能是一个真正的时间浪费和容易出错。使用ViewBag是没有讨论的。

问题:有没有一种方法告诉MVC,我们想要一些字段[必需]GET和其他POST?

下面是我所说的伪代码:

 public class RestaurantMenuName_ViewModel
{   
    [Required: in GET, POST]  //<--Pseudo code
    public Int64 RestaurantMenuNameId { get; set; }
    [Required: in GET, POST]  //<--Pseudo code
    public Int64 OwnerId { get; set; }
    [Required: in POST]       //<--Pseudo code
    public string MenuNameCategory { get; set; }
    [Required: in POST]       //<--Pseudo code
    public string CategoryDescription { get; set; }
    public bool IsFormSaved { get; set; }
} 

MVC ViewModel,使用带有一些标记为required的属性的VM,这取决于它是GET还是POST

在只需要几个属性的情况下传递复杂的对象并不是一个很好的做法(在您的情况下还会令人困惑)。最好只传递必需的id作为原语。

如果情况特殊,您确实需要复杂的对象,那么最好为每个请求创建两个不同的视图模型,并相应地装饰所需的属性。

但是,您可以创建自己的require验证属性,该属性将根据当前请求验证属性。

public class MyRequiredAttribute : ValidationAttribute
{
    private string httpVerb;
    public MyRequiredAttribute(string httpVerb)
    {
        this.httpVerb = httpVerb;
    }
    public override bool IsValid(object value)
    {
        if(HttpContext.Current.Request.HttpMethod == this.httpVerb)
        {
            return value != null;
        }
        return true;
    }
}
// Usage
public class MyViewModel
{
    [MyRequired("GET")]
    public string A { get; set; }
    [MyRequired("POST")]
    public string B { get; set; }
}

注意:您可以使用枚举来避免一些困难(例如大写,小写,拼写错误等),也可以覆盖FormatErrorMessage方法来更改默认错误消息并正确格式化。