4

我想在 ASP.Net MVC 的服务器端生成一些 JavaScript。是否有支持此功能的视图引擎?理想情况下,我希望能够从以下网址获取 JavaScript:

http://myapp/controller/action.js

我查看了 MonoRail 项目,他们似乎有这个功能,但是文档非常缺乏,我找不到任何 ASP.Net MVC 的端口。

编辑:这个想法是能够通过使用如下网址将页面呈现为标准 HTML:

http://myapp/controller/action

并通过使用问题中的第一个 url 作为 js(特别是 ExtJS 组件)。控制器中只有一个动作,但有两个视图:一个用于 HTML,一个用于 JS。

编辑 2:我基本上想达到与CakePHP中的路由器扩展解析/请求处理相同的结果。

4

6 回答 6

3

我想扩展这个想法,不仅允许 Javascript 视图,而且或多或少任何类型的文档。要使用它,您只需将 *.js url 的视图放在控制器视图文件夹的子文件夹中:

\Views
+-\MyController
  +-\js
  | +-Index.aspx <- This view will get rendered if you request /MyController/Index.js
  +-Index.aspx

该类是任何类型的 ViewEngine 的装饰器,因此您可以将它与 NVelocity/WebForms/Whatever 一起使用:

public class TypeViewEngine<T> : IViewEngine where T : IViewEngine
{
    private readonly T baseEngine;
    public T BaseEngine
    {
        get { return baseEngine; }
    }

    public TypeViewEngine(T baseEngine)
    {
        this.baseEngine = baseEngine;
    }

    public void RegisterRoutes(RouteCollection routes)
    {
        routes.MapRoute(
            "TypeViewEngine",
            "{controller}/{action}.{type}",
            new {controller = "Home", action = "Index", type = "html"}
            );
    }

    public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName)
    {
        var vars = controllerContext.RouteData.Values;
        if(vars["type"] != null && vars["type"].ToString() != "html")
        {
            viewName = string.Format("{0}/{1}", vars["type"], viewName);
        }
        return baseEngine.FindView(controllerContext, viewName, masterName);
    }

    public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName)
    {
        return baseEngine.FindPartialView(controllerContext, partialViewName);
    }

    public void ReleaseView(ControllerContext controllerContext, IView view)
    {
        baseEngine.ReleaseView(controllerContext, view);
    }
}

然后,在您的 Global.asax.cs 文件中:

protected void Application_Start()
{
    var ve = new TypeViewEngine<WebFormViewEngine>(new WebFormViewEngine());
    ve.RegisterRoutes(RouteTable.Routes);
    RegisterRoutes(RouteTable.Routes);

    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(ve);
}

感谢大家对此的帮助!

于 2008-12-08T05:54:59.363 回答
2

根据您的编辑,我将尝试使用新答案,假设您需要 ExtJS 的 json 数据。我刚刚在我正在构建的应用程序中对其进行了测试,它运行良好。首先你需要两条路线

{controller}/{action}.{format}

{controller}/{action}

现在 Controller 类有一个 Json 方法来序列化你想要的任何对象,它是一个 JsonResult 所以你可以使用:

public ActionResult List(string format) {

    // logic here

    if (string.IsNullOrEmpty(format)) {
        return View();
    } else if (format == "js") {
        return Json(object_to_serialize);
    }

}
于 2008-12-07T20:44:40.020 回答
2

2007 年 7 月的 ASP.NET Futures 版本具有新的托管 JScript(我找不到更新的)。我已经成功地解决了一些问题 - 但请注意,您可能会被迫做一些额外的工作,JScript 的 .ASPX 解析存在无法使用的错误。

http://www.microsoft.com/downloads/details.aspx?FamilyId=A5189BCB-EF81-4C12-9733-E294D13A58E6&displaylang=en

于 2009-02-03T19:56:30.553 回答
1

我不得不做一些非常相似的事情,我使用了MVCContrib的 nvelocity 视图引擎——从技术上讲,你可以使用默认的 aspx 视图引擎,但我发现 nvelocity 语法对于输出脚本要简单得多(如果你以前没有用过它——我花了大约 10 分钟才弄明白!)。

然后你只需要向路由表添加一个路由来处理将你的 .js url 定向到操作!

编辑

无法验证这一点,因为我手头没有视觉工作室,但对于路线,您可能会有这样的事情:

RouteTable.Routes.Add(new Route
{
   Url = "[controller]/[action].js",
   Defaults = new { controller="home", requestType="javascript" }, // Whatever...
   RouteHandler = typeof(MvcRouteHandler)
});

RouteTable.Routes.Add(new Route
{
   Url = "[controller]/[action]",
   Defaults = new { controller="home"}, // Whatever...
   RouteHandler = typeof(MvcRouteHandler)
});

以 .js 结尾的请求应该通过第一条路线 - 无扩展名的请求将通过第二条路线。

然后您的操作可能有一个 requestType 参数:

public ActionResult MyAction (RequestType requestType)
{
  if(requestType == RequestType.JavaScript)
  {
     ... new nvelocity view to render javascript
  }
  else
  {
     ... 
  }
}

至于目录结构 - 你自己处理!不是因为我不想提供帮助,而是因为你可以灵活地做你想做的事!

于 2008-12-07T19:28:33.543 回答
1

您不一定需要查看引擎,只需返回纯文本结果。

这是我用来在 javascript 对象中呈现一些用户文化设置的控制器 (MonoRail):

[ControllerDetails("js")]
public class JavascriptController : Controller
{
    private ISessionContext sessionContext;

    public JavascriptController(ISessionContext sessionContext)
    {
        this.sessionContext = sessionContext;
    }

    public void CultureInfo()
    {
        var scriptformat = @"var cultureInfo = {0};";
        var json = Context.Services.JSONSerializer.Serialize(getJSONiZableCultureInfo(sessionContext.CurrentCulture));
        RenderText(String.Format(scriptformat, json));
    }

    object getJSONiZableCultureInfo(System.Globalization.CultureInfo  culture)
    {
        return new
                        {   // add more there
                            culture.NumberFormat
                        };
    }
}

对于原始文本渲染会闻到的更复杂的事情,任何视图引擎都可以工作。

此外,您不必使用 .js 扩展名将 url 放入脚本标记中。

于 2008-12-07T19:50:24.733 回答
0

如果您只想基于 ViewData 生成 javascript,您可以创建自己的自定义结果。是一个例子。

于 2008-12-07T19:54:29.810 回答