Как стать автором
Обновить

Комментарии 43

Помню твои статьи против Angular))) Уже не воюешь теперь?)
Помню твои статьи против Angular)))

Приятно видеть, что помнишь ))

Уже не воюешь теперь?)

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

Как тогда ни одного комментария в коде, так и сейчас. Вы хоть бы код комментариями покрыли. Да и если честно код не ахти.
Как тогда ни одного комментария в коде, так и сейчас. Вы хоть бы код комментариями покрыли.

Почему же ни одного, блочные комментарии есть, а каждую строку показалось очень перегружено и по ширине не удобно читать.

Да и если честно код не ахти.

Буду признателен, если посоветуете, что то конкретное. Это Get started, где я не рассматривал моменты, обобщенные Command/Query или html extensions, но и «не ахти» я не не вижу, хотя конечно это моё мнение.

А собственно зачем это тут? Мало чтоли фреймворков? Кто будет это использовать?
Кому нужно изучать странный способ определения банальных вещей (это я больше про *.cshtml)?
А собственно зачем это тут?

Решил, что это удачное место для продвижения

Мало чтоли фреймворков?

Одновременно client/server, не много.

Кто будет это использовать?

После подробного руководства, начинающие программисты (asp.net mvc), а тех кто уже пишет на чем то, будет сложно «переманить»

Кому нужно изучать странный способ определения банальных вещей (это я больше про *.cshtml)?

Основная причина, это типизация, которой так не хватает на JS.

P.S. Статья (как и сам framework) была в первую очередь для сотрудников нашей компании, а тут в целях информировать о том что у нас получилось (мы считаем, что не плохо) и попытки развить его во что то большое.
Основная причина, это типизация, которой так не хватает на JS.

TypeScript?
TypeScript?

Это не framework, а язык, так что это сложно сравнивать.
Так и JS — язык. Типизация вообще свойственна языку, а не фрейворку. Если вам не хватает типизации — почему не взять язык, в котором она есть, зачем городить фреймворк?
Так и JS — язык.

Я думал, Вы в рамках framework сравниваете, а так да, Вы правы.

Если вам не хватает типизации — почему не взять язык, в котором она есть, зачем городить фреймворк?

TypeScript не имеет интеграции с template (где у нас тоже типизация), а в сравнение с IML (декларативный язык) он не имеет функционала. Framework нужен, что бы ускорить разработку за счет «абстракции» от рутинных операций (Repository, CQRS, Ajax и т.д.), которые повторяются из проекта в проект.

Типизация на всех этапах это один из бонусов, но основное, что мы получаем от incframework — это эко-систему для разработки приложений (web,desktop). А вот на сколько гибкую, это пока открытый вопрос.

P.S. Мы уже вели дискуссии на эту тему, так что мне кажется Вам должны быть знакомы мои ответы ))

Я думал, Вы в рамках framework сравниваете, а так да, Вы правы.

А я не сравниваю, я отвечаю на ваш же тезис о том, что основная причина того, что вы напридумывали во view — это отсутствие типизации в JS. Как можно видеть из вашего дальнейшего текста, вы слегка лукавите.
А я не сравниваю, я отвечаю на ваш же тезис о том

Тезиз был в сравнение TypeScript и Incoding Framework.

что основная причина того, что вы напридумывали во view — это отсутствие типизации в JS

Да, в рамках View кроме поддержки Intelisense была задача получить декларативный язык, который будет интегрирован с серверной частью приложения (вызов CQRS) и типизированные Templatе и конечно больше ни каких undifend ))

В итоге мы пришли к тому, что все приложения строится на языке C# без написания дополнительного JS кода.

