Asp.net mvc 向模型添加值并通过模型状态变量

Asp.net mvc 向模型添加值并通过模型状态变量,asp.net-mvc,entity-framework,validation,asp.net-web-api2,modelstate,Asp.net Mvc,Entity Framework,Validation,Asp.net Web Api2,Modelstate,我正在努力了解解决我的问题的最佳方法是什么。假设我有一个这样的模型: public class Customer { [Key] public int Id { get; set; } public string Name { get; set; } [Required] public int StoreId { get; set;} [Required] public DateTime UpdatedAt {get; set;} } 我有一个API

我正在努力了解解决我的问题的最佳方法是什么。假设我有一个这样的模型:

public class Customer
{
   [Key]
   public int Id { get; set; }
   public string Name { get; set; }
   [Required]
   public int StoreId { get; set;}
   [Required] 
   public DateTime UpdatedAt {get; set;}
}
我有一个API控制器,它将有如下方法在数据库中插入一个新客户:

public IHttpActionResult Insert(Customer customer)
{
    customer.StoreId = 5; //just for example
    customer.UpdatedAt = DateTime.Now; //again, just as example

    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    db.Customers.Add(customer);
    db.SaveChanges();

    return Ok(customer.Id);
}
现在,正如您在方法中所看到的,让我们假设
StoreId
UpdatedAt
字段不会包含在发布到此方法的原始http请求中,因为这些值需要在服务器端计算和分配(假设客户端基本上不应该将这些值发送到服务器端方法)。在这种情况下,
ModelState
将不再有效,因为它缺少两个必填字段

解决此问题的一种方法是通过执行以下操作,逐个清除模型状态上的错误:

 ModelState["Store.Id"].Errors.Clear();
 ModelState["UpdatedBy"].Errors.Clear();
然后进行验证,但这看起来不是一个好方法,尤其是当服务器端有许多字段需要处理时


更好的解决方案是什么?

好方法?创建特定于视图的视图模型,并且只具有视图应该提供的属性

public class CustomerVm
{
   public int Id { get; set; }
   public string Name { get; set; }       
}
在GET操作中,将此对象发送到视图

public ActionResult Edit(int id)  //Or even Create
{
  var vm=new CustomerVm { Id=id, Name="Scott to be edited"};
  return View(vm);
}
现在,您的视图将被强类型化为

@model CustomerVm
@using(Html.BeginForm())
{
  @Html.HiddenFor(s=>s.Id)
  @Html.TextBoxFor(s=>s.Name)
  <input type="submit" />
}

模型将有效。如果未传递
StoreId
UpdatedAt
的任何值,则它们将初始化为默认值(
0
1/1/0001
)。唯一可能无效的方法是专门为其发送
null
值。您应该使用不包含这些属性的视图模型。添加
[必需]没有任何意义
属性,除非您想指定特定的错误消息-
int
DateTime
不可为空且始终是必需的。您可以在
视图中设置必需的值或参考值,然后再将其发送到控制器,这样模型将始终有效。仅当您发送null时,它将被视为无效盖子
[HttpPost]
public ActionResult Create(CustomerVm model)
{
   var customerEntity = new Customer { Name= model.Name };
   //Stuff server should set goes now
   customerEntity.StoreId = 23;
   customerEntity.UpdatedAt = DateTime.Now;

   db.Customers.Add(customerEntity);
   db.SaveChanges();
   return Ok(customerEntity.Id);
}