Sdscompany.ru

Компьютерный журнал
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Using html beginform

Создание HTML-форм

Инфраструктура ASP.NET MVC Framework включает набор встроенных вспомогательных методов, которые помогают управлять созданием HTML-элементов

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

Обратите внимание, что атрибуты name всех элементов установлены в соответствие со свойствами модели, которые эти элементы отображают. Атрибут name применяется стандартным связывателем моделей ASP.NET MVC Framework для выяснения того, какие элементы содержат значения для свойств типа модели, при обработке запроса POST. Если опустить атрибут name, форма не будет корректно функционировать.

Далее создается папка Views/Shared, в которую добавляется файл компоновки по имени Layout.cshtml с содержимым, показанным в примере ниже:

Это простая компоновка с несколькими стилями CSS, предназначенными для элементов формы. Запустив приложение и перейдя на URL вида /Home/CreateUser, можно наблюдать базовую функциональность формы:

Из-за того, что данные формы никак не используются в приложении, щелчок на кнопке «Отправить» приводит к повторному отображению этих данных. Ниже приведена HTML-разметка, которую пример приложения MVC отправляет браузеру — мы будем использовать ее для демонстрации изменений, вызванных вспомогательными методами:

Применение вспомогательных методов для генерации HTML-элементов вроде :

Обратите внимание, что вызовы этих вспомогательных методов должны трактоваться как операторы C#. Причина в том, что указанные вспомогательные методы записывают свои дескрипторы напрямую в вывод. Хотя проектное решение выглядит довольно неуклюжим, это не имеет особого значения, поскольку вспомогательные методы BeginForm() и EndForm() редко применяются подобным образом. Намного более распространенный подход, продемонстрированный в примере ниже, предусматривает помещение вызова вспомогательного метода BeginForm() внутрь выражения using. В конце блока using исполняющая среда .NET вызовет метод Dispose() объекта, возвращенного методом BeginForm(), который, в свою очередь, вызовет метод EndForm():

Такой подход называется самозакрывающейся формой и ему следует отдавать предпочтение. Удобно, когда блок кода содержит форму и дает возможность легко понять, какие элементы будут находиться между открывающим и закрывающим дескрипторами .

Остальные 12 вариаций метода BeginForm() позволяют изменять различные аспекты создаваемого элемента . Среди этих перегруженных версий встречается много повторений, т.к. они позволяют последовательно указывать детали формы. В таблице ниже перечислены наиболее важные перегруженные версии, которые регулярно используются в приложениях MVC. Остальные не показанные здесь перегруженные версии метода BeginForm() предназначены для совместимости с версиями инфраструктуры ASP.NET MVC Framework, которые выходили до появления в языке C# поддержки создания динамических объектов.

Создает форму, осуществляющую обратную отправку методу действия, который привел к визуализации представления

Создает форму, которая осуществляет обратную отправку методу действия и контроллеру, указанным в виде строк

Подобна предыдущей перегруженной версии, но позволяет указывать значение для атрибута method, используя перечисление System.Web.Mvc.FormMethod (POST, GET и т.п.)

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

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

Ранее демонстрировалась простейшая версия метода BeginForm(), которой было вполне достаточно для примера приложения, а в примере ниже можно видеть, как используется наиболее сложная версия, позволяющая указывать дополнительную информацию относительно конструирования элемента :

В этом примере явно указывается набор деталей, которые иначе были бы выведены инфраструктурой ASP.NET MVC Framework автоматически, такие как имя действия и контроллер. Мы также указали, что форма должна быть отправлена с применением HTTP-метода POST, который использовался бы в любом случае.

Более интересными аргументами являются те, которые устанавливают значения для переменной маршрута и атрибуты для элемента . Аргументы значений маршрутов применяются для указания значения переменной сегмента id в стандартном маршруте, добавленном Visual Studio в файл /App_Start/RouteConfig.cs при создании проекта. Кроме того, определяются атрибут class и атрибут данных data_formType. (Атрибуты данных — это специальные атрибуты, которые можно добавлять к элементам для выполнения обработки HTML-содержимого.)

