【问题标题】:.Net Core 5.0 .cshtml Razor Pages "if" Block Open HTML Tag Without Closing It.Net Core 5.0 .cshtml Razor 页面“如果”阻止打开 HTML 标记而不关闭它
【发布时间】:2021-12-18 22:36:32
【问题描述】:

我不确定我是否有足够的词汇量来正确地提出这个问题,我希望这个问题的标题措辞正确......无论哪种方式,我都试图在 .cshtml Razor 页面上使用.Net Core 5.0 (Visual Studio 16.10.0)。我正在使用 Entity Framework Core 5.0.11,但我不确定这是否与此相关。

我正在从数据库中提取数据,我想做的是构建一个包含两列的表。所以,我希望我拉的第一个项目在第一列,我拉的第二个项目在第二列,我拉的第三个项目在第一列(现在在项目一下面),我拉的第四个项目拉到第二列(现在在第 2 项下)等等。

我正在尝试生成一个包含任意数量项目的两列表。

(编辑:对不起,如果这张表看起来一团糟。当我在编辑页面时,它看起来像是我想要的,但是当我在最后一页上查看我的问题时,它看起来就像原始文本。只是想说明我知道这一点,但不知道该怎么办。或者,也许这只是我的屏幕,在你的屏幕上看起来很棒。手指交叉。)

像这样: |标题(但在实际代码中忽略标题)|另一个标题(它只是说这里需要标题行)| |----------------------------------------------------------|--- ------------| |第 1 项|第 2 项| |第 3 项|第 4 项|

现在,这是我尝试使用的代码,但它似乎不起作用:

@if (Model.MyListOfItems is not null) // I can verify that it is not null
{
<table>
    <tbody>
        @{ int count = 0; }
        @foreach (var item in Model.MyListOfItems)
        {
            count++;
            @if (count % 2 == 1)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(i => item.Text)
                    </td>
            }
            else
            {
                    <td>
                        @Html.DisplayFor(i => item.Text)
                    </td>
                </tr>
            }
        }
        @if (count % 2 == 1)
        {
            </tr>
        }
    </tbody>
</table>
}

现在,你可以看到我在做什么了,对吧?对于奇数项目,打开一个新的表格行。对于偶数项目,关闭它。如果我们以奇数项目结束,我们将打开一行,因此最后一个 if 语句将其关闭。这样,我们就得到了我上面描述的表格。

但是,这不起作用。它不会编译。对于文件的第一行,我收到类似; expected 的错误。它开始抱怨此代码之前的代码。我开始收到一堆such and such doesn't exist in this current context

但事情是这样的......我知道其余的代码很好,因为如果我把它改成这个

@if (Model.MyListOfItems is not null) // I can verify that it is not null
{
<table>
    <tbody>
        @{ int count = 0; }
        @foreach (var item in Model.MyListOfItems)
        {
            count++;
            @if (count % 2 == 1)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(i => item.Text)
                    </td>
                </tr> <!-- Added this -->
            }
            else
            {
                <tr> <!-- Added this -->
                    <td>
                        @Html.DisplayFor(i => item.Text)
                    </td>
                </tr>
            }
        }
        @if (count % 2 == 1)
        {
            <!-- </tr> --> <!-- Removed This -->
        }
    </tbody>
</table>
}

