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

时间:2011-06-12 04:31:40

标签: asp.net-mvc-3 razor

我正在尝试显示应该为样式目的切换类的项目列表。我们的想法是创建一个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;
   }     
}

实现这个目标的正确方法是什么?

更新
我还尝试了以下代码,虽然编译,但不会在其中呈现任何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;
   }

}

这是名为

的部分类
<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>

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

4 个答案:

答案 0 :(得分: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>
    }
    
  • 改进步骤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>
    }
    

    其中MyClass的定义如下:

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

    @Model.List(
        @<div class="@item.MyClass">
            @Html.Partial("_Foo", @item.Model)
        </div>
    )
    

    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);
                }
            });
        }
    }
    

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

答案 1 :(得分:16)

您需要在行前面添加带有@:的格式不正确的代码,以防止Razor尝试解析代码。
Details

答案 2 :(得分:7)

您可能确定某些型号中有物体 - 但不是您的型号:) 以下直接来自您的示例代码可以正常工作:


@{ 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;
   }     
}


答案 3 :(得分:0)

您需要编写@Html.Partial(...)以将结果呈现给页面。

调用Html.Partial会返回带有部分视图的HelperResult,但实际上并未对其进行渲染。