Плохо это или нет, уже конечно каждый сам решает, но многие скажут, что лучше знакомый JS, чем неизвестный псевдо-язык (просто набор методов на C# аля domain specific language) хотя мы на своей практики получили огромный прирост по скорости и безопасности при разработке.

— Скорость заключается в таких возможностях, как оборачивать код в HTML extensions (пример сложного), а так же Intellisense.

— Безопасность находится в том, что IML язык декларативный, а это значит то, что вызов любого метода будет работать (при условии правильных параметров), если конечно нету глобальной ошибки в рамках самого framework. Да это накладывает ограничения (есть много вариантов, для работы со сторонним JS), но всему своя цена.

На критику, что любой метод/код можно написать рабочим, скажу то что его надо реализовывать, а IML (к примеру HTML декларативный язык) уже готов и проверен.

P.S. Конечно IML это просто набор методов на языке C#, так что назвать его по «настоящему» декларативным сложно, но мне кажется это понятие очень хорошо подходит для его описания.
Тезиз был в сравнение TypeScript и Incoding Framework.

И кто придумал это сравнение?

В итоге мы пришли к тому, что все приложения строится на языке C# без написания дополнительного JS кода.

Я даже знаю, где я это уже видел — в WebForms. Там тоже серверные компоненты позволяли построить весь интерфейс декларативно…
Я даже знаю, где я это уже видел — в WebForms. Там тоже серверные компоненты позволяли построить весь интерфейс декларативно…

Так же можно привести в пример и asp.net mvc (Html.TextBoxFor, Html.DropDownFor) Если, Вы смотрели, как мы интегрируем IML в html элементы, то заметили, что используется RouteValueDictionary, который передается в TextBoxFor,DropDownFor и т.д.

Основное преимущество TextBoxFor и других html extensions, в том что их можно «связать» с серверной часть, а в частности с моделью.
Так же можно привести в пример и asp.net mvc (Html.TextBoxFor, Html.DropDownFor)

Отнюдь. asp.net MVC как раз спроектирован так, чтобы максимально облегчить взаимодействие HTML и клиентских скриптов (а не заменить одно другим). Это неоднократно повторяется в соответствующей литературе (например, у Эспозито): asp.net MVC опускается на уровень (или несколько) абстракции ниже, чем WebForms, чтобы дать фронт-энд разработчикам более детальный контроль за происходящим.

А вы поднимаете этот уровень абстракции обратно. Хорошо это или плохо — вопрос отдельный.

PS. AjaxGet(Url.Dispatcher().AsView("~/Views/Home/AddOrEditHuman.cshtml"))
Здравствуй, нарушение SoC.
А вы поднимаете этот уровень абстракции обратно.

Мы просто дополнительно передаем атрибуты в качестве параметра в уже существующие «конторолы» asp.net mvc.
Вы считаете, что возможность написать свой (ниже пример) html extensions это плохо?

 @Html.Rap().Admin.Tab(setting =>
                                  {
        setting.Url = Url.Dispatcher().AsView("~/Views/DiabetesMedication/Index.cshtml");
        setting.Title = "Diabetes Medications";
                                  })  


Сравнивания с asp.net control такие как, updatepanel, grid и т.д, то надо понимать, что для обработке клиентских сценариев все равно требовалось подписывать на события и писать JS, а мы полностью строим все на сервере (а вот выполняем и там и там)

Вот пример, ajax drop down в виде готового control

  @Html.ForGroup(r => r.FirstName).TextBox(control => control.Label.Name = "First name")

пример из статьи

Здравствуй, нарушение SoC.

Попробовал загуглить, но не нашел определения для SoC, Вы имеете ввиду, какую то проблему с безопасностью?
UPD. Пример, не тот привел, вот для Ajax drop down

@Html.For(r => r.AgencyId).DropDown(control =>
                                            {
                   control.Url = Url.Dispatcher().Query<GetSupportServicesForDDQuery>().AsJson();
                   control.AddClass("selectInput400 firstControl");
                                            })

Мы просто дополнительно передаем атрибуты в качестве параметра в уже существующие «конторолы» asp.net mvc.

Окей, давайте на примере.

Вы говорите, что ваше приложение строится целиком на C#, без написания JS. Как вы реализуете сложную клиентскую валидацию (поле такое-то должно зависеть от полей таких-то и таких-то)? А динамические интерфейсы (если выбрано поле такое-то, показать поля такие-то и такие-то)?

Сравнивания с asp.net control такие как, updatepanel, grid и т.д, то надо понимать, что для обработке клиентских сценариев все равно требовалось подписывать на события и писать JS, а мы полностью строим все на сервере (а вот выполняем и там и там)

Я сравниваю с девэкспрессом, где чертова уйма клиентского поведения реализовывалась самим контролом, и была разработчику недоступна.

Попробовал загуглить, но не нашел определения для SoC, Вы имеете ввиду, какую то проблему с безопасностью?

Я имею в виду Separation of Concerns.
Я имею в виду Separation of Concerns.

AjaxGet(Url.Dispatcher().AsView("~/Views/Home/AddOrEditHuman.cshtml"))
это тоже самое, что и
AjaxGet(Url.Action(«AddOrEditHuman»,«Home»))

Так что, не совсем понял, что именно нарушается. MVD (Url.Dispatcher()), просто строит адрес, но выполняется все потом на сервере в рамках Command/Query и Dispatcher

Я сравниваю с девэкспрессом, где чертова уйма клиентского поведения реализовывалась самим контролом, и была разработчику недоступна.

Вы сами пишете это поведение, точно так же, как и страницу HTML с помощью тэгов, но не думаете, как они «рисуются» браузером

P.S. Ответил на быстрые вопросы, а про валидацию с примерами, чуть позже.
AjaxGet(Url.Dispatcher().AsView("~/Views/Home/AddOrEditHuman.cshtml"))
это тоже самое, что и
AjaxGet(Url.Action(«AddOrEditHuman»,«Home»))

Нет. В первом случае я явно указываю серверу, какое представление мне нужно, а во втором — я указываю, какой экшн у какого контроллера вызвать. Разная степень информированности о сервере.

Вы сами пишете это поведение, точно так же, как и страницу HTML с помощью тэгов, но не думаете, как они «рисуются» браузером

Вот это я и называю повышеним абстракции — рисование, не думая. В WebForms действительно была такая идеология. В asp.net MVC от нее отказались.
Нет. В первом случае я явно указываю серверу, какое представление мне нужно, а во втором — я указываю, какой экшн у какого контроллера вызвать. Разная степень информированности о сервере.

Мы уже долго говорили на эту тему в статье про MVD. Мне кажется это не нарушение Separation of Concerns, а больше похоже на «обобщение», хотя SuperService тоже на него похож, но…
По мне плюсы, которые я получаю, а именно возможность писать на много меньше кода, покрывают с лихвой это момент, при том условии, что Вам не нужно ничего дополнительно дописывать.

Вот это я и называю повышеним абстракции — рисование, не думая. В WebForms действительно была такая идеология. В asp.net MVC от нее отказались.

Но, так же используют Html extensions для скрытия сложных и часто повторяемых html конструкций. Мы тоже довольно низко-уровневая часть, то есть IML он просто дает функционал, но ничего конкретного не реализовывает к примеру grid, tabs или TextBoxAlertByChange
По мне плюсы, которые я получаю, а именно возможность писать на много меньше кода, покрывают с лихвой это момент, при том условии, что Вам не нужно ничего дополнительно дописывать.

К сожалению, почти всегда — надо.

Мы тоже довольно низко-уровневая часть, то есть IML он просто дает функционал, но ничего конкретного не реализовывает к примеру grid, tabs или TextBoxAlertByChange

Тогда как же вам удалось полностью отказаться от JS?
К сожалению, почти всегда — надо.

MVD умеет вызывать Command/Query, отреднерить View (с Model или с данными из query), получить JSON или File из Query, что ещё надо даже не знаю. Если по каким то причинам, будет не хватать возможностей (хотя я пока не вижу), то можно совместно использовать и обычный Controller ( на работу AjaxGet это не повлияет, потому что ему нужен просто URL к вашем данным)

Тогда как же вам удалось полностью отказаться от JS?

от написания ДОПОЛНИТЕЛЬНОГО кода, то есть сам движок, который выполняет IML само собой на JS, потому что browser особо ничего не понимает.

P.S. примеры по валидации сейчас пишу!
сам движок, который выполняет IML само собой на JS

… и этот JS программистом никак не контролируется. Вот именно это мне и напомнило старые добрые времена WebForms.
… и этот JS программистом никак не контролируется. Вот именно это мне и напомнило старые добрые времена WebForms.

Нету у нас JS программистов ))))
Каждый разработчик это front-end и back-end в одном лице, потому что после написания Command/Query, он может сразу её выполнить на JS, не используя его.
Нету у нас JS программистов

