Передача нескольких моделей представления в одном представлении

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

Основной вид:

@model Project.Models.ProfileModel

 @(ViewBag.HasLocalPassword ? Html.Partial("_ChangePasswordPartial", Model.PasswordModel) : Html.Partial("_SetPasswordPartial", Model.PasswordModel))

            @Html.Partial("_UsernamePartial", Model.UsernameModel)
            @Html.Partial("_PlayNamePartial", Model.PlayNameModel)

Модели:

 public class ProfileModel
{
    public PasswordModel PasswordModel { get; set; }
    public PlayNameModel PlayNameModel { get; set; }
    public UsernameModel UsernameModel { get; set; }
}

Имя пользователя Действие ПОЛУЧИТЬ:

public ActionResult _UsernamePartial()
    {
        var usernameModel = new UsernameModel();
        using (var db = new DataContext())
        {
            usernameModel.Username =
                (from u in db.Users where u.ID == WebSecurity.CurrentUserId select u.Username).FirstOrDefault();
        }
        return PartialView(usernameModel);
    }

Имя пользователя POST-действие:

[HttpPost]
    public ActionResult _UsernamePartial(UsernameModel usernameModel)
    {
        if (ModelState.IsValid)
        {
            using (var db = new DataContext())
            {
                User user = db.Users.FirstOrDefault(u => u.ID == WebSecurity.CurrentUserId);
                user.Username = usernameModel.Username;
                db.SaveChanges();
            }
        }
        return View("_UsernamePartial");
    }

Действие профиля:

public ActionResult Profile(ManageMessageId? message)
    {
        var profile = New ProfileModel();
        ViewBag.StatusMessage =
            message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
            : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
            : message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
            : "";
        ViewBag.HasLocalPassword = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
        ViewBag.ReturnUrl = Url.Action("Profile");
        return View(profile);


    }

Просмотр страницы для имени пользователя:

@model Acatar.Models.UsernameModel

@using (Html.BeginForm("_UsernamePartial", "Account")) {

       <p id="legend">Username</p>
       @Html.TextBoxFor(m=>m.Username)

    <button type="submit" value=" Username">Save</button>
}

Сообщение об ошибке: The model item passed into the dictionary is of type 'Project.Models.ProfileModel', but this dictionary requires a model item of type 'Project.Models.UsernameModel'.

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


person BB987    schedule 12.02.2013    source источник
comment
на какой странице просмотра вы действительно видите эту ошибку?   -  person bot    schedule 12.02.2013
comment
@bot на главной странице просмотра - первый раздел кода, который у меня есть. Должен ли я передавать все GETS для трех моделей в один метод GET на странице профиля?   -  person BB987    schedule 12.02.2013
comment
@ BB987, нет, вам не нужно публиковать все сообщения Gets на одной странице. интересно, у вас есть дочерний метод для _UsernamePartial, который никогда не используется. не относится к вашей проблеме, но интересно   -  person Dave Alperovich    schedule 12.02.2013
comment
OIC, @BB987, вы непреднамеренно создали дочерние методы действий. Вы называете свои методы действий после своих частей. Ваше намерение состояло в том, чтобы (по кажущемуся соглашению) отправить им сообщение. Но на самом деле они пытаются вернуть партиалы.   -  person Dave Alperovich    schedule 12.02.2013
comment
@DaveA моя общая проблема заключается в том, что до того, как моя страница загружалась нормально с текстовым полем, я хотел, чтобы они были предварительно заполнены данными, которые были сохранены ранее, а этого не было, потому что она получала нулевую ссылку, поэтому ничего не показывалось. Но он сохранялся правильно после проверки изменений в базе данных.   -  person BB987    schedule 12.02.2013
comment
@DaveA Также в моем URL-адресе, если я перехожу непосредственно на страницу просмотра _UsernamePartial - он отлично работает с загрузкой в ​​​​текстовое поле, но только тогда, когда я хочу иметь несколько представлений, которые будут загружать все данные на тот же экран, который он не показывает.   -  person BB987    schedule 12.02.2013
comment
@ BB987, большой вопрос: вы намеревались, чтобы ваши частичные части заполнялись из моделей, которые вы передали, или из дочерних действий, которые они разделяют. Если вы намеревались использовать дочерние действия, метод Пола Мендосы лучше всего подходит для ваших нужд.   -  person Dave Alperovich    schedule 12.02.2013


Ответы (2)


Если вы вызываете Html.Partial, я не верю, что он вызывает метод действия. Вы должны использовать Html.RenderAction(), который вызовет действие контроллера.

person Paul Mendoza    schedule 12.02.2013
comment
Я не думаю, что @BB987 намеревался использовать свои частичные действия с дочерними действиями. Я могу ошибаться, но я думаю, что его намерение состояло в том, чтобы отображаемые формы публиковались в действиях, названных в честь соответствующих представлений. Это было бы неправильным пониманием соглашения новичком. Я думаю... - person Dave Alperovich; 12.02.2013
comment
Итак, я правильно понял - я буду использовать Html.RenderAction() в профиле (основной вид)? - person BB987; 12.02.2013
comment
Это не решит всех ваших проблем. Вы НЕ должны публиковать свою форму в _UsernamePartial, если она не возвращает usernameModel. Этот метод будет «привязан» к вашему частичному и попытается его отобразить. Но ваш частичный объект ожидает модель типа usernameModel. - person Dave Alperovich; 12.02.2013
comment
@ДэйвА. УХ ТЫ! Я только что прокомментировал свой метод записи и запустил страницу, и теперь она работает как надо. Но если пользователь вносит изменения в username и сохраняет - разве мне все еще не нужен POST для сохранения в базе данных? или это делается по другому - person BB987; 12.02.2013
comment
@ BB987 да, вы должны публиковать сообщения, но в родительских методах Views, никогда не публикуйте сообщения в методе, названном в честь партиала, если только вы не хотите использовать этот метод для вызова партиала. прочитайте ссылку, которую я включил под своим ответом. это объясняет ассоциацию, которую вы случайно установили между вашими действиями и частями. и это говорит о том, что Павел говорил вам. - person Dave Alperovich; 12.02.2013
comment
@DaveA Большое спасибо, вы очень помогли, и я прочитаю ссылку и исправлю название моего поста, и, надеюсь, сегодня вечером у меня больше не возникнет проблем. - person BB987; 12.02.2013
comment
Если вы действительно хотите реализовать что-то вроде того, что предлагает Пол Мендоса, вы можете сделать это таким образом. @{Html.RenderAction(_UsernamePartial, ControllerName); }. Добавьте это в свой основной вид. - person bot; 12.02.2013
comment
@bot да, это сработало, но поскольку рядом с текстовым полем имени пользователя есть кнопка «Сохранить» - как это вызовет публикацию, потому что то, что у вас есть, отлично подходит для отображения результатов GET - person BB987; 12.02.2013

Когда вы публикуете в _UsernamePartial, это действует как дочерний метод действия, который возвращает другой Partial. Вы проходите обратно

Вы эффективно возвращаете View _UsernamePartial, но возвращаете его

return View("_UsernamePartial");

без имени пользователяМодель

person Dave Alperovich    schedule 12.02.2013
comment
@BB987, прочитайте этот пост о частичных и дочерних действиях, он должен многое прояснить arrangeactassert.com/ - person Dave Alperovich; 12.02.2013