asp.net-mvc – 我的自定义ASP.NET MVC实体绑定:它是一个很好的解决方案吗?

假设我想允许在页面上选择我们的实体(来自下拉列表等),让我们说产品.结果我可能收到这个:

public ActionResult SelectedAction(Guid productId)
{
}

但是,我想使用模型绑定器的功能,所以我编写模型绑定器以从存储库获取我的产品,而不是使用

public ActionResult SelectedAction(Product product)
{
   if (ModelState.IsValid) {} else {}
}

如果产品无效,我的模型绑定器会将模型状态设置为false.
现在,这种方法存在问题:

>使用强类型方法(如Html.ActionLink(c => c.SelectedAction(id))并不总是很容易,因为我们需要传递Product,而不是id.
>无论如何,将实体用作控制器参数并不好.
>如果模型状态无效,并且我想重定向并显示错误,我无法保留所选产品!因为绑定的产品没有设置,我的ID不存在.我想做RedirectToAction(c => c.Redisplay(product))但当然这是不可能的.

现在,好像我回来使用“Guid productId”作为参数……但是,我想提出并讨论一个解决方案.

   public class EntityViewModel<T> where T : BaseEntity
   {
      public EntityViewModel(Guid id)
      {
         this.Id = id;
      }

      public static implicit operator EntityViewModel<T>(T entity)
      {
         return new EntityViewModel<T>(entity.Id);
      }

      public override string ToString()
      {
         return Id.ToString();
      }

      public Guid Id { get; set; }
      public T Instance { get; set; }
   }

现在,如果我使用

public ActionResult SelectedAction(EntityViewModel<Product> product)
{
   if (ModelState.IsValid) {} else {}
}

所有问题都解决了:

>如果我只有Id,我可以传递只有Id设置的EntityViewModel.
>我不使用实体作为参数.而且,我
可以在另一个ViewModel中使用EntityViewModel作为属性.
>我可以将EntityViewModel传递回RedirectToController,它将保留其Id值,这将是
重新显示给用户以及验证消息(感谢MVCContrib和ModelStateToTempData / PassParametersDuringRedirect).

模型绑定器将从存储库获取实例,并将设置模型状态错误,如“数据库中未找到”等.我可以使用ActionLink之类的东西(c => c.Action(Model.MyProductViewModelProperty)).

问题是,这里有任何缺点吗?我看不出有什么不好但我还是MVC的新手,可能会错过一些重要的事情.也许有更好和认可的方式?也许这就是为什么每个人都使用实体ID作为输入参数和属性?

最佳答案 总的来说,这对我来说是一个很好的选择……

作为替代方案,您可以将POCO用于您的viewmodel然后我认为所有3个问题都将自动解决.您是否看过允许实体进行DTO处理的Automapper项目?通过将ViewModel与EntityModel分离,这将为您提供更大的灵活性,但实际上取决于您正在构建的应用程序的复杂性.

MVC的ViewDataExtensions可能也很有用,而不是创建自定义容器来保存各种viewmodel对象,正如您在数字2中提到的那样.

MVCContrib的ModelStateToTempData应该适用于任何可序列化的对象(必须可以为任何进程外的会话状态提供程序序列化,例如SQL,Velocity等),所以你可以使用它,即使没有包装你的实体类也不行吗?

点赞