Оно и видно.
Оно и видно.

Вы я так понимаю, начинаете грубить?
Нет, почему же. Просто это объясняет ваше желание полностью убрать программирование на JS.
Нет, почему же. Просто это объясняет ваше желание полностью убрать программирование на JS.

Хм, фраза «оно и видно» чаще намекает, на незнание или подчеркивание плачевности ситуации оппонента в каком то деле. Но, раз Вы этого не имели ввиду, то все окей.

P.S. примеры по валидаци, пишу ))

Вы говорите, что ваше приложение строится целиком на C#, без написания JS. Как вы реализуете сложную клиентскую валидацию (поле такое-то должно зависеть от полей таких-то и таких-то)? А динамические интерфейсы (если выбрано поле такое-то, показать поля такие-то и такие-то)?


Сценарий проверки email на уникальность по Ajax

    <span class="field-valiion-valid"></span>
    @(Html.When(JqueryBind.Change)
          .AjaxGet(Url.Dispatcher().Query(new  IsEmailUniqueQuery()
                                          {
                                                  Email = Selector.Jquery.Self()
                                          }))
          .OnSuccess(dsl =>
                     {
   dsl.WithClass("field-valiion-valid").JQuery.Attr.RemoveClass("field-validation-error");
   dsl.WithClass("field-valiion-valid").JQuery.Attr
       .AddClass("field-validation-error")
       .If(() => Selector.Result.For<IncBoolResponse>(r => !r.Value));
                     })
          .AsHtmlAttributes(new {id ="id or you can use TextBoxFor with typed C#"})
          .ToTextBox())