Ниже показан HTML-дескриптор , который порождается этим вызовом BeginForm():

Как видите, значение для атрибута id было добавлено к целевому URL, а к элементу были применены атрибут class и атрибут данных. Обратите внимание, что в вызове метода BeginForm() указывался атрибут по имени data_formType, но в выводе он превратился в data-formType. Дело в том, что указывать имена свойств динамического объекта C#, содержащие символы дефиса, не допускается, поэтому использовался символ подчеркивания, который в выводе был автоматически заменен символом дефиса, аккуратно устраняя несоответствие между синтаксисами C# и HTML. (И, разумеется, имя свойства class было снабжено префиксом @, что позволило применить зарезервированное ключевое слово C# в качестве имени свойства для атрибута class.)

Указание маршрута, используемого формой

Когда используется метод BeginForm(), инфраструктура ASP.NET MVC Framework ищет в конфигурации маршрутизации первый маршрут, подходящий для применения при генерации URL, который будет нацелен на требуемое действие и контроллер. В сущности, выбор маршрута оставлен за вами. Если вы хотите обеспечить использование конкретного маршрута, можете применять вместо BeginForm() вспомогательный метод BeginRouteForm(). Чтобы продемонстрировать эту возможность, в файл /App_Start/RouteConfig.cs добавлен новый маршрут, как показано в примере ниже:

Если вызвать метод BeginForm() с такой конфигурацией маршрутизации, получится элемент с атрибутом action, содержащим URL, который создан из стандартного маршрута. В примере ниже видно, как с помощью метода BeginRouteForm() указать на необходимость использования этого нового маршрута:

В результате генерируется следующий дескриптор , атрибут action которого соответствует структуре нового маршрута:

Подобно BeginForm(), метод BeginRouteForm() имеет множество перегруженных версий, которые позволяют указывать разнообразные детали для элемента . Все они следуют той же самой структуре, как их аналоги BeginForm().

I Came, I Learned, I Blogged

«the Quest for knowledge» 🙂

MVC and posting data using Html.BeginForm and Url Routing

We all have pages which represent “fill in” data forms. Quite common is a user’s details form: what’s your first name, what’s your last name, email, date of birth etc. This can be coded in various ways, but I thought that this would be a good way to get to know ASP.NET MVC’s Html.BeginForm( ). While there’s also an Ajax.BeginForm(), I think that the two may differ mainly in the desired behavior after you have completed posting and saving the form data. For example, if you’d like to redirect your user to some other view, or display an entirely new View altogether, you might prefer using Html.BeginForm( ). However, you may want to simply display an informatory “Saved successfully” message, and in that case you’d probably consider using Ajax.BeginForm( ) or simply jQuery’s post.

Читать еще:  View index shtml

The thing is that Routing could make this a little tricky (as it was in my case). If a certain Route led to a Controller and resulted in a View with a “fill in” details form, the generated html Form’s Action attribute is going to be that exact route which you originally used. So how on earth are you supposed to save your data, if the same route was used to originally render your details in the first place? Sounds confusing? I also thought so till I figured it out. Lets clarify this issue with a real world example. Suppose your website allows users to view and edit their personal profile. Your route could be like so:

Note that the controller has a LoadProfile action method (which corresponds to the route action shown earlier), and a SaveProfile action method. In order to have the form data posted to SaveProfile , we need to provide some arguments to Html.BeginForm( ):

Basically, this works. The View renders fine, the submit button posts the data to SaveProfile as expected and everything seems great. But, I’m only missing one thing: I don’t have the original username from which the Form originally rendered. In order words, I have no idea at this time to which user the filled in data relates to. This was available from the Route url when the profile was loaded, but it’s unavailable now, when Html.BeginForm( ) uses custom data for posting. I thought that this would be easy to accomplish, because the Html.BeginForm( ) has overloads which accept routing data, but it turned out that when I provided those, other Routes I have in my application got prioritized and this gets ugly, because it means that I’ll have to provide more routes or route constraints in order for this to work. And this was just one form in my app, and it doesn’t make sense that I’ll have to do this for all the forms I’ll develop.

