如何在Durandal中使用cshtml文件?

时间:2013-02-20 14:07:25

标签: asp.net-mvc-4 single-page-application durandal

我在VS2012上获得了DurandalJS StarterKit模板......一切都很好......

但在某些观点中,我需要做类似的事情:

@if (Roles.IsUserInRole("Administrators"))
{
   <p>Test</p>
}

然而,对于durandal,我的所有观点都是'.html'文件......是否可以使用'.cshtml'文件来访问某些类似的信息?

或者还有其他办法与durandal一起做吗?

小型

8 个答案:

答案 0 :(得分:32)

我这样做:

  1. 为Durandal视图创建一个通用控制器:

    public class DurandalViewController : Controller
    {
      //
      // GET: /App/views/{viewName}.html
      [HttpGet]
      public ActionResult Get(string viewName)
      {
        return View("~/App/views/" + viewName + ".cshtml");
      }
    }
    
  2. 注册路线:

    routes.MapRoute(
        name: "Durandal App Views",
        url: "App/views/{viewName}.html",
        defaults: new { controller = "DurandalView", action = "Get" }
    );
    
  3. 将Views / web.config复制到/App/views/web.config(因此Razor视图在此位置工作)。

  4. 这让我可以使用普通的Durandal约定(甚至是视图的html扩展名),并将durandal视图作为cshtml文件放在正常位置,而不再添加任何服务器代码。

    如果你还有静态html视图,你也可以将cshtml视图放在子文件夹中或使用普通的MVC / Views文件夹。

答案 1 :(得分:8)

我不建议在Durandal中使用ASP.NET MVC。

您可能要做的是使用 Razor视图引擎(以获得编译器的好处,强类型等),它独立于ASP.NET MVC。只需WebAPI进行数据I / O就足以高效地创建Durandal.js应用程序。

如果您有兴趣使用 Razor / CSHTML与Durandal和Knockout ,那么有一个名为 FluentKnockoutHelpers 的开源选项可能正是您所需要的。它提供了ASP.NET MVC的许多“好”部分,允许您使用Durandal和Knockout的强大功能,几乎没有垮台。

