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; }
}
在只需要几个属性的情况下传递复杂的对象并不是一个很好的做法(在您的情况下还会令人困惑)。最好只传递必需的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
方法来更改默认错误消息并正确格式化。