This led me to a different question altogether: Why should I explicitly supply BeginForm( ) with an action or controller in the first place? How come that in MVC’s templates there aren’t such arguments when calling Html.BeginForm( ), and yet when posting data, the correct action is invoked? I noticed that if I provided no arguments to Html.BeginForm( ), the default action was a “profile/” route, just like what I used for loading the user’s profile. I was puzzled over this, because I didn’t understand how MVC was supposed to differentiate between loading a profile and saving a profile, as the Route used for both operations is identical. I looked up MVC’s template and found an example for ChangePassword. Turns out that there are a couple of ChangePassword( ) overloads. The first overload received no arguments (for “loading” the form), but the second overload received a Model with the data (“saving” the form). So how does the route knows which method should be invoked?

The answer lies in an [HttpPost] attribute which is placed over the “saving” action method. The route is quite clever and the action type (either GET or POST) is used to differentiate between actions of the same name. This makes sense, because usually a GET operation is to be used for loading a form, and a POST operation is usually used to posting and saving a form. I went ahead and tried it: I removed the arguments from Html.BeginForm( ), changed LoadProfile and SaveProfile action methods simply to “ Profile “, added [HttpPost] to the Profile action method which performs the saving operation, and changed the route accordingly. Here’s how this looks:

If we use two action methods by the same name without [HttpPost] on one of them, the run-time throws a “ The current request for action ‘Profile’ on controller type ‘AccountController’ is ambiguous between the following action methods ” exception.

Now I could use the RouteData collection for retrieving the user name, as well as other form fields which were sent over as arguments.

Why we need to use @using with Html.BeginForm

Can someone explain to me why we need to use

What is the main purpose of @using in here, as far as I know, I only use ‘using’ keyword to make sure that the object is disposed as soon as it goes out of scope. I am a little confused.

Edit: This is my code that renders the «System.Web.Mvc.Html.MvcForm . «