примечание: проверка идет на клиенте, но ещё можно (на много легче), валидировать на сервер и далее OnError(r=>r.Self().Form.Validation.Refresh()), который интегрирован с ModelState (в статье есть пример)

ещё примечание: если у Вас часто идет проверка по Ajax, то можно обернуть в Html.ProjName().Control.Unique(r=>r.Email)

Валидатора для предыдущего примера

 public class Validator : AbstractValidator<TCommand>
{
   public Validator()
   {
     var dispatcher = IoCFactory.Instance.TryResolve<IDispatcher>();
     RuleFor(r => r.Email) .Must((email) => dispatcher.Query(new IsEmailUniqueQuery() { Email = email }));
    }
 }

примечание: мы повторно используем код

Сценарий зависимых элементов

@model FirstAndLastName
@Html.CheckBoxFor(r => r.SomethingElse)
@Html.For(r => r.First).TextBox(control =>
                                {
        control.OnChange = dsl => dsl.With(Html.Selector().Name(r => r.Last))
                                     .JQuery.Attr.AddClass("hide")
                                     .If(() => Selector.Jquery.Self() == "Remove hide from Last" &&
                                               Html.Selector().Name(r => r.SomethingElse));
                                })
@Html.For(r => r.Last).TextBox()


IML позволяет строить сложные условия или к примеру, установить значения одного элемента из другово (и не только html объекта)

dsl.With(someSelector).Jquery.Attr.Val(Selector.Incoding.QueryString("test"))


P.S. Можно оценить возможности IML на примере todo mvc, а так же есть статьи о template, selector и т.д. Раньше была «песочница», но после редизайна сайта, не было времени её востановить.
Cценарий проверки email на уникальность по Ajax

Это ужасно. Нет, это серьезно ужасно.

Во-первых, это уродливо. Ваш DSL очень плохо читается. Нет, правда: Html.When().AjaxGet().OnSuccess().AsHtmlAttributes().ToTextBox(). Событие и цель события разнесены в разные концы, смысл двух последних действий из названия не понятен.

Во-вторых, это семантически неверно. В вашем примере не валидация, а произвольный код, где-то ссылающийся на JQuery. Ничто, кроме классов, не указывает на то, что это валидация, нет очевидной связи с общей отправкой формы. И это несмотря на то, что есть JQuery Validation, который все это умееет.

Ну и в-третьих, это неверный уровень абстрации. Вот как это должно выглядеть на самом деле:

