为什么模型绑定器需要一个空构造函数

我需要一些基本面的帮助……

我有这个控制器,用一个类的实例来提供我的视图(至少我认为它是如何工作的)。 所以,既然我给了我的视图一个新的对象实例,为什么它必须为我的post创建一个更新的模型绑定? 请看下面的例子。

[HttpGet] public ActionResult Index(){ int hi = 5; string temp = "yo"; MyModel foo = new MyModel(hi, temp); return View(foo); } [HttpPost] public ActionResult Index(MyModel foo){ MyModel poo = foo; if(poo.someString == laaaa) return RedirctToAction("End", "EndCntrl", poo); else throw new Exception(); } View: @model myApp.models.MyModel @html.EditorFor(m => m.hi)  Model: public class MyModel { public int hi {get; set;} public string someString {get; set;} public stuff(int number, string laaaa){ NumberforClass = number; someString = laaaa; } } 

为什么我需要一个空白构造函数? 此外,如果我有一个无参数构造函数,为什么poo.someString会在我进入RedirctToAction("End", "EndCntrl", poo)

为什么我需要一个空白构造函数?

因为

 [HttpPost] public ActionResult Index(MyModel foo){ ... } 

您要求绑定器在Post上为您提供一个具体实例,因此绑定器需要为您创建该对象。 您的原始对象不会在GET和POST操作之间保留,只有(某些)其属性作为HTML字段存在。 这就是“HTTP无国籍”的含义。

当你使用较低级别时,它会变得更加明显

 [HttpPost] public ActionResult Index(FormCollection collection) { var Foo = new MyModel(); // load the properties from the FormCollection yourself } 

为什么poo.someString会在我进入RedirctToAction("End", "EndCntrl", poo)

因为您的视图中未使用someString 。 因此,当您获得新模型时,它将永远是空白的。 改变这种情况:

 @model myApp.models.MyModel @html.HiddenFor(m => m.SomeString) @html.EditorFor(m => m.hi)  

这会将值存储为HTML中的隐藏字段,并在POST时为您恢复。

您传递给视图的模型与您在请求中收到的模型之间没有直接连接。 在最终的情况下,初始请求和响应的代码将在IIS的不同实例或甚至不同的机器上运行。

因此,当请求返回时,ASP.Net MVC需要重新创建所有对象(控制器,模型,…)。 使用默认构造函数允许运行时创建新对象,而无需了解自定义构造函数的特定参数。

附注:对于generics,存在类似的构造函数重构,其中您只能指定默认构造函数的where T:new()

我对这个问题感到有些困惑,但你试过这个:

 [HttpPost] public ActionResult Index(MyModel foo){ if(foo.someString == "laaaa") return RedirctToAction("End", "EndCntrl", foo); else throw new Exception(); } 

如果添加了参数化构造函数,则只需要无参数构造函数。

例如:MyObject item = new MyObject();

只要不定义任何构造函数,它就不需要参数less构造函数。 如果使用参数定义构造函数,则需要一个参数less constructor,因为它是模型绑定器使用的构造函数。

当您回发值时,活页夹会将您的请求映射到类型化对象,它首先创建对象,然后尝试将发布的值映射到某个属性。

如果你没有参数较少的构造函数…如果代码不在你的控制之下,那么你必须创建一个自定义绑定器。