最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Is there an ASP.Net MVC view engine that supports JavaScript views? - Stack Overflow

programmeradmin1浏览0评论

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 ponent) 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.

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 ponent) 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.

Share Improve this question edited Jul 13, 2012 at 9:10 tereško 58.5k25 gold badges100 silver badges150 bronze badges asked Dec 7, 2008 at 18:58 JacobJacob 23.2k8 gold badges42 silver badges55 bronze badges
Add a ment  | 

6 Answers 6

Reset to default 3

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!

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

}

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./downloads/details.aspx?FamilyId=A5189BCB-EF81-4C12-9733-E294D13A58E6&displaylang=en

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 plex 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.

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!

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

发布评论

评论列表(0)

  1. 暂无评论