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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With