【问题标题】:ASP.NET MVC 4 - Alternative Render based on requestASP.NET MVC 4 - 基于请求的替代渲染
【发布时间】:2013-06-09 18:16:49
【问题描述】:

尝试实现一个系统,开发人员可以照常创建一个 cshtml Razor 视图(例如,一系列 @Html.EditorFor(t=>t.MyProperty) 调用,其中穿插着标记等),但基于某些标题通过在请求中不同的响应。

举个例子:

标准用户通过在浏览器中输入路线导航到操作,获得标准的、预期的 HTML 结果。

非人类系统访问与用户相同的 URL,但包含一个 HTTP 标头来标识自己,获取自定义输出。在这种情况下,自定义输出是使用 EditorFor 调用定义的字段的 JSON 表示形式。

通过创建一个名为 CustomEditorFor 的新帮助程序,我已经取得了相当大的进展字段以逗号分隔并包装为 JSON 集合,但助手可用的信息似乎没有给我任何关于它是视图中的第一个/最后一个等的上下文。

我正在寻找我需要覆盖的地方以相对干净地执行此操作。到目前为止,看起来我需要 IView 的自定义实现(或更可能是 RazorView 的子类化)和 ViewEngine 的自定义实现(我们已经将 RazorViewEngine 子类化以处理路径等,所以这不是问题),它看起来像,为了获得绝对理想的结果,我可能还需要创建 WebViewPage 或 WebPageBase 的子类,以便能够影响响应中显示或未显示的内容等。

我确实有一些限制:

  1. 我不能为此使用单独的视图文件
  2. 由于 (1),我无法将 JSON 的位放入视图文件中。默认情况下,它需要正确呈现为 HTML,并且仅呈现为存在正确标头的 JSON

有人做过类似的事情吗?我在正确的道路上吗?有没有更简单的方法来做到这一点?感觉设计过度了,但我目前看不出有任何其他方法可以干净地做到这一点。

【问题讨论】:

  • 对于普通请求和基于机器的请求,您的 url 结构是否必须完全相同?您可以将 Web API 与 MVC4 一起使用,它会以 Json 响应。限制是您必须在某处使用包含 /api/ 的不同 url。
  • 不幸的是,它必须是一样的,但你的思路是正确的。最终,输出被首选为带有 HTML 回退的 JSON 的情况,因此如果没有我想避免的重定向,备用 URL 将无法工作。
  • 提供更多信息,本质上该应用程序设计用于单页应用程序或 IOS/Android 本机应用程序,这是 JSON 要求的来源,但 URL 相同对于浏览应用程序的普通用户将起作用,这将导致 HTML。目的是让开发人员一次性创建他们的视图模型和视图,以 HTML 为目标,并让设备和单页应用程序能够以 JSON 格式获取他们需要的数据,而无需渲染/解析 HTML。
  • 我认为您不必担心覆盖任何视图功能。如果您的操作返回 ActionResult,您可以根据 Request.Headers 集合中的 KeyValue 在 JSonResult 和 ViewResult 之间切换。如果这看起来还是有点脏,你可以将它抽象到另一个类吗?

标签: asp.net asp.net-mvc json asp.net-mvc-4 razor


【解决方案1】:

想到的一种方法,并且需要您的工作量最少,如下所示: 首先,您可以使用DisplayModeProvider 并为您的特定代理注册一个模式。以下是注册 iPhone(浏览器)的方法。使用自定义扩展

 protected void Application_Start()
    {
        DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone")
        {
            ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf
                ("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
        });

       ...
    }

其次,您可以使用自定义扩展为每个视图编写一个视图,即myView.MyCustomExtention.cshtml

来自您的预期代理的请求将使 MVC 使用您的自定义扩展呈现视图

第三,您可以使用 @Html.RenderPartial() 在带有自定义扩展名的视图中呈现您的视图

由于您已经拥有为每个控件呈现相应 JSoN 的 CustomEditorFor,因此您新创建的视图使您能够添加开始和结束括号。

就逗号而言,您可以在 CustomEditorFor 中的每个元素之后添加一个逗号,并在 JSON 中使用一个虚拟的最后一个元素来去掉最后一个逗号(或者如果您的视图中只有一个元素)

免责声明:这是基于我的理论知识。我还没有自己做这件事。

【讨论】:

    猜你喜欢
    • 2021-09-27
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多