class SomeModel
{
  [ValidationQuery(typeof(IsEmailUniqueQuery)]
  public string Email {get; set;}
}


Ну или ad-hoc:

Html.TextBoxFor(m => m.Email).Validate(v => v.WithQuery<IsEmailUniqueQuery>())


Сценарий зависимых элементов

Тут все лучше, но нет никакой возможности оптимизировать получившийся JS-код… впрочем, как мы выясняли, у вас это некому делать.

(повторяться про то, что сервис-локатор — зло, я не буду)
Ну и в-третьих, это неверный уровень абстрации. Вот как это должно выглядеть на самом деле:

То, что Вы привели это будет работать в первую очередь на сервер, на клиент надо дописывать Jquery validation и т.д.

Ну или ad-hoc:

Если Вы читали, то увидели, что я привел такой пример «Html.ProjName().Control.Unique(r=>r.Email)»

нет очевидной связи с общей отправкой формы

Проверка email идет сразу после ввода, если Вам нужно после в моменты отправки form, то в incoding framework можно написать validator и в обработчике Submit добавить OnError в котором вызывать Form.Validation.Refresh().

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

Тут все лучше, но нет никакой возможности оптимизировать получившийся JS-код

Это примерно, как Nhibernate (или другой ORM), там все уже оптимизировали и своего добавить нельзя, но зато можно не писать SQL

впрочем, как мы выясняли, у вас это некому делать.

Все же грубите ?)
То, что Вы привели это будет работать в первую очередь на сервер, на клиент надо дописывать Jquery validation и т.д.

Нет, это будет работать там, куда вы это напишете. MVC, например, умеет генерить клиентскую валидацию из атрибутов.

Если Вы читали, то увидели, что я привел такой пример «Html.ProjName().Control.Unique(r=>r.Email)»

Это поддерживается фреймворком или написанный программистом хелпер? Ну и он все равно семантически неверен.

Проверка email идет сразу после ввода, если Вам нужно после в моменты отправки form, то в incoding framework можно написать validator и в обработчике Submit добавить OnError в котором вызывать Form.Validation.Refresh().

… а все это должно работать само и целиком. Как, собственно, в MVC и работает.

Это примерно, как Nhibernate (или другой ORM), там все уже оптимизировали и своего добавить нельзя, но зато можно не писать SQL

Про точки расширения в ORM вы не слышали? И да, ORM — это потеря производительности и контроля, и есть проекты, где их ровно поэтому не применяют.

Но главное — все-таки под ORM уже лежит декларативная парадигма, а вы пытаетесь заменить императивный язык неким метаскриптом. Пропасть глубже.

Все же грубите ?)

Нет, аргументирую для себя принятые вами решения.
Нет, это будет работать там, куда вы это напишете. MVC, например, умеет генерить клиентскую валидацию из атрибутов.

Понятно дело, что fluent validation прекрасно транслирует NotEmpty,NotNull, но к примеру Must уже не получится, а вызов Ajax это тот самый случай.

Это поддерживается фреймворком или написанный программистом хелпер? Ну и он все равно семантически неверен.

В framework по мимо IML, есть и набор готовых решений на нем, но для каждого проекта присущи свои особенности.Задача была написать, как язык для решения любых сценариев, так и готовые компоненты.

… а все это должно работать само и целиком. Как, собственно, в MVC и работает.

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

Нет, аргументирую для себя принятые вами решения.

Ваш профиль говорит, о том что кроме как «аргументирую для себя принятые кем то решения» не делаете ничего. Да, осуждать можно и не показав свои примеры работ, но Вы это делаете постоянно и я думаю было бы справедливо предоставить плоды Вашей деятельности?
Понятно дело, что fluent validation прекрасно транслирует NotEmpty,NotNull, но к примеру Must уже не получится, а вызов Ajax это тот самый случай.

Что вам мешает самим-то (внутри фреймворка) реализовать аналогичное? Это же тривиальный анализ мета-данных и эмит кода в представление.

В framework по мимо IML, есть и набор готовых решений на нем, но для каждого проекта присущи свои особенности.Задача была написать, как язык для решения любых сценариев, так и готовые компоненты.

Ну то есть программистом. Что, знаете ли, удивительно, учитывая, как много вы говорите о своем фреймворке с точки зрения «уменьшает количество кода». Валидация — один из первых пунктов интереса в таком фреймворке (и именно она съедает ощутимую долю усилий).

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

Хороший валидационный фреймворк делает и то, и другое, и без дополнительных усилий со стороны пользователя.

Ваш профиль говорит, о том что кроме как «аргументирую для себя принятые кем то решения» не делаете ничего.