简而言之,它提供了许多功能,使得Durandal / Knockout开发与ASP.NET MVC一样简单。 (您只需提供一个C#类型,您的JavaScript模型基于大多数功能。)您只需要为复杂的情况编写JavaScript和未编译的标记,这是不可避免的,与MVC没有区别! (除了在MVC中你的代码也可能最终也会是一个很大的jQuery混乱,这就是为什么你首先使用Durandal / Knockout!)

功能

  • 使用类似于ASP.NET MVC的强类型,流畅,lambda表达式助手,无痛地生成Knockout语法
  • 丰富的intellisense和编译器支持语法生成
  • Fluent语法可以轻松创建自定义帮助程序或扩展内置的
  • OSS替代ASP.NET MVC助手:随意添加社区中每个人都可以使用的可选功能
  • 无痛地在几行代码中为所有当前/未来的应用程序类型和更改提供基于.NET类型和DataAnnotations的验证
  • 客户端JavaScript对象工厂(基于C#类型)创建新项目,例如列表,没有头疼或服务器流量

没有FluentKnockoutHelpers的示例

<div class="control-group">
    <label for="FirstName" class="control-label">
        First Name
    </label>
    <div class="controls">
        <input type="text" data-bind="value: person.FirstName" id="FirstName" />
    </div>
</div>
<div class="control-group">
    <label for="LastName" class="control-label">
        Last Name
    </label>
    <div class="controls">
        <input type="text" data-bind="value: person.LastName" id="LastName" />
    </div>
</div>
<h2>
    Hello,
    <!-- ko text: person.FirstName --><!-- /ko -->
    <!-- ko text: person.LastName --><!-- /ko -->
</h2>

使用.NET类型提供FluentKnockoutHelpers,您可以使用Intellisense和Razor / CSHTML中的编译器

进行风格设计
@{
  var person = this.KnockoutHelperForType<Person>("person", true);
}

<div class="control-group">
    @person.LabelFor(x => x.FirstName).Class("control-label")
    <div class="controls">
        @person.BoundTextBoxFor(x => x.FirstName)
    </div>
</div>
<div class="control-group">
    @person.LabelFor(x => x.LastName).Class("control-label")
    <div class="controls">
        @person.BoundTextBoxFor(x => x.LastName)
    </div>
</div>
<h2>
    Hello,
    @person.BoundTextFor(x => x.FirstName)
    @person.BoundTextFor(x => x.LastName)
</h2>

查看 Source Live Demo ,详细了解FluentKnockoutHelper在非平凡的Durandal.js应用程序中的功能。

答案 2 :(得分:7)

是的,你绝对可以在Durandal上使用cshtml文件并利用服务器上的Razor。我认为这也意味着你想要MVC,所以你也可以这样做并使用它的路由。

如果您不想要路由,那么您可以在web.config中设置webpages.Enabled,正如其他评论所示。

<add key="webpages:Enabled" value="true" /> 

答案 3 :(得分:5)

我不建议您直接使用.cshtml文件作为视图。你最好将.cshtml文件放在控制器后面。

例如,获取HotTowel示例,编辑/App/main.js,并使用以下内容替换函数定义:

define(['durandal/app', 
        'durandal/viewLocator', 
        'durandal/system',
        'durandal/plugins/router',
        'durandal/viewEngine', 
        'services/logger'],
function (app, viewLocator, system, router, viewEngine, logger) {

请注意,我们添加了对Durandal viewEngine的引用。然后我们需要替换

viewLocator.useConvention();

viewLocator.useConvention('viewmodels', '../../dynamic'); 
viewEngine.viewExtension = '/';

viewLocation.useConvention的第一个参数将/ Apps / viewmodels /目录设置为视图模型js文件的位置,但对于视图位置,使用URL http://example.com/dynamic/,扩展名为“/” 。因此,如果Durandal正在寻找名为'shell'的视图,它将引用http://example.com/dynamic/shell/(这是因为视图目录是相对于viewmodels目录映射的,因此/App/viewmodels/../../dynamic会给你简单/动态的。

按照惯例,此前一个URL(http://example.com/dynamic/shell/)将映射到控制器DynamicController,并且操作“Shell”。

在此之后,您只需添加一个控制器 - DynamicController.cs,如下所示:

// will render dynamic views for Durandal
public class DynamicController : Controller
{
    public ActionResult Shell()
    {
        return View();
    }

    public ActionResult Home()
    {
        return View();
    }

    public ActionResult Nav()
    {
        return View();
    }

    public ActionResult Details()
    {
        return View();
    }

    public ActionResult Sessions()
    {
        return View();
    }

    public ActionResult Footer()
    {
        return View();
    }
}

为上述每个操作创建.cshtml文件。这样您就可以使用控制器,服务器端IoC等为您的SPA生成动态视图。

答案 4 :(得分:2)

DurandaljS是一个客户端框架,主要构成单页应用程序(SPA)的坚实基础。 我假设你使用asp.net web API作为你的服务器技术。在这种情况下,您可以在API控制器中确定用户的角色,并根据返回到客户端的数据。在客户端上,您可以使用Knockout“if”绑定来显示/隐藏页面的某些区域。

您可能做的是将此代码放在Index.cshtml中。

答案 5 :(得分:2)

以下链接显示了如何将moduleid自定义为viewid映射

http://durandaljs.com/documentation/View-Location/

按照惯例,durandal试图在以下步骤中找到视图网址

1)Checke对象是否具有返回dom或字符串的getView()函数(视图的url)

2)如果object没有getView函数,则检查对象是否具有viewUrl属性

3)如果以上两个步骤无法生成url或DOM视图,则drundal会降为默认约定

使用在main.js中定义的view url(Views文件夹的路径)将moduleid xyz.js映射到xyz.html

因此对于moduleid xyz.js,视图的路径为views/xyz.html

您可以通过覆盖convertModuleIdToViewId函数来覆盖此默认映射行为。

因此,您可以通过多种方式自定义特定模型(.js对象)的视图网址

答案 6 :(得分:1)

我对Durandal进行了扩展,使您能够将applicationContent div与applicationHost div一起放在cshtml文件中。在applicationContent中,您现在可以使用ASP .Net MVC语法和knockout绑定。

我唯一做的就是在viewLocator.js文件中添加一些额外的代码来查找applicationContent div:

        locateViewForObject: function(obj, area, elementsToSearch) {
        var view;

        if (obj.getView) {
            view = obj.getView();
            if (view) {
                return this.locateView(view, area, elementsToSearch);
            }
        }

        if (obj.viewUrl) {
            return this.locateView(obj.viewUrl, area, elementsToSearch);
        }

        view = document.getElementById('applicationContent');
        if (view) {
            return this.locateView(view, area, elementsToSearch);
        }

        var id = system.getModuleId(obj);
        if (id) {
            return this.locateView(this.convertModuleIdToViewId(id), area, elementsToSearch);
        }

        return this.locateView(this.determineFallbackViewId(obj), area, elementsToSearch);
    },

您原来的cshtml文件现在可以执行以下操作:

<div class="row underheader" id="applicationContent">
<div class="small-5 columns">
    <div class="contentbox">
        @using (Html.BeginForm("Generate", "Barcode", FormMethod.Post, Attributes.Create()
                                                                                    .With("data-bind", "submit: generateBarcodes")))
        {
            <div class="row formrow">
                <label for="aantalBijlagen">@Translations.Label_AantalBijlagen</label>
            </div>
            <div class="row">
                <select name="aantalBijlagen" class="small-6 columns">
                    <option>0</option>
                    <option>1</option>
                    <option>2</option>
                    <option>3</option>
                    <option>4</option>
                </select>
            </div>
            <div class="row">
                <button class="button right" type="submit" id="loginbutton"><span class="glyphicon glyphicon-cog"></span> @Translations.Action_Generate</button>
            </div>
        }
    </div>
</div>
<div class="small-7 columns" data-bind="if: hasPdfUrl">
    <div class="contentbox lastcontent">
        <iframe data-bind="attr: {src: pdf_url}"></iframe>
    </div>
</div>

你可以找到我的durandal项目的分叉here和一个关于我做了什么以及如何做here的小博文。

答案 7 :(得分:0)

我对DurandalJS不是很熟悉,但因为它是一个客户端系统,所以在服务器上使用什么技术生成HTML标记应该没什么区别。因此,如果您使用Razor CSHTML文件在服务器上生成HTML,DurandalJS应该可以正常使用它。

如果您遇到特定错误,请分享该错误,但我想不出有什么理由不起作用。