然后它可以正常工作并编译。该表显然不像我希望的那样,但我将其包括在内是为了说明我知道这不是我的代码的问题,或者即使是我的其余代码,编译器也没有看到结尾&lt;tr&gt; 标记在开头的 if 语句中,然后没有将 } else { 识别为 C# 代码(因此会在整个页面上抛出错误)。

我知道编译器正试图将我从自己手中拯救出来,但如果我可以强制它编译我……至少相当有信心该表格将是正确格式的 HTML。即使不是,如果我可以编译它,那么我可以看到这段代码 生成什么样的表并从那里修复它。但是,编译器显然不喜欢我在 if 块中打开标签然后不关闭它。

我之前遇到过类似的问题,这也是为什么我确信这是编译器而不是我的原因,但通常我只是找到其他方法来解决问题。而且我确定这次我会这样做,我会在发送此消息后立即开始尝试,但我想我还是会和你们确认一下;我想我一定是缺少了什么。

另外,是的,我尝试将 else 更改为 @else,但这并没有解决问题,只是开始抛出错误,说那里不允许使用 @else

所以,我认为,要问我想问什么还有很长的路要走,但我认为所有的说明都是必要的。无论如何,我想这是一个问题:

当我在该块中打开 HTML 标记但不关闭 HTML 标记时,如何强制编译器将我的右括号识别为代码?

(编辑:根据@Dai 的回复在表格中添加了明确的&lt;tbody&gt;

【问题讨论】:

  • 顺便说一句,你应该在你的表中添加一个明确的&lt;tbody&gt;
  • 如果你想让一行 HTML 不被解析,在它前面加上 @:

标签: c# html .net-core razor syntax


【解决方案1】:

好的,好吧,如果有人知道我的问题的答案,我仍然会非常感激,因为就像我提到的那样,我以前遇到过这样的事情并且总是必须找到解决方法。但是,如果有人想知道,这是我的解决方法。

我正在使用 Bootstrap 框架,它有这个列组织。每页 12 列,每个容器内多 12 列。基本上,您可以继续将页面分成越来越小的十二组。这不是最好的解释,但是......这是他们的网页https://getbootstrap.com/docs/4.0/layout/grid/

无论如何,我没有使用表格,而是使用网格系统,如下所示:

<div class="row">
@if (Model.MyListOfItems is not null) // I can verify that it is not null
    {
        int count = 0;
        @foreach (var item in Model.MyListOfItems)
        {
            count++;
            <div class="col-6">
                @Html.DisplayFor(i => item.Text)
            </div>
            @if (count % 2 == 0)
            {
                <br />
            }
        }
        @if (count % 2 ==0)
        {
            <br />
        }
    }
</div>

我知道最后两个 if (count % 2 == 0) 块可能根本不需要,因为 Bootstrap 的网格系统是响应式的,但我只是喜欢明确。不过,为了大家的理智,这应该会产生相同的结果:

<div class="row">
@if (Model.MyListOfItems is not null) // I can verify that it is not null
    {
        @foreach (var item in Model.MyListOfItems)
        {
            <div class="col-6">
                @Html.DisplayFor(i => item.Text)
            </div>
        }
    }
</div>

【讨论】:

    【解决方案2】:

    您可以分块您的项目列表,以便您可以像这样遍历您的子列表列表:

    <table>
        <tbody>
        @{
            var listOfSubLists = Model.MyListOfItems
                                    .Select((x, i) => new { Index = i, Value = x })
                                    .GroupBy(x => x.Index / 2)
                                    .Select(x => x.Select(v => v.Value).ToList())
                                    .ToList();
        }
        @foreach (var subList in listOfSubLists)
        {
            <tr>
                @foreach (var item in subList)
                {
                    <td>
                        @Html.DisplayFor(i => item.Text)
                    </td>
                }
            </tr>
        }
        </tbody>
    </table>
    

    这样,你就可以使用&lt;table&gt;标签了。我认为这比在 UI 中使用 Bootstrap col- 类创建表更合适。

    还有.NET6 LINQ will support a built-in chunk method,它允许您将列表分成一行代码:

    var listOfSubLists = Model.MyListOfItems.Chunk(2);
    

    【讨论】:

    • 啊,太棒了,非常感谢!这真是太好了,知道它将来会派上用场,非常感谢!
    猜你喜欢
    • 2022-09-24
    • 2017-09-12
    • 1970-01-01
    • 2022-11-03
    • 2021-05-07
    • 1970-01-01
    • 2019-10-18
    • 2018-06-15
    • 1970-01-01
    相关资源
    最近更新 更多