Странно, я думал, что в нем есть ссылка на мой фейсбук, в котором есть все, что надо знать о моей работе (к сожалению, по непонятным причинам хабр не делает ссылок на LinkedIn или, что веселее, StackOverflow, но они тоже легко находятся).

я думаю было бы справедливо предоставить плоды Вашей деятельности?

Нет, спасибо, на «сперва добейся» я не ведусь — особенно учитывая, что моя деятельность в конкретной обсуждаемой области была для конкретного работодателя, и, как следствие, код я вам показать не смогу.
Что вам мешает самим-то (внутри фреймворка) реализовать аналогичное? Это же тривиальный анализ мета-данных и эмит кода в представление.

Как Вы можете рассуждать, что надо реализовать, если Вы даже не использовали?

Ну то есть программистом. Что, знаете ли, удивительно, учитывая, как много вы говорите о своем фреймворке с точки зрения «уменьшает количество кода». Валидация — один из первых пунктов интереса в таком фреймворке (и именно она съедает ощутимую долю усилий).

Вы не хотите ничего читать, в статье (и много другого материала об этом) есть описание, как работает валидация
 .OnError(dsl => dsl.Self().Core().Form.Validation.Refresh())


Нет, спасибо, на «сперва добейся» я не ведусь — особенно учитывая, что моя деятельность в конкретной обсуждаемой области была для конкретного работодателя, и, как следствие, код я вам показать не смогу.

Вы очень долго уже критикуете меня, так что я считаю было бы справедливо показать, как надо? На счет «не могу показать кода», то есть для себя Вы не пишите ни каких инструментов, которые используете от проекта в проекту?

P.S. До сих пор не понятен Ваш интерес, потому что сам framework Вам не нужен (мы говорили о нем год назад, но я так понимаю Вы его даже не устанавливали). Спорить с Вами очень трудно и я думаю доказать, что то не возможно, но тот факт, что статья продвигает из-за кол-во комментариев меня побуждает продолжать дискуссию )
Как Вы можете рассуждать, что надо реализовать, если Вы даже не использовали?

Легко — я посмотрел на приведенный вами код. Да, я могу ошибаться в том, насколько это сложно сделать внутри вашего конкретного кода, но я знаю, что это несложно сделать в ванильном asp.net MVC.

Вы не хотите ничего читать, в статье (и много другого материала об этом) есть описание, как работает валидация

Во-первых, лишний вызов (валидация должна работать прозрачно). Во-вторых, это клиентская валидация или серверная?

то есть для себя Вы не пишите ни каких инструментов, которые используете от проекта в проекту?

Обычно я их пишу для проектов работодателя, и там же они и остаются. То, что нужно мне самому, чаще всего уже есть в том или ином открытом проекте, куда я при случае контрибьючу. BTW, пример такой контрибуции тоже легко находим через мой профиль, который вы, по вашим словам, посмотрели.
Во-первых, лишний вызов (валидация должна работать прозрачно). Во-вторых, это клиентская валидация или серверная?

Если клиентская транслируется (к примеру Fluent validation), то будет на клиенте (и сервер), иначе отправляем (через ajax) сервер и в случаи не удачи (не критической http 500, а логической) то вернем IncodingResult.Error(ModelState), который в OnError обрабатываем, как угодно.
К примеру, можем кастомно сделать dsl.WithId(«someId»).Insert.WithTemplateByUrl(«path to tempate for model state»).Html() или же dsl.WithTag(Form).Form.Validation.Refresh(), что приведет к обновлению валидационных сообщений.

BTW, пример такой контрибуции тоже легко находим через мой профиль, который вы, по вашим словам, посмотрели.

Я не увидел ссылок в Вашем профиле, так что если хотите, то укажите тут.
Что бы показать уровень интеграции, создал на github пример.

