сделать HTTPPOST MVC2 - PullRequest
       17

сделать HTTPPOST MVC2

0 голосов
/ 06 апреля 2011

У меня есть MVC2-приложение.в этом приложении у меня есть строгое представление, конкурирующее с моделью NewHorseModel:

public class NewHorseModel
{
    public List<Category> Faehigkeit { get; set; }
}

public class Choice
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Beschreibung { get; set; }
    public bool Selected { get; set; }
}

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Beschreibung { get; set; }
    public List<Category> Subcategories { get; set; }
    public List<Choice> Choices { get; set; }
    public int Parent { get; set; }
}

Представление выглядит так:

<p>
    <input faehigkeit_ID="1" id="Selected" name="Selected" type="checkbox" value="true" />
    <input name="Selected" type="hidden" value="false" />
    Mitteltrab
    <input id="Id" name="Id" type="hidden" value="1" />
</p>
<p>
    <input faehigkeit_ID="2" id="Selected" name="Selected" type="checkbox" value="true" />
    <input name="Selected" type="hidden" value="false" />
    Arbeitstrab
    <input id="Id" name="Id" type="hidden" value="2" />
</p>
<p>
    <input faehigkeit_ID="3" id="Selected" name="Selected" type="checkbox" value="true" />
    <input name="Selected" type="hidden" value="false" />
    Trab versammelt
    <input id="Id" name="Id" type="hidden" value="3" />
</p>
<p>
    <input faehigkeit_ID="11" id="Selected" name="Selected" type="checkbox" value="true" />
    <input name="Selected" type="hidden" value="false" />
    Trab
    <input id="Id" name="Id" type="hidden" value="11" />
</p>

Представление создается как в этом сообщении: Категориии подкатегории MVC2

Теперь я хочу сделать сообщение, но как получить данные?Когда я делаю пост, подобный этому:

[HttpPost]
public void myAction(NewHorseModel newHorseModel)
{
    // ...
}

Faehigkeit в NewHorseModel равен нулю

Здесь мой ASPX-код:

<div id="Div2">
    <%
    foreach (Category item2 in Model.Faehigkeit)
    {
        Html.RenderPartial("Faehigkeit", item2);
    }
    %>
</div>

Частичное представление категории (строго типизированная модельКатегория):

<%
if (Model.Choices != null)
{
    foreach (var item in Model.Choices)
    { 
        Html.RenderPartial("Choice", item);
    }
}
if (Model.Subcategories != null)
{
    foreach (var item in Model.Subcategories)
    {
        Html.RenderPartial("Faehigkeit", item);
    }
}
%>

И варианты частичного просмотра (выбор модели со строгим типом)

<p>
    <%: Html.CheckBoxFor(m => m.Selected, new { faehigkeit_ID = Model.Id }) %>
    <%: Model.Name %>
    <%: Html.HiddenFor(u=>u.Id) %>
</p>

Обновление Следующий тест: в частичном Faehigkeit.ascx я добавил этокод:

     <input type="hidden"  name="Faehigkeit[<%=Model.Id%>].Id" value="<%=Model.Id%>" />
<input type="hidden" name="Faehigkeit[<%=Model.Id%>].Name" value="<%: Model.Name%>" />

в частичном Choices.ascx я добавил следующий код:

<input type="checkbox" name="Faehigkeit[0].Choices[<%=Model.Id%>].Selected" />

Мне не нужно знать, какой выбор в этой категории.Мне нужно знать, какой ID выбора проверен, а какой нет.

HTML-вывод выглядит так:

  <input type="hidden"  name="Faehigkeit[1].Id" value="1" />
<input type="hidden" name="Faehigkeit[1].Name" value="Qualit&#228;t der Gangarten" />
<input type="hidden" name="Faehigkeit[1].Choices[4].Id" value="4" />
<input type="checkbox" name="Faehigkeit[1].Choices[4].Selected" />

Мой контроллер выглядит следующим образом: [HttpPost]

public ActionResult CreateNewHorse(NewHorseModel collection)
    {
        if (User.Identity.IsAuthenticated)
        {


            return View();
        }
        else
        {
            return View("Account/LogOn");
        }

    }

Если я попытаюсь получить значение «Faehigkeit» -> «Выбор», каждая вещь равна нулю (имя «Faehigkeit», идентификатор «Faehigkeit», и нет выбора) Изображение, котороепоказывает содержимое NewHorseModel во время отладки: http://i.stack.imgur.com/6yLZW.png

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 06 апреля 2011

