简体   繁体   English

ViewModel在HttpPost方法中是Null

[英]ViewModel is Null in HttpPost method

I'm using ASP.NET MVC 4 and I built these ViewModels : 我正在使用ASP.NET MVC 4,我构建了这些ViewModel:

public class NotificationViewModel
{

    public string GroupDesc { get; set; }

    public bool AM { get; set; }

    public bool PM { get; set; }

    public int MaxNotif { get; set; }
}

public class SettingsViewModel
{
    public List<NotificationViewModel> ListNotification { get; set; }

    public SettingsViewModel()
    {
        ListNotification = new List<NotificationViewModel>();
    }
}

My View : 我的观点 :

@model PortailT2A.Models.SettingsViewModel

@{
    ViewBag.Title = "Preferences";
    Layout = "~/Views/Shared/_LayoutAdmin.cshtml";
}

<h2>Preferences</h2>


@using(Html.BeginForm("Preferences", "Administrateur", FormMethod.Post))
{

    <table id="settingsTable">
        <tr>
            <th>Groupe</th>
            <th></th>
            <th>AM</th>
            <th>PM</th>
            <th>Limite de notifications</th>
        </tr>

    @for (int i = 0; i < Model.ListNotification.Count(); i++ )
    {
        var notif = Model.ListNotification[i];
        <tr>
            <td>@notif.GroupDesc </td>
            <td>Heure de notification</td>
            <td>@Html.CheckBoxFor(u => notif.AM)  </td>
            <td>@Html.CheckBoxFor(u => notif.PM)  </td>
            <td>@Html.TextBoxFor(u => notif.MaxNotif)</td>
        </tr>
        <tr/>


    }

    </table>


    <input type ="submit" value="Sauvegarder" />

}

My HttpGet method populates my ViewModel and returns it. 我的HttpGet方法填充我的ViewModel并返回它。

    [HttpGet]
    public ActionResult Preferences(long idUser)
    {
        context = new MainDatabaseEntities();

        List<NotificationViewModel> notifications = new List<NotificationViewModel>();

        SettingsViewModel settings = new SettingsViewModel();

        //Population...

        return View(settings);
    }

However, when I want to save the changes, I got a ViewModel which is null and I don't understand why. 但是,当我想保存更改时,我得到一个nullM的ViewModel,我不明白为什么。 Any idea guys? 伙计们好吗?

EDIT : My post method : 编辑 :我的帖子方法:

            [HttpPost]
            public ActionResult Preferences(SettingsViewModel sm)
            {
                //since here my ViewModel is null
                context = new MainDatabaseEntities();

                Utilisateur user = (from u in context.Utilisateurs where u.Username == User.Identity.Name select u).FirstOrDefault();

                //operations...

}

HTML generated : 生成的HTML:

<tr>
        <td>Groupe B </td>
        <td>Heure de notification</td>
        <td><input id="notif_AM" name="notif.AM" type="checkbox" value="true" /><input name="notif.AM" type="hidden" value="false" />  </td>
        <td><input checked="checked" id="notif_PM" name="notif.PM" type="checkbox" value="true" /><input name="notif.PM" type="hidden" value="false" />  </td>
        <td><input id="notif_MaxNotif" name="notif.MaxNotif" type="text" value="10" /></td>
    </tr>

List<T> can be tricky when modelbinding since it relies heavily on the indexed keys. 模型绑定时List<T>可能很棘手,因为它严重依赖于索引键。 The helpers need to know the index, but by assigning notif within your for loop they're losing the reference. 帮助者需要知道索引,但是通过在for循环中分配notif ,他们将丢失引用。 Instead, try something like the following: 相反,尝试以下内容:

@for (int i = 0; i < Model.ListNotification.Count(); i++ )
{
    var notif = Model.ListNotification[i];
    <tr>
        <td>@notif.GroupDesc </td>
        <td>Heure de notification</td>
        <td>@Html.CheckBoxFor(u => u.ListNotification[i].AM)  </td>
        <td>@Html.CheckBoxFor(u => u.ListNotification[i].PM)  </td>
        <td>@Html.TextBoxFor(u => u.ListNotification[i].MaxNotif)</td>
    </tr>
    <tr/>
}

Which should then provide you with something like: 那应该为您提供如下内容:

<tr>
    <td>Groupe B </td>
    <td>Heure de notification</td>
    <td>
        <input id="ListNotification[0]_AM" name="ListNotification[0].AM" type="checkbox" value="true" />
        <input name="ListNotification[0].AM" type="hidden" value="false" />
    </td>
    <td>
        <input checked="checked" id="ListNotification[0]_PM" name="ListNotification[0].PM" type="checkbox" value="true" />
        <input name="ListNotification[0].PM" type="hidden" value="false" />
    </td>
    <td>
        <input id="ListNotification[0]_MaxNotif" name="ListNotification[0].MaxNotif" type="text" value="10" />
    </td>
