是否有支持 JavaScript 视图的 ASP.Net MVC 视图引擎?

发布于 2024-07-10 02:34:02 字数 610 浏览 11 评论 0 原文

我想在 ASP.Net MVC 的服务器端生成一些 JavaScript。 有支持这个的视图引擎吗? 理想情况下,我希望能够从这样的 url 获取 JavaScript:

http://myapp/controller/action.js

我查看了 MonoRail 项目,他们似乎有此功能,但它非常缺乏文档,而且我找不到任何 ASP 的端口。网络 MVC。

编辑: 这个想法是能够通过使用像这样的 url 将页面呈现为标准 HTML,

http://myapp/controller/action

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

编辑2:我基本上想达到与路由器扩展解析/请求处理

I would like to generate some JavaScript on the server side in ASP.Net MVC. Is there a view engine that supports this? Ideally I would like to be able to get JavaScript from an url like:

http://myapp/controller/action.js

I've looked at the MonoRail project, and they seem to have this feature, but it's very lacking in documentation, and I can't find any ports to ASP.Net MVC.

Edit: The idea is to be able to render a page both as standard HTML by using a url like:

http://myapp/controller/action

and as js (specifically an ExtJS component) by using the first url in the question. There would be only a single action in the controller, but two views: one for HTML and one for JS.

Edit 2: I basically wanted to achieve the same result as router extension parsing/request handling in CakePHP.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

暗恋未遂 2024-07-17 02:34:02

我想扩展这个想法,不仅允许 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);
}

感谢大家的帮助!

I wanted to extend this idea to not only allow Javascript views, but more or less any type of document. To use it, you just put the views for *.js urls in a subfolder of your controller's view folder:

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

The class is a decorator for any type of ViewEngine, so you can use it with 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);
    }
}

Then, in your Global.asax.cs file:

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);
}

Thanks for everyone's help with this!

原野 2024-07-17 02:34:02

根据您的编辑,我将尝试使用新答案,假设您需要 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);
    }

}

Based on your edit I'll try with a new answer asumming you need json data for ExtJS. I've just tested it in the app I'm building and it works fine. First you need two routes

{controller}/{action}.{format}

{controller}/{action}

Now the Controller class has a Json method to serialize whatever object you want and it's a JsonResult so you can just use:

public ActionResult List(string format) {

    // logic here

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

}
暖树树初阳… 2024-07-17 02:34:02

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

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

The July 2007 ASP.NET Futures release has the new Managed JScript (I can't find a newer one). I've successfully batted it around a bit - but beware, you will probably be forced to do some extra work, the .ASPX parsing for JScript is unusably buggy.

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

萌辣 2024-07-17 02:34:02

您不一定需要视图引擎,只需返回纯文本结果即可。

这是一个控制器(MonoRail),我用来在 javascript 对象中渲染一些用户文化设置:

[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 放入脚本标记中。

You don't necessarily need view engine for that, just return plain text result.

Here is a controller (MonoRail) I've used to render some user culture settings in a javascript object:

[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
                        };
    }
}

for more complex things for which raw text rendering would smell, any view engine would work.

Also you are not forced to use .js extension to put the url in your script tag.

爱情眠于流年 2024-07-17 02:34:02

我必须做一些非常类似的事情,并且我使用了 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
  {
     ... 
  }
}

至于目录结构 - 你就得靠你自己了! 不是因为我不想提供帮助,而是因为您可以灵活地用它做您想做的事情!

I had to do something very similar, and I used the nvelocity view engine from MVCContrib - technically you could use the default aspx view engine, but I found that the nvelocity syntax was a lot more straightforward for puting out script (don't worry if you haven't used it before - I spent about 10 minutes figuring it out!).

Then you just need to add a route to the route table to handle directing your .js url to the action!

EDIT

Can't verify this as I don't have visual studio to hand but for the route, you might have something like this:

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)
});

Requests ending in .js should go through the first route - extensionless requests fall through to the second.

Then your action could have a requestType param:

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

As for directory structure - you're on your own with that! Not because I don't want to be helpful, but more down to the fact that you have flexibility to do what you want with it!

執念 2024-07-17 02:34:02

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

If you just want to generate a javascript based on the ViewData you can create your own custom result. Here is an example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文