如何将MVC3中的HTML和C#代码与Razor混合使用?

Ped*_*C88 31 razor asp.net-mvc-3

我正在尝试显示应该为样式目的切换类的项目列表.我们的想法是创建一个foreach循环,循环遍历myObj模型中的所有内容.

我尝试了以下不起作用的代码(因为我做错了)

@{ int i = 2;
   foreach(var myObj in Model)
   {
        if (i % 2 == 0)
        {
            <div class="class1">
        }
        else
        {
            <div class="class2">
        }
        Html.Partial(...);
        </div>
         i += 1;
   }     
}
Run Code Online (Sandbox Code Playgroud)

完成此任务的正确方法是什么?

更新
我还尝试了以下代码,虽然编译,但不会在其中呈现任何HTML代码(我确信模型中有对象).

@{ int i = 2;
   foreach(var myObj in Model)
   {
        if (i % 2 == 0)
        {
            @:<div class="class1">
        }
        else
        {
            @:<div class="class2">
        }
        Html.Partial(...);
        @:</div>

        i += 1;
   }

}
Run Code Online (Sandbox Code Playgroud)

这是被调用的部分类

<div class="class">
    <div class="class2">
        @if (string.IsNullOrEmpty(var))
        {
            @var2
        }
        else
        {
            @var
        }
    </div>
    <div class="class3">
        @var3
    </div>
</div>
<div class="class4">
    <p>var4</p>
    <ul class="class5">
        <li>element1</li>
        <li>element2</li>
    </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

对不起,我无法发布实际的名称和变量.

Dar*_*rov 27

让我们从改进代码开始吧.

  • 改进步骤1:

    @foreach(var myObj in Model.Select((model, index) => new { model, index }))
    {
        <div class="class@(myObj.index % 2 == 0 ? "1" : "2")">
            @Html.Partial("_Foo", myObj.model)
        </div>
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 改进步骤2(使用该类的自定义HTML帮助程序):

    @foreach(var myObj in Model.Select((model, index) => new { model, index }))
    {
        <div class="@Html.MyClass(myObj.index)">
            @Html.Partial("_Foo", myObj.model)
        </div>
    }
    
    Run Code Online (Sandbox Code Playgroud)

    其中MyClass的定义如下:

    public static string MyClass(this HtmlHelper html, int index)
    {
        return (index % 2 == 0) ? "class1" : "class2";
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 改进步骤3是现有技术(使用Templated Razor代表):

    @Model.List(
        @<div class="@item.MyClass">
            @Html.Partial("_Foo", @item.Model)
        </div>
    )
    
    Run Code Online (Sandbox Code Playgroud)

    List扩展方法如下:

    public class ModelHolder<T>
    {
        public T Model { get; set; }
        public string MyClass { get; set; }
    }
    
    public static class RazorExtensions
    {
        public static HelperResult List<T>(
            this IEnumerable<T> items,
            Func<ModelHolder<T>, HelperResult> template
        )
        {
            return new HelperResult(writer =>
            {
                foreach (var item in items.Select((model, index) => new { model, index }))
                {
                    var myClass = item.index % 2 == 0 ? "class1" : "class2";
                    template(new ModelHolder<T> { Model = item.model, MyClass = myClass }).WriteTo(writer);
                }
            });
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

我投票给改进3号,它比原来的foreach循环更好,更简洁.

  • 我相信总是很高兴回顾并查阅旧问题...当时这个答案看起来很复杂我甚至没有尝试其他改进,现在一切似乎都很明显......再次感谢Darin,这是一个非常好答案. (3认同)
  • 我去了改进1号并且它起作用了.为了将来的参考,我没有测试其余部分. (2认同)

SLa*_*aks 18

您需要在行前面添加非格式良好的标记,@:以防止Razor尝试解析标记.
细节.


Ada*_*SFT 8

您可能确定某些模型中有对象 - 但不是您的模型:)以下直接从您的模型派生的示例代码可以正常工作:


@{ int i = 2;
   string[] list = new string[] {"a","b","c","d"};
   foreach(var myObj in list)
   {
        if (i % 2 == 0){
            @:<div class="class1">
        }
        else
        {
            @:<div class="class2">
        }
        //Html.Partial(...);
        @:</div>
         i += 1;
   }     
}