@model IEnumerable在c#中代码的位置无关紧要?

时间:2017-02-04 14:06:22

标签: c# asp.net-mvc

我是ASP mvc框架和C#的新手。以下代码由visual studio自动生成。我对模型对象很困惑。我想想(如果我错了,请纠正我)它必须来自实现View(object model)方法的控件类。 &#39; @model IEnumerable&#39;将model对象强制转换为枚举器?我知道一些编程语言可以做到这一点。此外,当我将model重命名为其他内容时,我收到错误,指出上下文未找到aModel => aModal.Name收到错误。此外,@model IEnumerable<ExploreCalifornia.Models.Tour>看起来不是顺序的(我的意思是它不需要在顶部)。如果我删除@model IEnumerable<ExploreCalifornia.Models.Tour>,我会收到aModal => modal.Name的错误消息。但是,当我将@model IEnumerable<ExploreCalifornia.Models.Tour>放在任何地方(即使在最后一行)时,错误也是固定的。我甚至不理解为什么他们必须使用lambda运算符。我觉得c#正在质疑我非常基本的编程逻辑,(不需要定义对象,不需要顺序等等)。

@model IEnumerable<ExploreCalifornia.Models.Tour> @*Renaming or removing this will cause an error*@

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(aModal => aModal.Name)   @*an error is caused when removing the top line code*@
        </th>
        <th>
            @Html.DisplayNameFor(aModal => aModal.Description) @*here too.*@
        </th>
    </tr>
</table>

@*Putting the top line code here fixes the errors for some reason? Shouldnt it be sequential?*@

最后,正如您所看到的,Html.DisplayNameFor(aModal => aModal.Name)有一个使用lambda运算符的表达式。我不明白为什么他们这样做。为什么他们不能直接使用aModal.Name中的字符串。如果查看下面的方法签名,则至少需要2个参数,但实现的方法只有1个参数。这里发生了什么?

public static MvcHtmlString DisplayNameFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression);
public static MvcHtmlString DisplayNameFor<TModel, TValue>(this HtmlHelper<IEnumerable<TModel>> html, Expression<Func<TModel, TValue>> expression);

2 个答案:

答案 0 :(得分:1)

1。那么@model做了什么?

根据ScottGu's Blog post,他提到:

  

@model指令提供了更清晰,更简洁的方法   从视图文件中引用强类型模型。

关于您的IEnumerable问题,没有任何转化。您可以拥有@model IEnumerable<ExploreCalifornia.Models.Tour>@model ExploreCalifornia.Models.Tour,它们是两个不同的东西,正如您所期望的那样。第一个是IEnumerable模型的Tour,这意味着在您的操作中,您将返回以下内容:

public ActionResult Index()
{
    List<Tour> myTours = GetTours();
    return View(myTours); // return a List of Tour, for example
}

...但您可以返回array或其他任何实现IEnumerable Tour的类型。

第二个是单个模型Tour,因此您可以传递Tour而不是IEnumerable<Tour>

因此,如果您的@model是一个Tour,则expression的{​​{1}}参数将是DisplayNameFor,其中Expression<Func<Tour, TValue>>是类型表达式中使用的属性,在您的情况下,我猜TValue是一个字符串。

2。为什么@model可以在我的视图的任何地方声明?

name只是一个定义类型的指令,让Razor知道模型的强类型。这行代码根本不执行任何操作,razor将解释您的文件并编译生成的html。这就像声明一个类,你可以有一个包含多个类的文件,你可以这样做:

@model

因此,仅仅声明类型的顺序并不重要。

3。为什么Html.DisplayNameFor使用表达式?

简而言之,因为public class TopClass { public BottomClass SomeClass { get; set; } // using class declared later... } public class BottomClass { } 允许方法在不需要实际实例的情况下检查类型。假设你有一个像这样的创建动作:

Expression

您仍然可以在视图中使用public ActionResult Create() { return View(); // returning no models at all.... } 创建输入和标签,甚至没有将模型实例传递给视图,请注意上面的示例我们没有将任何内容传递给{{1} }。

这是有效的,因为@Html方法使用View(),这允许他们扫描表达式树,检测属性的@Html以构建正确的输入。如果为@model提供了一个实例,它将使用该模型的值,这通常发生在编辑操作中,您可以在其中传递视图的现有模型。

阅读expression trees here

关于Expressions有两个参数并且只是提供一个参数,这是因为它是extension method,所以第一个参数实际上是对调用该方法的对象实例的引用。在这种情况下,DataAnnotations是您正在使用的DisplayNameFor

答案 1 :(得分:-2)

基本上它是一个存储多个值的结构,比如linkedList。它的祖先是Array,List,ArrayList,Hashtable等。您可以运行linq查询或使用此结构发送params。

你可以查一查。 https://www.dotnetperls.com/ienumerable