Добавление значений в модель и прохождение проверки 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 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();

а затем выполнить проверку, но это не выглядит хорошим способом, особенно если у вас есть много полей, о которых нужно позаботиться на стороне сервера.

Каковы лучшие решения?

1 ответ

Хороший способ? Создайте модель представления, специфичную для представления, и имейте только те свойства, которые предполагается предоставить представлению.

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" />
}

и в вашем действии HttpPost, используйте ту же модель представления, что и параметр вашего метода, прочитайте значения свойств и используйте

[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);
}
Другие вопросы по тегам