Существует ли механизм представления ASP.Net MVC, поддерживающий представления JavaScript? - PullRequest
4 голосов
/ 07 декабря 2008

Я хотел бы сгенерировать немного JavaScript на стороне сервера в ASP.Net MVC. Есть ли движок просмотра, который поддерживает это? В идеале я хотел бы иметь возможность получить JavaScript из URL, например:

http://myapp/controller/action.js

Я посмотрел на проект MonoRail, и у них, похоже, есть эта функция, но в ней очень мало документации, и я не могу найти никаких портов для ASP.Net MVC.

Редактировать: Идея состоит в том, чтобы иметь возможность отображать страницу как в стандартном HTML, используя URL-адрес, такой как:

http://myapp/controller/action

и как js (в частности, компонент ExtJS), используя первый URL в вопросе. В контроллере будет только одно действие, но два представления: одно для HTML и одно для JS.

Редактировать 2: В основном я хотел достичь того же результата, что и Разбор расширения маршрутизатора / обработка запросов в CakePHP.

Ответы [ 6 ]

3 голосов
/ 08 декабря 2008

Я хотел расширить эту идею, чтобы не только разрешать представления Javascript, но более или менее любой тип документа. Чтобы использовать его, вы просто помещаете представления для URL * .js в подпапку папки представления вашего контроллера:

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

Класс является декоратором для любого типа ViewEngine, так что вы можете использовать его с NVelocity / WebForms / Независимо от:

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

Спасибо всем за помощь!

2 голосов
/ 03 февраля 2009

В июльском выпуске ASP.NET Futures появился новый управляемый JScript (я не могу найти более новый). Я успешно справился с этим немного - но будьте осторожны, вы, вероятно, будете вынуждены проделать некоторую дополнительную работу, синтаксический анализ .ASPX для JScript необычно глючит.

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

2 голосов
/ 07 декабря 2008

На основании ваших правок я попробую с новым ответом, утверждая, что вам нужны данные json для ExtJS. Я только что проверил его в приложении, которое я создаю, и оно работает нормально. Сначала вам нужно два маршрута

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

}
1 голос
/ 07 декабря 2008

Вам не обязательно нужен движок для просмотра, просто верните текстовый результат.

Вот контроллер (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-адреса в тег скрипта.

1 голос
/ 07 декабря 2008

Мне нужно было сделать что-то очень похожее, и я использовал механизм просмотра nvelocity из MVCContrib - технически вы могли бы использовать механизм просмотра aspx по умолчанию, но я обнаружил, что синтаксис nvelocity гораздо проще для выпуск сценария (не волнуйтесь, если вы не использовали его раньше - я потратил около 10 минут, чтобы выяснить это!).

Тогда вам просто нужно добавить маршрут в таблицу маршрутов, чтобы обработать направление вашего .js url к действию!

EDIT

Не могу проверить это, так как у меня нет визуальной студии, но для маршрута у вас может быть что-то вроде этого:

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
  {
     ... 
  }
}

Что касается структуры каталогов - вы сами по себе! Не потому, что я не хочу быть полезным, а скорее потому, что у вас есть гибкость, чтобы делать с ней то, что вы хотите!

0 голосов
/ 07 декабря 2008

Если вы просто хотите сгенерировать javascript на основе ViewData, вы можете создать свой собственный результат. Здесь является примером.

...