2013-06-13 22 views
1

试图实现一个系统,开发人员将按照惯例创建一个cshtml Razor视图(例如,一系列@ Html.EditorFor(t => t.MyProperty)调用穿插带有标记等),但基于请求中的某些头部来区分响应。ASP.NET MVC 4 - 基于请求的替代渲染

作为一个例子:

标准用户通过键入路由到浏览器导航到的动作,获取标准,预期HTML结果。

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

通过创建一个名为CustomEditorFor的新帮手,如果它的存在会抛出JSON,或者推迟到HtmlHelper.EditorFor,如果不存在,但这给我一些限制 - 我需要每个这些字段用逗号分隔并包装成JSON集合,但助手可用的信息似乎没有给出任何关于视图中第一个/最后一个等等的上下文。

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

我在这里有几个限制:

  1. 我不能使用一个单独的视图文件中查找该
  2. 我不能把比特用于JSON在视图文件中,因为(1)。它需要默认呈现为HTML,并且仅适用于存在正确标题的JSON

有没有人沿着这些方向做过任何事情?我在正确的道路上吗?有没有更简单的方法来做到这一点?感觉非常糟糕,但我目前看不到任何其他方式干净利落。

+0

您的网址结构是否必须与普通和基于机器的请求完全相同?您可以使用MVC4的Web API,它将在Json中响应。限制是你不得不使用包含/ api /的某个地方的不同url。 – Stokedout

+0

不幸的是它必须是相同的,但你沿着正确的路线。最终,这是一种输出优选为JSON和HTML回退的情况,所以如果没有我想避免的重定向,替代URL将不起作用。 –

+0

为了提供更多信息,本质上是应用程序的设计与单页面应用程序或IOS/Android本机应用程序一起使用,这是JSON要求的来源,但相同的URL将用于正常播放用户浏览到会导致HTML的应用程序。目标是让开发人员创建视图模型和视图一次,针对HTML以及设备和单页应用程序只需获取JSON所需的数据而无需渲染/解析HTML。 –

回答

0

您想到的一个方法是,您需要的工作量最少: 首先,您可以使用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()

渲染自定义扩展的意见里面你的看法既然你已经有了CustomEditorFor呈现相应的JSON对于每个控件,新创建的视图使您能够添加起始和结束括号。

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

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