Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: ASP.NET MVC
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
kolol
0 / 0 / 0
Регистрация: 17.09.2016
Сообщений: 6
1

Большое количество входных параметров от динамических форм. Что я делаю не так?

17.09.2016, 15:02. Просмотров 888. Ответов 7
Метки нет (Все метки)

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

1. Форма должна быть одна, она генерирует сложный запрос к БД и отдает некие данные. Чтобы как-то разделить эту одну форму на составные части (в дальнейшем подформы) я отдаю по клику на определенную кнопку - определенную подформу, в то время как другие "скрываю" (<div hidden>).
2. Каждых подформ может быть сколько угодно. То есть к примеру подформа "дети", пользователь нажимает на кнопку и появляется подформа позволяющая добавить информацию о новом ребенке.
3. Я создаю подформы следующим образом. По клику на кнопку я отправляю на сервер ajax запрос и генерирую PartialView, который вставляю после существующего блока, не удаляя предыдущий. Следующего содержания:

HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
@model bb.Models.MetaViewModel
<div class="panel-body form-inline">
    <div class="form-group">
        <lavel><strong>Имя</strong></lavel>
        @Html.TextBox(string.Concat("name1[" + Session["nameBlockIdNumber"] + "]"),
            null, new { @class = "form-control" })       
    </div>
    <div class="form-group">
        <lavel><strong>Фамилия</strong></lavel>
        @Html.TextBox(string.Concat("name2[" + Session["nameBlockIdNumber"] + "]"),
            null, new { @class = "form-control" })
    </div>
</div>
4. Вот тут появляется первая проблема. Чтобы в последствии получить массив строк вида string name1[] и string name2[], мне приходится генерировать nameBlockIdNumber, чтобы id каждого блока формы были одинаковы и получалось что-то типо <div id="name1[nameBlockIdNumber]">
Мне это уже не нравится. Хотелось бы, чтобы каждая подформа создавала ОБЪЕКТ, а лист этих объектов уже отправляла на сервер по POST. Отсюда первый вопрос. Как сделать так, чтобы динамическая форма отправляла лист объектов? Я знаю, что есть хелперы вида @Html.TexBoxFor, но я ума не приложу как это реализовать для динамических а не статических форм...

5. Следующая проблема в том, что принимая массивы в Action обрабатывающий форму, я получаю что-то типо этого:

C#
1
2
3
4
5
6
7
8
9
10
        [HttpPost] 
        public RedirectResult QueryBuilder(
            string[] name1, string[] name2, //те самые name1 и name2 из PartialView
            string[] param3, string[] param4, string[] param5,
            string[] param6, string[] param7,
            string[] param8, string[] param9,
            string[] param10, string[] param11,
            string[] param12, string[] param13,
            string[] param14, string[] param15
            )
Это просто ужас, ведь мне придется добавить еще много полей в форму. И сколько этих параметров будет 30? А может 50? С этим еще можно мирится, но что-то мне подсказывает, что и у этой проблемы есть какое-то решение, чтобы не нагромождать код.

Спасибо всем, кто дочитал до конца. Очень надеюсь на вашу помощь.

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

0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.09.2016, 15:02
Ответы с готовыми решениями:

Что делаю не так...?
Set cn = Server.CreateObject('ADODB.Connection') cn.ConnectionString = dsn...

Обновление частичного представления! Что я делаю не так?
Хочу с помощью библиотеки jquery сделать частичное обновление страницы без...