Вкратце, можно выделить 3 типа валидации:

  • Клиентская и Серверная — RuleFor(r=>r.NotEmpty).NotEmpty() может выполнятся на клиенте (jquery validate
    примечание: можно дописать свой вариант трансляции в рамках fluent validation, в том числе Ваш ValidationQuery(typeof(IsEmailUniqueQuery))
  • Серверная — Must или When, которые не могут быть выполнены на клиенте, то выполняются на сервере а потом в качестве ModelState возвращаются на форму (с точки зрения пользователя разница не существенная)
  • Серверная в рамках Command — Бывают ситуации, когда остановить выполнение нужно в середине процесса, то в этом случаи Incoding Framework позволяет «выбрасывать» специальный exception, который будет работать так же как и Must (fluent validation)


Примеры

Command
public class TestCommand : CommandBase
{
  public string NotEmpty { get; set; }
  
  public string Must { get; set; }
  
  public string ThrowFromCommand { get; set; }
  
  public override void Execute()
  {
      throw IncWebException.For<TestCommand>(command => command.ThrowFromCommand, "Error");
  }

  public class Validator : AbstractValidator<TestCommand>
  {
      public Validator()
      {
          RuleFor(r => r.NotEmpty).NotEmpty();
          RuleFor(r => r.Must).Must(s => s != "Test").WithMessage("Value it is 'Test'");
      }
  }
}


View
@using (Html.BeginPush(setting => { setting.OnSuccess = dsl => dsl.Utilities.Window.Alert("Success"); }))
{            
// work on client (also checking on server) because can translated by Fluent Validation
@Html.ForGroup(r => r.NotEmpty).TextBox(control => { control.Label.Name = "Not Empty"; })

// work ONLY server side
@Html.ForGroup(r => r.Must).TextBox(control => { control.Label.Name = "Value"; })

// work ONLY server side
@Html.ForGroup(r => r.ThrowFromCommand).TextBox(control => { control.Label.Name = "Error"; })

<input type="submit" value="Submit"/>
}


Html extensions
public static class HtmlExtensions
{
  public static IDisposable BeginPush<T>(this HtmlHelper<T> htmlHelper, Action<Setting> action)
  {
    var setting = new Setting();
    action(setting);
  
    var url = new UrlHelper(htmlHelper.ViewContext.RequestContext);
    return htmlHelper.When(JqueryBind.Submit)
                     .PreventDefault()
                     .Submit()
                     .OnBegin(dsl => dsl.Self().Core().Form.Validation.Parse())
                     .OnSuccess(dsl =>
                                {
                                    if (setting.OnSuccess != null)
                                        setting.OnSuccess(dsl);
                                })
                     .OnError(dsl => dsl.Self().Core().Form.Validation.Refresh())
                     .AsHtmlAttributes()
                     .ToBeginForm(htmlHelper, url.Dispatcher().Push(new TestCommand()));
  }
  
  public class Setting
  {
      public Action<IIncodingMetaLanguageCallbackBodyDsl> OnSuccess { get; set; }
  }
}
TypeScript не имеет интеграции с template

а вот и имеет. называется tsx :)
а вот и имеет. называется tsx :)

TypeScripts new support for JSX — это просто библиотека, которую теперь можно использовать в TypeScript, с тем же успехом можно и handlebars или mustaches, но я говорил о более тесной интеграции ( пример с github)

dsl.Self().WithTemplateUrl(Url.Dispatcher().AsView("path")).Html()

То есть, template это часть инфраструктуры framework.

Получилось то может и неплохо, просто обычно все фреймворки пишут для своих нужд и когда человек будет пытаться адаптировать все это под свои (не в HelloWord), то возникнут проблемы, иногда не решаемые и тогда начнется…
и когда человек будет пытаться адаптировать все это под свои (не в HelloWord), то возникнут проблемы, иногда не решаемые и тогда начнется…

Да, Вы правы такое бывает, но framework разрабатывался (и до сих пор развивается) для разных проектов, потому что наша компания занимается outsource, а это приводит к постоянной смене направления (от досок объявлений до медицинских порталов). По этому я могу с уверенностью сказать, что гибкость достигается за счет IoC (замена IRepository, IUnitOfWork и т.д.), а так же на клиенте Вы можете выбрать Template Engine или взаимодействовать со сторонним JS кодом ( jquery plugin и т.д.).

Если, не сложно то назовите несколько ситуаций, когда Вы упирались в ограничения какого-либо framework. Я спрашиваю, что бы постараться привести наш пример решения, то или иной задачи в рамках incoding framework

P.S. Я не утверждаю, что у нас все продуманно и идеально (такое наверно не бывает), но и framework для «одной задачи» мы не делали.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации