从Ilist模型获取数据到控制器

时间:2014-10-24 14:31:57

标签: c# asp.net asp.net-mvc

好的,请原谅,如果这是新手错误..我一直在寻找各种解决方案,但仍然无法到达任何地方。 我需要能够将用户(Id)与公司相关联。我已链接到SelectCompInst并已传入用户ID。 我在getinstitution模型中有一个bool标志,我在get方法中设置了它。标志在视图中正确显示。如果需要,我可以改变它的复选框这一事实..但我只是想放一个按钮,理想情况下链接会在列表中引起回发,以便允许操作员选择要附加到该用户的公司。我确信一直都在做。

我已经看到了对这类问题的各种引用,说我可能不得不使用编辑模板?但我从未发现它解释了原因?当然它可以变得那么复杂吗? 这是我的模特:

    [Key]
    public int Id { get; set; }
    public DateTime RecordCreateDate { get; set; }
    [ForeignKey("Address")]
    public int AddressId { get; set; }
    public string Name { get; set; }
    [ForeignKey("PrimaryContact")]
    public string PrimaryContactId { get; set; }

    public virtual Address Address { get; set; }
    public virtual ApplicationUser PrimaryContact { get; set; }

    [NotMapped]
    public bool UserFlag { get; set; } //Bool to define if user is in this activity type when searching

这是观点:

@model IList<Dune.Models.CompanyInstitution>

@{
    ViewBag.Title = "Index";
    string staffid = ViewBag.StaffId;
}

<h2>Select Company/Institution for user @ViewBag.UserName</h2>
@using (Html.BeginForm("SelectCompInst","UserAdmin",FormMethod.Post, new {id ="compselect"}))
{ 
    @Html.AntiForgeryToken()
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table class="table">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model[0].Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model[0].Address)
            </th>
            <th>
                @Html.DisplayNameFor(model => model[0].PrimaryContact)
            </th>
            <th>
                @Html.DisplayNameFor(model => model[0].RecordCreateDate)
            </th>
            <th></th>
        </tr>

        @for (int i = 0; i < Model.Count(); i++)
        {
            <tr>
                <td>
                    @Html.DisplayFor(m => m.ElementAt(i).Name)
                </td>
                <td>
                    @{
            var AddressString = Model.ElementAt(i).Address.AddressAsString();
                    }
                    @Html.DisplayFor(modelItem => AddressString)
                </td>
                <td>
                    @{ var NameString = "Not Allocated";
                     if (Model.ElementAt(i).PrimaryContact != null)
                     {
                         NameString = Model.ElementAt(i).PrimaryContact.FullNameNoMidString();
                     }
                    }
                    @Html.DisplayFor(modelItem => NameString)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => modelItem.ElementAt(i).RecordCreateDate)
                </td>
                <td>
                    @Html.EditorFor(modelItem => modelItem.ElementAt(i).UserFlag)
                </td>
                <td>
                    @*  Ideally I would like to put a simple 'Select' Link here and also post back the UserId
                     contained in Viewbag.StaffId.. I figure I can add that to the view model though
                     if I can get anything at all*@
                </td>
            </tr>
        }
    </table>
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="Select" />
    </div>
}

..以及控制器方法:

//
//  GET: 
public async Task<ActionResult> SelectCompInst(string StaffId)
{
    ApplicationUser user = await UserManager.FindByIdAsync(StaffId);
    ViewBag.UserName = "Error User not found!";
    if (user != null)
    {
        ViewBag.UserName = user.FullNameString();
        ViewBag.StaffId = StaffId;
    }
    var companysInstitutions = db.CompanysInstitutions.Include(c => c.Address).Include(c => c.PrimaryContact);
    // Walk the list and set the flag if this user is already mapped to this institution.
    foreach (CompanyInstitution comp in companysInstitutions)
    {
        if (user.CompanyInstitutionStaffMember.CompanyInstituteId == comp.Id)
        {
            comp.UserFlag = true;
        }
        else
        {
            comp.UserFlag = false;
        }
    }
    IList<CompanyInstitution> companys = await companysInstitutions.ToListAsync();
    return View(companys);
}