Есть 2 сообщения в блоге, которые я написал и решит вашу проблему:

  1. Как опубликовать IList<T> действиям контроллера объясняется здесь ипроведет вас от начала до конца, чтобы вы поняли, как это на самом деле работает и почему.

  2. И поскольку у вас могут быть сложные объекты JSON на стороне клиента, и вы хотели бы, чтобы они былимодель привязана к серверу в вашем методе действия (как в вашем случае), этот пост может быть также интересным прочтением.Он объясняет проблему отправки сложных объектов JSON и предоставляет простой плагин jQuery, который преобразует объекты клиента в форму, которая будет легко привязывать данные к параметрам метода действия строгого типа.

Примечание: Существует также возможность использования JsonValueProviderFactory, как объяснил Фил Хаак, но это решение требует изменений как на стороне клиента, так и на стороне сервера (поскольку вы используете MVC2).

На основе вашего кода

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

Все поля ввода, которые вы хотите связать моделью на сервере, должны иметь правильные имена.Из отображенных имен флажков мы видим, что это совсем не так.

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

<!-- erste fähigkeit -->
<input name="Faehigkeit[0].Id" />
<input name="Faehigkeit[0].Name" />
<input name="Faehigkeit[0].Beschreibung" />
<input name="Faehigkeit[0].Subcategories[0].Id" />
<input name="Faehigkeit[0].Subcategories[0].Name" />
...
<input name="Faehigkeit[0].Choices[0].Id" />
<input name="Faehigkeit[0].Choices[0].Name" />
<input name="Faehigkeit[0].Choices[0].Beschreibung" />
<input name="Faehigkeit[0].Choices[0].Selected" />
...
<input name="Faehigkeit[0].Choices[x].Id" /> <!-- "x" could be any number -->
...
<input name="Faehigkeit[0].Parent" />
<!-- zwite fähigkeit -->
<input name="Faehigkeit[1].Id" />
...
<!-- usw. -->

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

Чрезвычайно важно : я должен указать, что индексы (то есть. Faehigkeit[0])не должны относиться к идентификаторам, а скорее являются индексами элементов массива / списка.Они должны быть последовательными, поэтому они должны всегда начинаться с 0 и должны увеличиваться на 1 до последнего N , следовательно, не должны иметь никаких пробелов .Поверьте мне, я проверял это, когда писал свой блог.В противном случае привязка модели на сервере не удастся.Убедитесь, что вы выполняете это требование!Исходя из вашего отредактированного вопроса, это не так, потому что вместо индексов вы вводите идентификаторы.

Если вы передадите данные в виде JSON клиенту, у вас будет объектна клиенте как:

var data = {
    Faehigkeit: [
        {
            Id: 1,
            Name: "Some name",
            Beschreibung: "Some description",
            Subcategories: [
                { ... },
                { ... },
                ...
            ],
            Choices: [
                { ... },
                { ... },
                ...
            ]
        },
        { ... },
        ...
    ]
};

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

$.ajax({
    type: "POST",
    url: "someController/myAction",
    data: $.toDictionary(data), // this is my jQuery plugin mentioned earlier
    success: function() { ... },
    error: function() { ... }
});

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

Вы можете попробовать с <%= Html.EditorFor(m => m); %> но это может быть не та форма, которую вы хотели бы использовать.В таком случае необходимо будет использовать ручное именование.Или вы также можете написать некоторый пользовательский код.

Один из способов - изменить типы режимов частичного просмотра, например, Tuple<string, Category>.String сообщит ему, что string должно быть привязано к именам ваших полей.

Html.RenderPartial("Faehigkeit", Tuple.New("Faehigkeit[0]", item2));

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

Не приятно, но я полагаю, что это единственный способ сделать это.

0 голосов
/ 06 апреля 2011

Обычно, если вы указываете HttpPost в качестве атрибута вашего действия, оно выглядит примерно так:

[HttpPost]
public void myAction(NewHorseModel newHorseModel)
{;}

Затем укажите тип класса в качестве аргумента. должен автоматически связать его для вас, если вам нужно что-то сумасшедшее, или вы отправляете сообщение с внешней не ASP-страницы на это действие, вы можете просто используйте FormCollection (я думаю) в качестве аргумента, и это прославленный словарь, содержащий все ваши элементы и значения.

...