ASP.net MVC - 模型绑定不包括类字段?

时间:2011-10-17 05:22:16

标签: asp.net-mvc-3 model-binding

在最近的一个项目中 - 我遇到了意想不到的障碍 具有简单公共字段的类(注意不是属性)似乎不希望与之相配 ASP.net MVC 3.0模型绑定器。

这是设计吗?

除了将字段更改为属性 - 这里有任何选项吗?

更新

简单字段(而不是属性)的原因是因为我正在使用MVC和Script Sharp项目之间的共享库。脚本锐利支持属性 - 但它在视图中使用javascript变得混乱(使用knockout.js)

所以尽管我喜欢(只是使用属性)我在我的dto课程中使用公共字段。

我想避免对同一个类进行多次定义。叹息

2 个答案:

答案 0 :(得分:12)

  

这是设计吗?

是的,只有具有公共getter / setter的属性才能使用默认的模型绑定器。

  

除了将字段更改为属性 - 这里有任何选项吗?

这就是你应该做的事情,因为你应该使用视图模型。视图模型专为视图而设计。因此,将字段更改为属性是正确的方法。现在,如果您不遵循良好实践并尝试将域模型用作操作的输入/输出,那么您将必须编写一个适用于字段的自定义模型绑定器。不过,这将是很多工作。

答案 1 :(得分:1)

我知道这违背了c#团队的理念,但我认为poco类中的字段很干净。对我来说似乎不那么动人的部分。无论如何,

这是一个将加载字段的模型绑定器。这是相当微不足道的。请注意,您可以使用Activator.CreateInsance的新对象,也可以以现有对象作为起点。我使用是/否下拉菜单,你可能有复选框,在这种情况下,你不得不循环通过fieldinfos并寻找丢失的表单输入b / c html如果它是一个假复选框,则不提交表单项。

〜/ Binders / FieldModelBinder.cs

using System;
using System.Reflection;
using System.Web.Mvc;

namespace MyGreatWebsite.Binders
{
  public class FieldModelBinder : DefaultModelBinder
  {
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
      var obj = controllerContext.HttpContext.Session["CurrentObject"];// Activator.CreateInstance(bindingContext.ModelType);
      var form = controllerContext.HttpContext.Request.Form;
      foreach (string input in form)
      {
        FieldInfo fieldInfo = obj.GetType().GetField(input);
        if (fieldInfo == null)
          continue;
        else if (fieldInfo.FieldType == typeof(bool))
          fieldInfo.SetValue(obj, form[input] == "Yes");
        else
          fieldInfo.SetValue(obj, Convert.ChangeType(form[input], fieldInfo.FieldType));
      }
      return obj;
    }
  }
}

<强> Startup.cs

  public partial class Startup
  {
    public void Configuration(IAppBuilder app)
    {
      ConfigureAuth(app);
      ModelBinders.Binders.Add(typeof(FieldModelBinder), new FieldModelBinder());
    }
  }

<强>用法

[HttpPost]
public ActionResult MyGreatAction([ModelBinder(typeof(FieldModelBinder))] MyGreatProject.MyGreatNamespace.MyGreatType instance, string myGreatParameters)
{
  DoSomethingGreatWithMyInstance();
  return View();
}