</tr>

Also, make sure to check ModelState.IsValid in your posted action to confirm the model was bound correctly. 此外,请确保在已发布的操作中检查ModelState.IsValid以确认模型已正确绑定。 If not, you should see a list of errors in ModelState that would give you some indication as to where it may have failed. 如果没有,您应该在ModelState中看到一个错误列表,它可以指示它可能失败的位置。

Also, I don't see you dump GroupDesc anywhere (except to output). 另外,我没有看到你将GroupDesc转储到任何地方(输出除外)。 If this is necessary on the incoming model, you may consider using @Html.HiddenFor(x => x.ListNotifications[i].GroupDesc) . 如果在传入模型上这是必要的,您可以考虑使用@Html.HiddenFor(x => x.ListNotifications[i].GroupDesc)

You're not building your HTML correctly. 您没有正确构建HTML。 What is posted back will not have the paths the model binder expects. 回发的内容将不具有模型绑定器所期望的路径。

Consider replacing this: 考虑替换这个:

@for (int i = 0; i < Model.ListNotification.Count(); i++ )
{
    var notif = Model.ListNotification[i];
    <tr>
        <td>@notif.GroupDesc </td>
        <td>Heure de notification</td>
        <td>@Html.CheckBoxFor(u => notif.AM)  </td>
        <td>@Html.CheckBoxFor(u => notif.PM)  </td>
        <td>@Html.TextBoxFor(u => notif.MaxNotif)</td>
    </tr>
    <tr/>
}

with this: 有了这个:

@Html.DisplayModelFor(m => m.ListNotification)

and add a template like this to /Views/{YourController}/{YourAction}/EditorTemplates/NotificationViewModel.cshtml 并将这样的模板添加到/Views/{YourController}/{YourAction}/EditorTemplates/NotificationViewModel.cshtml

@model NotificationViewModel
<tr>
    <td>@Model.GroupDesc</td>
    <td>Heure de notification</td>
    <td>@Html.CheckBoxFor(m => m.AM)</td>
    <td>@Html.CheckBoxFor(m => m.PM)</td>
    <td>@Html.TextBoxFor(m => m.MaxNotif)</td>
</tr>

My first suggestion would be to try adding some random property to your SettingValueModel and adding it to the form as a hidden. 我的第一个建议是尝试向您的SettingValueModel添加一些随机属性,并将其作为隐藏添加到表单中。

Something like 就像是

 public class SettingsViewModel
 {
  public List<NotificationViewModel> ListNotification { get; set; }
  public string TestValue { get; set; }

  public SettingsViewModel()
  {
    ListNotification = new List<NotificationViewModel>();
    TestValue = "Test";   
  }
 }

Then in your view add 然后在你的视图中添加

@Html.HiddenFor(s=> s.TestValue)

When you submit your form, check to see if the SettingsViewModel isn't null. 提交表单时,请检查SettingsViewModel是否为空。 If the problem is just in the ListNotification serialization, then you might end up with an object with a TestValue of "Test" and null List Notifications. 如果问题只出现在ListNotification序列化中,那么最终可能会得到一个TestValue为“Test”且为null List Notifications的对象。 If that is the case, at least you know the problem is the ListNotifications. 如果是这种情况,至少你知道问题是ListNotifications。

Also try changing your for loop to this 还可以尝试将for循环更改为此

  @for (int i = 0; i < Model.ListNotification.Count(); i++ )
     {

         <tr>
             <td>@Model.ListNotification[i].GroupDesc </td>
             <td>Heure de notification</td>
             <td>@Html.CheckBoxFor(u => u.ListNotification[i].AM)  </td>
             <td>@Html.CheckBoxFor(u => u.ListNotification[i].PM)  </td>
             <td>@Html.TextBoxFor(u => u.ListNotification[i].MaxNotif)</td>

Also I don't think FormMethod.Post is required in the form definition. 另外,我不认为表单定义中需要FormMethod.Post。 Try all of these things. 尝试所有这些事情。 If none of them help, then I can only assume your PC is haunted =) 如果他们都没有帮助,那么我只能假设你的电脑被困扰=)

在我的情况下,由于某些奇怪的原因,我在我的视图模型定义中将我的setter作为内部,因此无法设置和存储绑定:

public int PaymentType { get; internal set; }

In POST action do you use right type of model? 在POST操作中,您使用正确的模型吗?

[HttpPost]
public ActionResult Preferences(PortailT2A.Models.SettingsViewModel model)
{
   //...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM