Blazor应用嵌套if语句运行异常 尾部if语句直接输出文本排查
问题核心原因
你的问题本质是对Razor视图(ASP.NET Core/Blazor)的语法上下文切换规则、标签校验机制不熟悉导致的,核心错误点有三个:
- 拆分输出的不完整HTML标签没有做特殊处理:你代码中单独输出的
<tr><td>、</td></tr>属于不完整的标签片段,Razor默认会自动校验标签闭合性,识别到未闭合标签就会抛出错误。 - 上下文切换没有明确标识:Razor遇到HTML标签时会自动从C#代码上下文切换到标记上下文,后续的C#逻辑如果没有加
@标识,会被直接当成普通文本输出到页面,这就是最后一个if语句直接显示的原因。 - 存在显式语法错误:
- 通信状态判断的else分支中,td标签书写错误:
<td> class=cardAlert>应为<td class=cardAlert> - 设备名称、自定义状态值输出时没有加
@前缀,会直接输出变量名字符串 - 设备Updating状态的显示文本复制错误,写为了Status: Normal
- 通信状态判断的else分支中,td标签书写错误:
解决方法
按照以下步骤修改即可解决所有问题:
1. 处理不完整HTML片段
所有拆分输出的不完整标签,统一加@:前缀,告诉Razor将其作为普通字符串输出,不做标签闭合校验。
2. 明确标记C#代码
在标记上下文中的C#逻辑,用@前缀或者@{ }代码块包裹,明确告诉Razor这部分是需要执行的C#代码。
3. 修复所有显式语法错误
修正后核心代码示例
@if (CurrentSystem == null) { <p><em>Loading...</em></p> } else { @foreach (Device thisDevice in CurrentSystem.LocalDevices) { menuCounter++; divCounter++; @if (divCounter == 1) { // 输出不完整标签加@:前缀 @:<tr><td class=cardBox> } else { @:<tr><td class=outSideColumns></td> @:<td></td> @:<td class=cardBox> } // 标记上下文里的C#代码用代码块包裹 @{ targetName = "target" + menuCounter; targetNameWithDot = "." + targetName; menuId = "contextMenu" + menuCounter; modalID = "modalWindow" + menuCounter; } <table> <tr> <td></td> <td> <div class="targetName" style="text-align:right;justify-content:right;"> <a href="#" class="menuButton">...</a> </div> </td> </tr> <tr> <td colspan="2" align="center"> <!-- 输出变量加@前缀 --> <h3>@thisDevice.DeviceName</h3> <img src="@ReturnDeviceImage(thisDevice)" class=deviceImage /> @if (thisDevice.CurrentStatus == Device.DeviceStatus.Alert) { <h4 Class="cardAlert">Status: Alert</h4> } else if (thisDevice.CurrentStatus == Device.DeviceStatus.Inactive) { <h4 Class="cardInactive">Status: Inactive</h4> } else if (thisDevice.CurrentStatus == Device.DeviceStatus.Unknown) { <h4 Class="cardUnknown">Status: Unknown</h4> } else if (thisDevice.CurrentStatus == Device.DeviceStatus.Normal) { <h4 Class=cardNormal>Status: Normal</h4> } else if (thisDevice.CurrentStatus == Device.DeviceStatus.Updating) { <!-- 修正复制错误的文本 --> <h4 Class=cardUpdating>Status: Updating</h4> } else { <h4>Status: @thisDevice.CurrentStatus</h4> } <TelerikContextMenu IdField="@menuId" Selector="@targetNameWithDot" Data="@MenuItems" OnClick="@((ContextMenuItem item) => OnItemClick(item, thisDevice.DeviceIDHash))"> </TelerikContextMenu> </td> </tr> <tr> <td class=nameDivs> Device Type: </td> <td> @thisDevice.DeviceType </td> </tr> <tr> <td class=nameDivs> Hostname: </td> <td> @thisDevice.DeviceHostname </td> </tr> <tr> <td class=nameDivs> Communications: </td> @if (thisDevice.UsingEncryption) { <td class=cardNormal>Are Encrypted</td> } else { <!-- 修正错误的td标签写法 --> <td class=cardAlert>Are Not Encrypted</td> } </tr> <tr> <td class=nameDivs> Anomaly Response Level: </td> <td> @thisDevice.AnomalyResponse </td> </tr> </table> <!-- 标记上下文中的if加@前缀 --> @if (divCounter == 1) { // 不完整闭合标签加@:前缀 @:</td> @:<td></td> @:<td class=outSideColumns></td> @:</tr> } else { @:</td></tr> divCounter = 0; } } </table> }
之前异常现象的原因说明
- 最后一个
if直接输出文本:前面输出了完整的</table>标签,Razor处于标记上下文,你没有加@标识,所以被当成普通文本输出 - 加
@就报缺少闭合标签:之前没有加@:的不完整<tr><td>被Razor识别为正式标签,校验时发现没有闭合,加@:后Razor会将其作为纯字符串输出,不会做标签校验 - 中间的
if不加@就不运行:这些if处于<table>标签内部的标记上下文,必须加@才能被Razor识别为C#代码 foreach不加@就没有输出:不加@的foreach会被Razor当成普通文本,不会被解析为循环逻辑
内容的提问来源于stack exchange,提问作者Ken Tola
相关产品推荐
相关产品推荐