that is to generate corresponding closing tag (in this case the closing ‘ tag. – mstaessen 20 янв. 17 2017-01-20 10:03:46

Why without using the ‘using’ keyword the output is «System.Web.Mvc.Html.MvcForm < . " ? and we also have the closing tag ? – Mehdi Souregi 20 янв. 17 2017-01-20 10:21:23

Nope, it is different, I don’t want the solution, I know that using keyword is working fine, i just want to know what goes behind the scene – Mehdi Souregi 20 янв. 17 2017-01-20 10:43:56

3 ответа

by using @using (Html.BeginForm(«CheckUser», «Home», FormMethod.Post))

It automatically adds in your page. you don’t need to care about closing your form tag and it prevents accidental issue if somebody forgets to close the form.

If you want to use Html.EndForm(), use it like following

Reason: Html.EndForm() doesn’t returns anything( return type void ), it write on the stream in stead. If you don’t use <> , @ symbol will expect something to return from the following statement hence it will use object.ToString() which results into System.Web.Mvc.Html.MvcForm

Создан 20 янв. 17 2017-01-20 10:04:36 K D

Читать еще:  Html input hide

I used the @Html.EndForm but it still renders «System.Web.Mvc.Html.MvcForm » before rendering the content of the form. – Mehdi Souregi 20 янв. 17 2017-01-20 10:26:54

use it like this @K D 20 янв. 17 2017-01-20 10:28:34

yes, i used this form actually @, the @Html.EndForm did not work for me 🙂 .But it still renders «System.Web.Mvc.Html.MvcForm » – Mehdi Souregi 20 янв. 17 2017-01-20 10:30:00

your begin form statement should also be like @can you paste your html along with these helpers in your question? – K D 20 янв. 17 2017-01-20 10:33:03

Check the edit of my question – Mehdi Souregi 20 янв. 17 2017-01-20 10:36:35

yeah, you have not added Begin form correctly. check the usage in my answer again and try – K D 20 янв. 17 2017-01-20 10:37:43

Thanks a lot, it is clear for me now 🙂 – Mehdi Souregi 20 янв. 17 2017-01-20 10:41:23

BeginForm has a rather interesting (mis)use of the IDisposible pattern!

Starting at the beginning, BeginForm returns an instance of MvcForm . MvcForm implements IDisposible and its Dispose method.

[. ] renders the closing tag at the end of a Using statement.

Without this sort of implementation you would need to do something along the lines of

Which, I guess, they made the decision would be clunky and easy to forget.

Создан 20 янв. 17 2017-01-20 10:04:28 Jamiec

Thanks for the @, this is first time I hear of about it, But it still renders «System.Web.Mvc.Html.MvcForm < . " – Mehdi Souregi 20 янв. 17 2017-01-20 10:25:23

@Souregi, Both the ‘BeginForm()’ and ‘EndForm()’ need to be wrapped in ‘@< . >‘ because they return ‘void’ (Jamiec, I took the liberty of editing your answer to show the correct syntax — and ‘EndForm()’ does exist 🙂 – Stephen Muecke 20 янв. 17 2017-01-20 10:39:51

Thanks @StephenMuecke – Jamiec 20 янв. 17 2017-01-20 10:40:14

thump up for Stephen Muecke it is clear for me now 🙂 – Mehdi Souregi 20 янв. 17 2017-01-20 10:41:00

Html-помощник ¶

Каждое веб-приложение формирует большое количество HTML-разметки. Если разметка статическая, её можно эффективно сформировать смешиванием PHP и HTML в одном файле, но когда разметка динамическая, становится сложно формировать её без дополнительной помощи. Yii предоставляет такую помощь в виде Html-помощника, который обеспечивает набор статических методов для обработки часто-используемых HTML тэгов, их атрибутов и содержимого.

Note: Если ваша разметка близка к статической, лучше использовать непосредственно HTML. Нет никакой необходимости в том, чтобы всё подряд оборачивать вызовами Html-помощника.

Основы ¶

Так как формирование динамической HTML-разметки при помощи конкатенации строк очень быстро вносит хаос в проект, Yii предоставляет набор методов для управления атрибутами тэгов и формирования тэгов на основе этих атрибутов.

Формирование тэгов ¶

Код формирования тэга выглядит следующим образом:

Здесь первый аргумент — это название тэга. Второй — содержимое, которое будет заключено между открывающим и закрывающим тэгами. Заметьте, что мы используем Html::encode . Это связано с тем, что содержимое не экранируется автоматически, чтобы можно было по-необходимости использовать чистый HTML. Третий аргумент — это массив настроек для HTML-кода, а другими словами — массив атрибутов для тэга. В этом массиве ключи являются названиями атрибутов, например class , href или target , а значения в массиве являются значениями этих атрибутов.

Вышеприведённый код сформирует следующую HTML-разметку:

В тех случаях, когда вам необходимо только закрыть или открыть тэг, можно использовать методы Html::beginTag() и Html::endTag() .

Дополнительные атрибуты используются во многих методах Html-помощника и в различных виджетах. Во всех этих случаях в дело вступают механизмы дополнительной обработки данных, о которых следует знать:

  • Если значение равно null , соответствующий атрибут не будет выведен.
  • Атрибуты, значения которых имеют тип boolean, будут интерпретированы как логические атрибуты.
  • Значения атрибутов будут экранированы с использованием метода Html::encode().

Если в качестве значения атрибута передан массив, он будет обработан следующим образом:

Если атрибут является одним из атрибутов данных, указанных в yiihelpersHtml::$dataAttributes, например data или ng , то будет сформирован список атрибутов по одному для каждого элемента массива. Например, код ‘data’ => [‘id’ => 1, ‘name’ => ‘yii’] сформирует data-id=»1″ data-name=»yii» ; а код ‘data’ => [‘params’ => [‘id’ => 1, ‘name’ => ‘yii’], ‘status’ => ‘ok’] сформирует data-params=’<"id":1,"name":"yii">‘ data-status=»ok» . Заметьте, что в последнем примере используется формат JSON для формирования вывода вложенного массива.

Если атрибут НЕ является атрибутом данных, значение будет сконвертировано в формат JSON. Например, код [‘params’ => [‘id’ => 1, ‘name’ => ‘yii’] сформирует params=’<"id":1,"name":"yii">‘ .

Формирование CSS классов и стилей ¶

При формировании атрибутов для HTML-тэгов часто приходится начинать с некоторых атрибутов по умолчанию, которые затем необходимо изменять. Для того, чтобы добавить или удалить CSS-класс, можно использовать следующий подход:

Можно указать несколько CSS-классов, используя синтаксис массива:

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

Html::addCssClass() предотвращает дублирование классов, поэтому можно не беспокоиться о том, что какой-либо класс будет добавлен дважды:

Если CSS-класс задаётся с помощью массива, можно использовать именованные ключи массива для обозначения логического предназначения класса. В этом случае класс с таким же ключом будет проигнорирован во время использования Html::addCssClass() :

CSS-стили могут быть установлены схожим образом с помощью атрибута style :

При использовании метода addCssStyle() можно указать массив, пары ключ-значение которого соответствуют названиям и значениям CSS-свойств, или строку, например width: 100px; height: 200px; . Эти два формата могут быть преобразованы друг в друга с помощью методов cssStyleFromArray() и cssStyleToArray(). Метод removeCssStyle() принимает на вход массив атрибутов, которые следует удалить. Если удаляется всего один атрибут, его можно передать строкой.

Экранирование контента ¶

Для корректного и безопасного отображения контента специальные символы в HTML-коде должны быть экранированы. В чистом PHP это осуществляется с помощью функций htmlspecialchars и htmlspecialchars_decode. Проблема использования этих функций заключается в том, что приходится указывать кодировку и дополнительные флаги во время каждого вызова. Поскольку флаги всё время одинаковы, а кодировка остаётся одной и той же в пределах приложения, Yii в целях безопасности предоставляет два компактных и простых в использовании метода:

Формы ¶

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

Note: Рассмотрите возможность использования ActiveForm, если работаете с моделями и нуждаетесь в валидации данных.

Создание форм ¶

Открывающий тэг формы может быть выведен с помощью метода beginForm() как показано ниже:

Первый аргумент — это URL-адрес, на который будет отправлена форма. Он может быть задан в виде Yii-маршрута и параметров, подходящих для передачи в метод Url::to(). Второй аргумент — способ отправки данных: по умолчанию это post . Третий аргумент — массив атрибутов формы. В данном примере мы изменяем способ кодирования данных в POST-запросе на multipart/form-data . Это необходимо для загрузки файлов.

Закрыть тэг формы можно простым кодом:

Кнопки ¶

Для формирования кнопок можно использовать следующий код:

Первый аргумент во всех трёх методах — это название кнопки, а второй — её атрибуты. Название кнопки не экранируется, поэтому при получении данных от конечных пользователей экранируйте их с помощью метода Html::encode().

Поля ввода ¶

Методы формирования полей ввода делятся на две группы. Первые начинаются со слова active и называются «active inputs», а вторые не содержат в своём названии слова active . «Active inputs» формируют поля ввода, которые получают данные из указанного атрибута модели, в то время как обычные методы формирования полей ввода непосредственно принимают данные.

Наиболее общие методы для формирования полей ввода:

Если вам заранее известен тип поля ввода, удобнее будет пользоваться этими вспомогательными методами:

Сигнатура методов для формирования радио-переключателей и чекбоксов немного отличается:

Выпадающие и обычные списки могут быть сформированы следующим образом:

Первый аргумент — это значение атрибута name для поля ввода, второй — выбранное в нём значение и, наконец, третий аргумент — это массив, ключами которого является список значений для формирования списка, а значениями массива являются названия пунктов в нём.

Если вы хотите сделать в списке доступными для выбора несколько вариантов, хорошим выбором будет список чекбоксов:

Если же нет, используйте радио-переключатель:

Тэги label и отображение ошибок ¶

Также как и для полей ввода, есть два метода формирования тэгов label для форм. Есть «active label», считывающий данные из модели и обычный тэг «label», принимающий на вход непосредственно сами данные:

Для отображения общего списка ошибок формы на основе модели или моделей можно использовать следующий подход:

Для отображения одной отдельной ошибки:

Атрибуты name и value для полей ввода ¶

Также имеются методы для получения значений атрибутов id, name и value для полей ввода, сформированных на основе моделей. Эти методы используются в основном внутренними механизмами, но иногда могут оказаться подходящими и для прямого использования:

В вышеприведённом коде первый аргумент — это модель, а второй аргумент — выражение для поиска атрибута модели. В самом простом случае оно представляет собой название атрибута модели, а вообще это может быть название, которому предшествует (и/или после которого следует) индекс массива. Такой формат используется в основном для табличного ввода данных:

  • [0]content используется для табличного ввода данных, чтобы указать на атрибут «content» первой модели табличного ввода;
  • dates[0] указывает на первый элемент массива, с помощью которого задан атрибут модели «dates»;
  • [0]dates[0] указывает на первый элемент массива, с помощью которого задан атрибут «dates» первой модели табличного ввода.

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

Подключение встроенных стилей и скриптов ¶

Для формирования встроенных скриптов и стилей есть два метода:

Если вы хотите подключить внешний CSS-файл:

Первый аргумент — URL-адрес. Второй — массив настроек. Помимо обычных настроек можно указать следующие:

  • condition для оборачивания тэга
  • с помощью условных комментариев с определённым условием. Надеемся, что вам никогда не понадобятся условные комментарии 😉
  • noscript может быть установлен в значение true , чтобы обернуть тэг
  • с помощью тэга

Использование хелпера EditorFor и шаблонов для полей редактирования в ASP.NET MVC

| Суббота, 18 января, 2014

В предыдущей статье про DisplayFor было показано как можно использовать UIHint атрибут для использования собственного шаблона, который генерирует специфичное поле отображения данных на HTML странице. Важным элементом той конструкции является строготипизированный html хелпер DisplayFor, который появился в ASP.NET MVC 2. Аналогично мы можем использовать хелпер EditorFor для полей редактирования в представлении. Для примера мы будем использовать следующую модель:

Добавим метод действия Edit в контроллере HomeController с целью создания представления редактирования для класса Post:

Далее с помощью Visual Studio мы генерируем строготипизированное представление для класса Post:

Введем следующий код для представления:

Если мы запустим приложение по адресу /home/edit, то увидим такую страницу:

Итак, представление для редактирования сгенерировано в помощью текстовых полей. Но мы можем переопределить некоторые с помощью шаблонов редактирования. В частности, переделаем поле «Оценка». Вместо того, чтобы заставлять пользователя печатать значение этого поля, мы переделаем это поле в выпадающий список с заранее заданными значениями для выбора.

Для начала переделаем представление, чтобы оно могло использовать шаблон. Изменим поле для оценки следующим образом:

То есть, мы используем хелпер EditorFor для генерации поля. Если мы запустим приложение, то представление и поле оценки будет выглядеть как и прежде.

Теперь создадим шаблон для поля оценки, сначала добавим подпапку EditorTemplates в папке Views:

Внутри этой папки создадим частичное представление и назовем его RatingsDropDown. Это новое представление будет содержать следующий код:

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

Используя Data Annotations укажем модели Post, что поле Rating должно генерироваться с помощью шаблона RatingsDropDown:

Теперь, если мы запустим наше приложение и откроем страницу редактирования, то увидим выпадающий список:

Итак хелпер EditorFor реализован с помощью шаблона RatingsDropDown, который привязан с помощью Data Annotation к полю модели. Это позволяет нам настраивать произвольный и удобный вид полей. И если нужно отобразить то же самое поле в другом представлении, мы получим такой же вид автоматически. Довольно удобная штука!

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector