中止/跳过/取消Razor视图的渲染

h b*_*bob 14 asp.net asp.net-mvc razor

许多开发人员这样做:

public void foo() {
  if (flag) {
    // do stuff
  }
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢"早退",所以这样做:

public void foo() {

  if (!flag) return;

  // do stuff

}
Run Code Online (Sandbox Code Playgroud)

在ASP.NET-MVC Razor视图中,中止/跳过/取消渲染视图/部分视图的正确方法是什么?例如,我如何转换它:

@if (flag) {
  // do stuff
}
Run Code Online (Sandbox Code Playgroud)

这样的事情:

@if (!flag) { /* what do I do here to abort/skip/cancel the rendering? */ }

// do stuff
Run Code Online (Sandbox Code Playgroud)

我已经尝试过使用return和播放Request,但我不确定这会如何影响这个过程.这样做的正确方法是什么?

h b*_*bob 23

正如我上面提到的,你可以简单地发一个return.

我记得cshtml文件是在运行时编译的,其中包括所有内联代码以及静态html.这意味着理论上,我希望任何代码都保持原样,不会以任何方式进行转换.

所以,如果你这样做:

@if (!flag) { return; }

// do stuff
Run Code Online (Sandbox Code Playgroud)

按预期工作(至少对我而言).我只是想知道这是否会导致任何意想不到的副作用.

  • @AdrianoRepetti:在我作为开发人员的早期职业生涯中,我总是试图在我的方法/成员中拥有一(或两个)“回报”点。因为那是每个人都被告知要做的事情。事实证明,试图实现这一目标最终会产生过多的代码嵌套。你真的不应该仅仅为了实现那个过时的原则而改变或牺牲合理的代码流。在现代编程中,共识是如果你可以退出一个方法,那就去做。而且越早越好。甚至不需要计算你有多少返回,只要你的重点是减少代码嵌套。无论如何,我的0.02美元。 (3认同)
  • +1我的upvote,但我不会在任何页面中使用它(如果你有20行功能,早期返回是很好的IMO但通常 - 一个cshtml页面更长,更复杂,正是单个返回点已被使用的原因过去).无论如何,即使我不欣赏它,也因为我甚至不知道它可能会起作用!通过快速查看使用Reflector来反汇编生成的代码,没有(可见的)副作用似乎没问题. (2认同)

Adr*_*tti 5

如果使用“中止”表示您想根据该标志排除某些内容,那么您无事可做,只需用于if分隔这些部分(最终它甚至可能是从该行到文件末尾)。像这样:

 @if (Model.User.HasEditingPrivileges)
 {
     <input type="button" id="edit" value="Edit"/>
 }
Run Code Online (Sandbox Code Playgroud)

很快它就会变得难以理解,因此您可以为此使用部分视图(特别是如果您必须包含/排除的块很大):

 @if (Model.User.HasEditingPrivileges)
 {
     Html.RenderPartial("EditSection");
 }
Run Code Online (Sandbox Code Playgroud)

如果您需要删除/跳过/取消页面创建(例如重定向到另一个页面或显示完全不同的内容),如下所示:

@if (!Model.User.hasEditingPrivileges)
{
    // Ooops, he shouldn't see this page, go back to Home!
}
Run Code Online (Sandbox Code Playgroud)

那么你在错误的地方做那个检查。在您的控制器中执行此操作,它会选择正确的视图,而视图不会意识到此类逻辑:

public ActionResult View(int id)
{
    if (HasUserEditingPrivileges)
        return View("Edit", new MyModel(id));

    return Redirect("UnauthorizedAccess"); // Oops, something went wrong
}
Run Code Online (Sandbox Code Playgroud)

为什么不?

  • 因为视图不应该知道这种逻辑。如果您需要类似的东西(CGI 之类的顺序流),那么您不应该使用 MVC,因为它增加了您不需要的复杂性。
  • 因为你不能(除非有人发现一个可怕的肮脏的黑客技巧)。MVC 的结构是在必须显示页面时构建页面(控制器决定哪个页面以及使用哪些数据)。当这个建筑开始时,需要一个输出(除非你抛出一个异常来表示错误,但你真的应该避免异常来处理程序流......)。对于小的 if,您可以简单地使用第一个提到的方法。

总结一下:

在 ASP.NET-MVC Razor 视图中,中止渲染视图/部分视图的正确方法是什么?

没有正确的方法,因为你不能这样做。视图中的代码必须呈现页面,它不必决定应该将哪个页面发送给客户端。如果您正在做其他任何事情,那么您正在使用 MVC,因为它不应该被使用,这是不正确的。