【问题标题】:Saving to m-2-m with checkboxes使用复选框保存到 m-2-m
【发布时间】:2013-09-24 19:59:41
【问题描述】:

所以我正在尝试使用 [Slauma's Answer][1]

到目前为止我做了什么,

模型 ViewModelProspectUsers

    public int Id { get; set; }
    public string User { get; set; }
    public IEnumerable<ViewModelUserProspectSelect> Prospects { get; set; }

模型 ViewModelUserProspectSelect

    public int ProspectID { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }

查看 UserInProspect

@model OG.ModelView.ViewModelProspectUsers

@using (Html.BeginForm())
{

<div class="container">
    <div class="contentContainer">
        @Html.HiddenFor(model => model.Id)
        Prospects for User <h3>@Html.DisplayTextFor(model => model.User)</h3>
    </div>
    <div class="contentContainer2">
        <h5>Please Select Prospects you wish to assign to this User.</h5>
        <p></p>

            @Html.EditorFor(model => model.Prospects)

    </div>
    <input type="submit" value="Save changes" />
    @Html.ActionLink("Cancel", "Index")
</div>
}

编辑器视图位于 ChangeUserInfo/EditorTemplates/*_ViewModelUserprospectSelect.cshtml* 下*

@model OG.ModelView.ViewModelUserProspectSelect

@Html.HiddenFor(model => model.ProspectID)
@Html.HiddenFor(model => model.Name)
test
@Html.LabelFor(model => model.IsSelected, Model.Name)
@Html.EditorFor(model => model.IsSelected)

[Get] 方法 UserInProspect 操作

public ActionResult UsersInProspect(int id = 0)
    {
        var data = db.UserProfiles
        .Where(s => s.UserID == id)
        .Select(s => new
        {
            ViewModel = new ViewModelProspectUsers
            {
                Id = s.UserID,
                User = s.UserName
            },
            prospects = s.Prospects.Select(c => c.ProspectID)
        })
        .SingleOrDefault();

        if (data == null)
            return HttpNotFound();

        // Load all companies from the DB
        data.ViewModel.Prospects = db.Prospect
            .Select(c => new ViewModelUserProspectSelect
            {
                ProspectID = c.ProspectID,
                Name = c.ProspectName
            })
            .ToList();

        // Set IsSelected flag: true (= checkbox checked) if the company
        // is already related with the subscription; false, if not
        foreach (var c in data.ViewModel.Prospects)
            c.IsSelected = data.prospects.Contains(c.ProspectID);

        return View(data.ViewModel);

    }

[HttpPost] 方法 UserInProspect 操作

    public ActionResult UsersInProspect(ViewModelProspectUsers viewModel)
    {
        if (ModelState.IsValid)
        {
            var subscription = db.UserProfiles.Include(s => s.Prospects)
                .SingleOrDefault(s => s.UserID == viewModel.Id);

            if (subscription != null)
            {
                // Update scalar properties like "Amount"
                //subscription.Prospects = viewModel.Prospects;
                //subscription. = subscription.
                //List<string> myList = new List<string>();
                //myList = viewModel.Prospects.Cast<String>().ToList();

                //IEnumerable<dbProspect> Isubscription = subscription.Prospects;
                ////or explicit:
                //var iPersonList = (IEnumerable<dbProspect>)myList;


                // or more generic for multiple scalar properties
                // _context.Entry(subscription).CurrentValues.SetValues(viewModel);
                // But this will work only if you use the same key property name
                // in ViewModel and entity

                foreach (var prospect in viewModel.Prospects)
                {
                    if (prospect.IsSelected)
                    {
                        if (!subscription.Prospects.Any(
                            c => c.ProspectID == prospect.ProspectID))
                        {
                            // if company is selected but not yet
                            // related in DB, add relationship
                            var addedProspect = new dbProspect { ProspectID = prospect.ProspectID };
                            db.Prospect.Attach(addedProspect);
                            subscription.Prospects.Add(addedProspect);
                        }
                    }
                    else
                    {
                        var removedProspect = subscription.Prospects
                            .SingleOrDefault(c => c.ProspectID == prospect.ProspectID);
                        if (removedProspect != null)
                            // if company is not selected but currently
                            // related in DB, remove relationship
                            subscription.Prospects.Remove(removedProspect);
                    }
                }

                db.SaveChanges();
            }

            return RedirectToAction("Index");
        }

        return View(viewModel);
    }

【问题讨论】:

  • 当你说“...我的前景是空的”你是指viewModel.Prospects还是subscription.Prospects
  • subscription.Prospects 抱歉没有澄清,我认为问题是我正在使用列表并且不明白如何设置我的列表viewModel.Prospects = Ienumerable Subscription.prospects
  • 嗯,但这看起来是一个非常不同的问题。您正在从数据库加载订阅包括潜在客户:subscription = db.UserProfiles.Include(s =&gt; s.Prospects)...subscription.Prospects 绝不能是 null,即使数据库中没有潜在客户。那么它可能是一个空集合,但绝不是null。你真的是说null,而不是“空集合”???
  • 值不再为 Null。我对代码进行了一些更改,发现我现在在viewModel(在 Post 方法开始之后)我检查了我的值,我的 viewModel.ProspectID 是 0 viewModel.Names 是“”。但所选值正在正确发布。然后我假设因为 id 是 null 并且在数据库中不存在,所以没有任何改变。
  • 您是否真的在我的回答中使用了编辑器模板中的方法?在这种情况下,Id 和 Name 都不应该为空,因为我已将它们作为隐藏字段放入视图中(@Html.HiddenFor(model =&gt; model.CompanyId)@Html.HiddenFor(model =&gt; model.Name))。或者您是否使用了第二个链接中的解决方案? Name 那里没有隐藏字段,因此很明显您不会在 POST 上获取此值。但是 Id 有一个隐藏字段,所以它不应该是 0。

标签: c# asp.net-mvc post checkbox many-to-many


【解决方案1】:

添加了对我的控制器的引用 OG.Views.ChangeUsersInfo.EditorTemplates;

再次删除。 “EditorTemplates”不应是命名空间。

在下添加了编辑器模板 视图/ChangeUsers/Info/EditorTemplates/ViewModeluserProspectSelect.cs

“编辑器模板”不是 C# (.cs) 代码文件,而是 Razor 视图 (.cshtml)。将文件 ViewModelUserProspectSelect.cs 移动到 ViewModelProspectUsers.cs 所在的文件夹,并将其命名空间更改为两个类的相同 (OG.Models)。

(为什么路径中有一个子文件夹/Info/?或者它是一个错字,只是Views/ChangeUsersInfo/EditorTemplates的意思?我假设控制器的名称是ChangeUsersInfoController,对吧?)

然后在 Views/ChangeUsersInfo/EditorTemplates 文件夹中创建一个新文件 ViewModelUserProspectSelect.cshtml,其中包含来自另一个答案的视图,这个:

@model OG.Models.ViewModelUserProspectSelect

@Html.HiddenFor(model => model.ProspectID)
@Html.HiddenFor(model => model.Name)

@Html.LabelFor(model => model.IsSelected, Model.Name)
@Html.EditorFor(model => model.IsSelected)

您主视图中的contentContainer2 div 元素应如下所示:

<div class="contentContainer2">
    <h5>Please Select Prospects you wish to assign to this User.</h5>

    @Html.EditorFor(model => model.Propects)
</div>

【讨论】:

  • 好的,代码已更改并编译,非常感谢您抽出宝贵时间帮助我。当它在视图中运行时,我看到 1234 我会假设它实际上是 1,2,3,4(但没有显示每个前景名称的空格,但是没有显示复选框,想法?)
  • @Pakk: 什么是 1,2,3,4???集合中 4 个 propect 的 PropectID?您根本不应该看到这些数字,因为 ID 是使用 HiddenFor 呈现的。要检查 MVC 是否找到了编辑器模板,您可以在模板中写入静态文本“测试”。您应该会看到它,就像您在 Prospects 集合中拥有项目一样频繁。
  • 所以我把文本放在了代码之间,我什至把它全部注释掉了,保存重新加载没有任何变化。觉得这很奇怪,所以我重新构建了应用程序并运行它,同样,没有变化。现在我很困惑,我更新上面的代码。另外,如何一步一步完成编辑器模板?它不会让我到达断点 - 没有添加任何符号?
  • @Pakk:在您编辑的问题中,您写了_ViewModelUserprospectSelect.cshtml。编辑器模板开头不能有下划线(必须与类同名)。
  • 太棒了,非常抱歉,感谢编辑器模板的介绍以及您对代码的帮助,现在能够编写 M-2-M 表真是太棒了,非常感谢!
猜你喜欢
  • 2015-04-17
  • 2017-04-11
  • 2023-01-20
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
相关资源
最近更新 更多