//
//  POST:
[HttpPost, ActionName ("SelectCompInst")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SelectComp(IList<CompanyInstitution> Company )
{
    //
    // Code removed because it doesnt get this far with any data :)
    //
    ModelState.AddModelError("", "Something failed.");
    return View();
}

我已经使用fiddler查看了帖子,但我什么都没有...虽然Post功能正在被击中。 IList公司是空的...... 我相信这可归结为对我的一个根本性的误解,但现在已经挣扎了2天......不得不让自己受到更明智的社区的怜悯:)

我想对表中的每一行添加一个链接,只需传回一行代码和用户ID ..谢谢。

继斯蒂芬斯评论后进一步编辑.. 该方案是在编辑用户时。用户可以将CompanyInstituion Id作为其模型的一部分。我希望向运营商(不一定是用户)提供公司列表,以允许他们将公司ID附加到该用户。所以在概念上它简单易行 - 提供了一个可供选择的公司名单。按&#39;选择&#39;在公司线上链接并返回控制器进行排序。因此,我需要在Viewbag中保留UserId - 是的,如果需要我可以创建一个viewmodel,但单独获取公司ID将是一个开始).. 这就是它......显示列表,选择一个并将其返回..我也不是真的想要使用复选框..我有点&#39;到达那里&#39;在尝试了一些事情之后在添加复选框之前,我最初在循环中有提交按钮。我确实尝试将公司ID放在按钮上,但这也没有用。

1 个答案:

答案 0 :(得分:2)

如果运营商必须选择与该用户关联的单个公司,那么采取所选公司ID和用户ID的POST操作会更有意义。这应该是您完成工作的足够信息:

[HttpPost, ActionName ("SelectCompInst")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SelectComp(int companyId, string staffId)
{
    ...
}

然后在您的视图中,您可以在表格的每一行上有多个表单和一个提交按钮:

@model IList<Dune.Models.CompanyInstitution>

@{
    ViewBag.Title = "Index";
    string staffid = ViewBag.StaffId;
}

<h2>Select Company/Institution for user @ViewBag.UserName</h2>

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model[0].Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model[0].Address)
            </th>
            <th>
                @Html.DisplayNameFor(model => model[0].PrimaryContact)
            </th>
            <th>
                @Html.DisplayNameFor(model => model[0].RecordCreateDate)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @for (var i = 0; i < Model.Count; i++)
        {
            <tr>
                <td>
                    @Html.DisplayFor(m => m[i].Name)
                </td>
                <td>
                    @{
                        var AddressString = Model[i].Address.AddressAsString();
                    }
                    @Html.DisplayFor(modelItem => AddressString)
                </td>
                <td>
                    @{ 
                        var NameString = "Not Allocated";
                        if (Model[i].PrimaryContact != null)
                        {
                            NameString = Model[i].PrimaryContact.FullNameNoMidString();
                        }
                    }
                    @Html.DisplayFor(modelItem => NameString)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => modelItem[i].RecordCreateDate)
                </td>
                <td>
                    @Html.EditorFor(modelItem => modelItem[i].UserFlag)
                </td>
                <td>
                    @using (Html.BeginForm("SelectCompInst", "UserAdmin", new { companyId = Model[i].Id, staffId = staffid }, FormMethod.Post, new { @class = "compselect" }))
                    {
                        @Html.AntiForgeryToken()
                        <div class="col-md-offset-2 col-md-10">
                            <input type="submit" value="Select" />
                        </div>
                    }
                </td>
            </tr>
        }
    </tbody>
</table>

基本上我们会在表格的每一行都有一个HTML表单,它会将必要的信息传递给服务器:

@using (Html.BeginForm(
    actionName: "SelectCompInst", 
    controllerName: "UserAdmin", 
    routeValues: new { companyId = Model[i].Id, staffId = staffid }, 
    method: FormMethod.Post, 
    htmlAttributes: new { @class = "compselect" }))
{
    @Html.AntiForgeryToken()
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="Select" />
    </div>
}