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

4

我需要在基础方面得到一些帮助...

我有一个控制器,用一个类的实例为我的视图提供服务(至少我是这么认为的)。所以,既然我正在为我的视图提供一个新的对象实例,为什么它还需要为我的后台模型绑定创建一个更加新的实例呢?请看下面的例子。

[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) 
<input type="submit" value="hit"/>

Model:
public class MyModel {
 public int hi {get; set;}
 public string someString {get; set;}
 public  stuff(int number, string laaaa){
  NumberforClass = number;
  someString = laaaa;
 }
}

为什么我需要一个空白构造函数?此外,如果我有一个无参数的构造函数,为什么在到达RedirctToAction("End", "EndCntrl", poo)之前,poo.someString会发生变化?


阅读此内容以了解模型绑定的基本知识。https://msdn.microsoft.com/zh-cn/magazine/hh781022.aspx - Praveen Paulose
你在说哪个空构造函数?我在你的例子中只看到一个构造函数 "stuff(int number, string laaaa)"。 - Sam
请确保您的代码一致,只发布能够编译的内容。class stuff != class MyModelhi != NumberforClass - H H
4个回答

6
为什么我需要一个空构造函数?
因为它可以提供默认值,确保在类的实例化过程中不会出现任何错误。
[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
}

为什么当我到达 RedirctToAction("End", "EndCntrl", poo) 时,poo.someString 会发生变化呢?

因为你的 View 中没有使用 someString。所以当你获取新的模型时,它总是为空白的。要改变这一点:

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

@html.EditorFor(m => m.hi) 
<input type="submit" value="hit"/>

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

2

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

因此,当请求返回时,ASP.Net MVC需要重新创建所有对象(控制器、模型等)。拥有默认构造函数可以使运行时在不了解特定参数的情况下创建新对象。

另外说明:类似于构造函数的重建还存在于泛型中,您只能为默认构造函数指定where T:new()


0

我对这个问题有点困惑,不过你试过这个了吗:

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

只有在添加了带参数的构造函数时,才需要一个无参构造函数。
例如:MyObject item = new MyObject();

0

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

当您回传值时,绑定器将在类型化对象中映射您的请求,它首先创建对象,然后尝试将您发布的值映射到某些属性。

如果您不能拥有无参数的构造函数... 如果代码不在您的控制之下,则必须创建自定义绑定器。


它确实需要一个无参构造函数。如果您没有定义自己的构造函数,C#编译器会自动为您添加一个,但这并不意味着模型绑定不需要它。 - Andy
是的,那就是我隐含地说的!但也许你是教授? - Laurent Lequenne
6
不,你在任何地方都没有暗示它,事实上你的意思恰恰相反。这不是学术问题,有些人仍然不知道C#编译器会为你插入一个默认构造函数。 - Andy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接