Возвратить данные из функции, которая имеет заранее неизвестное количество входных параметров
есть некая функция, например: public void func(params object arr) { что-то...

Можно ли заменить большое количество форм одной формой, но с вкладками
Можно ли как-то заменить большое количество форм одной формой, но с вкладками....

Как удобнее передавать большое количество параметров?
В продолжение этой темы. Я пишу WCF сервис и у меня очень много функций с...

7
IamRain
1375 / 1230 / 386
Регистрация: 02.08.2011
Сообщений: 3,623
17.09.2016, 16:07 2
Цитата Сообщение от kolol Посмотреть сообщение
Как сделать так, чтобы динамическая форма отправляла лист объектов? Я
Чтобы отправлять список объектов, нужно чтобы все динамически добавляемые элементы имели одно и то же имя.
Binding to a List
Было бы неплохо взглянуть на разметку после добавления, например, двух PartialView динамически.
1
kolol
0 / 0 / 0
Регистрация: 17.09.2016
Сообщений: 6
17.09.2016, 16:51  [ТС] 3
Цитата Сообщение от IamRain Посмотреть сообщение
Чтобы отправлять список объектов, нужно чтобы все динамически добавляемые элементы имели одно и то же имя. Binding to a List
Почитал, кажется что это должно помочь с листами. Попробую так сделать, хотя пока до конца не понятно.

Цитата Сообщение от IamRain Посмотреть сообщение
Было бы неплохо взглянуть на разметку после добавления, например, двух PartialView динамически.
Вот примерно так. Добавлены 2 "подформы" дети, позволяющие ввести имя и фамилию. И 2 подформы "собаки" позволяющие ввести породы и клички.

HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<div id="ChieldBlock"> <div class="panel-body form-inline">
    <div class="form-group">
        <lavel><strong>Имя</strong></lavel>
        <input name="name1[0]" class="form-control" id="name1_0_" type="text" value="">       
    </div>
    <div class="form-group">
        <lavel><strong>Фамилия</strong></lavel>
        <input name="name2[0]" class="form-control" id="name2_0_" type="text" value="">
    </div>
</div>
<div class="panel-body form-inline">
    <div class="form-group">
        <lavel><strong>Имя</strong></lavel>
        <input name="name1[1]" class="form-control" id="name11_1_" type="text" value="">       
    </div>
    <div class="form-group">
        <lavel><strong>Фамилия</strong></lavel>
        <input name="name2[1]" class="form-control" id="name22_1_" type="text" value="">
    </div>
</div>
</div>
 
<div id="DogBlock" hidden> <div class="panel-body form-inline">
    <div class="form-group">
        <lavel><strong>Кличка</strong></lavel>
        <input name="dog1[0]" class="form-control" id="dog11_0_" type="text" value="">       
    </div>
    <div class="form-group">
        <lavel><strong>Порода</strong></lavel>
        <input name="dog2[0]" class="form-control" id="dog22_0_" type="text" value="">
    </div>
</div>
<div class="panel-body form-inline">
    <div class="form-group">
        <lavel><strong>Кличка</strong></lavel>
        <input name="dog1[1]" class="form-control" id="dog11_1_" type="text" value="">       
    </div>
    <div class="form-group">
        <lavel><strong>Порода</strong></lavel>
        <input name="dog2[1]" class="form-control" id="dog22_1_" type="text" value="">
    </div>
</div>
</div>
0
IamRain
1375 / 1230 / 386
Регистрация: 02.08.2011
Сообщений: 3,623
17.09.2016, 17:12 4
Цитата Сообщение от kolol Посмотреть сообщение
<input name="dog2[1]" class="form-control" id="dog22_1_" type="text" value="">
и
Цитата Сообщение от kolol Посмотреть сообщение
<input name="dog1[1]" class="form-control" id="dog11_1_" type="text" value="">
Имена разные, даже в пределах одного блока. Вы и сами уже поняли.
1
kolol
0 / 0 / 0
Регистрация: 17.09.2016
Сообщений: 6
18.09.2016, 17:12  [ТС] 5
Цитата Сообщение от IamRain Посмотреть сообщение
Имена разные, даже в пределах одного блока. Вы и сами уже поняли.
Нет не понял. С же специально сделал их разными... Да и в присланной вами ссылке сказано

To bind complex objects, we need to provide an index for each item, rather than relying on the order of items. This ensures we can unambiguously match up the submitted properties with the correct object.
Я попробовал реализовать то, что описано там, кстати. И столкнулся с проблемой. По аналогией переписал на Razor, создав простенький проект.
1. Модель
C#
1
2
3
4
5
public class MyDogModel
{
   public string Name { get; set; }
   public string Breed { get; set; }
}
2. Контроллер
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class HomeController : Controller
{
    public ActionResult Index()
    {
        Session.Clear();
        return View();
    }
    [HttpPost]
    public ViewResult MyDogs (List<MyDogModel> myDogs) 
    {
        return View(myDogs);
    }
    [HttpPost]
    public PartialViewResult AddDog(List<MyDogModel> dogs)
    {
        int fieldsCount;
        if (Session["FieldsCount"] == null)
        {
            Session["FieldsCount"] = 1;
            fieldsCount = 1;
        }
        else
        {
            fieldsCount = (int)Session["FieldsCount"];
            Session["FieldsCount"] = fieldsCount++;
        }
        return PartialView(dogs);
    }
}
3. PartialView отвечающая за добавление новых полей. Где я получаю в этой строчке @Html.TextBoxFor(d => d[i].Breed); ошибку Exception thrown: 'System.NullReferenceException' in System.Web.Mvc.dll
C#
1
2
3
4
5
6
7
8
9
10
    @model List<WebApplication2.Models.MyDogModel>
    @using (@Html.BeginForm("MyDogs","Home"))
    {
        for (int i = 0; i < (int)Session["FieldsCount"]; i++)
        {
            @Html.TextBoxFor(d => d[i].Name);
            @Html.TextBoxFor(d => d[i].Breed);
        }
        <button type="submit">Send</button>
    }
4. Index
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    @{
        AjaxOptions options = new AjaxOptions
        {
            HttpMethod = "post",
            UpdateTargetId = "MyDogsForm",
            InsertionMode = InsertionMode.Replace
        };
        Layout = null;
    }    
    <!DOCTYPE html>    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
        <script src="~/Scripts/jquery-1.8.0.js"></script>
        <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
    </head>
    <body>
        <div> 
            @Ajax.ActionLink("Add new dog", "AddDog", options)
            <div if="MyDogsForm">
            </div>
        </div>
    </body>
    </html>

Подскажите, что я делаю не так? Мне бы очень хотелось, получать формы прямо с сервера, а не добавлять новые поля с помощью JQuery. С точки зрения дальнейшей логики работы это было бы гораздо удобней.
0
IamRain
1375 / 1230 / 386
Регистрация: 02.08.2011
Сообщений: 3,623
19.09.2016, 15:15 6
Лучший ответ Сообщение было отмечено kolol как решение

Решение

Цитата Сообщение от kolol Посмотреть сообщение
Подскажите, что я делаю не так?
=>
Цитата Сообщение от kolol Посмотреть сообщение
3. PartialView отвечающая за добавление новых полей.
Вы делаете неправильное сопоставление моделей и вьюх. Так, у вас модель для добавления собаки почему то является коллекцией собак.
Я бы делал по другому.
У вас должно быть два метода:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[HttpGet]
    public PartialViewResult AddDog()
    {
       return PartialView(new MyDogModel());
    }
 
[HttpPost]
    public JsonResult AddDog(MyDogModel dog)
    {
           if (!ModelState.Valid) return Json(new { Succeeded = false});          
 
       try 
        {
               // добавляем в базу
               // возвращаем результат операции 
              return Json(new {Succeeded = true, Data = dog, Message = "Some message"});
         }
       catch (Exception exc) 
            {
                    return Json(new {Succeeded = false, Data = dog, Message =  exc.ToString()});
            }
    }
И на клиенте вы просто js-ом инициируете ajax: (либо встроенными хелперами)
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 $("#addButtonId").onclick = function(e) {
       var e = e || window.event;   
       e.preventDefault();
      $.ajax({..}).done(function(data){
      if (data.Succeeded)
      {
          // добавляем в интерфейс через js и выводим сообщение мол все успешно добавлено
      }
       else {
      
       // отображаем stacktrace из data.Message, либо 
 }
 
}).fail(function(){
 //  show some message
});                 
 }
Вот когда это будет работать, тогда уже можно начинать разбираться с отправкой коллекции на сервер. И по-моему, вообще не обязательно отправлять всю коллекцию - в БД то сохраняется.
1
kolol
0 / 0 / 0
Регистрация: 17.09.2016
Сообщений: 6
19.09.2016, 18:01  [ТС] 7
Цитата Сообщение от IamRain Посмотреть сообщение
Так, у вас модель для добавления собаки почему то является коллекцией собак.
Спасибо, вот это действительно верно. Похоже я не правильно понимал концепцию моделей.

Я кажется разобрался. Правда мне не нужно сохранять запрос в бд, но идею я понял.

Жалко, что не получилось разобраться с коллекциями, ведь по сути это был главный вопрос, но я думаю что близок к тому, чтобы самому разобраться. Я выложу код в случае если воспользуюсь другим решением, используя коллекции. Может в будущем пригодится кому-нибудь.
0
IamRain
1375 / 1230 / 386
Регистрация: 02.08.2011
Сообщений: 3,623
19.09.2016, 18:28 8
Цитата Сообщение от kolol Посмотреть сообщение
сути это был главный вопрос,
Делайте так, как описано в статье.
Если не получится, то просто вручную собирайте на клиенте коллекцию объектов и делайте POST-запрос.
1
19.09.2016, 18:28
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.09.2016, 18:28

Что-то не то с Майкрсофт визуал студио 2010 или я что-то не так делаю
Дело в том что при запуске вот этой программы: #include &lt;iostream&gt; using...

Хотелось бы, чтоб по нажатию на кнопку что-то происходило. Но, Увы! Что я делаю не так?
Пытаюсь начать осваивать jQuery. Создал вот такой текст. (убрал лишнее)...

Что я делаю не так?
Ребят помогите пожалуйста с базой данных!не устанавливается связь!ключевые поля...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru