【问题标题】:Model passed to Partial to View模型传递给部分视图
【发布时间】:2015-05-07 12:33:56
【问题描述】:

一直在四处寻找,但找不到我想要实现的直接解决方案。

我已尝试根据需要包含尽可能多的内容,但这是一个非常大的项目,因此希望您能掌握要点。

概述: 我有一个视图模型,其中包含多个对象列表。我使用两个部分视图来控制每个对象列表,一个用于收集对象列表(在会话中保存),另一个用于将所述对象的列表添加到列表中。

更新: 根据评论-我要做的如下-在索引中,填写通过addToListPartialView显示的现有Ip模型信息,然后它将发布到ListPartialView以通过会话更新列表,在后端处理控制器,它将依次显示在索引上 - 最终的问题是,我如何实现这一点?

问题: 我遇到的问题是,一旦我通过部分视图将对象添加到对象列表、另一个部分视图中,我该如何将其传递回主视图?

代码:

控制器

public ActionResult AddExistingIp([Bind(Include = "Subnet, Cidr, Mask")]ExistingIp existingIp)
        {
            if(Session["pa_ipv4Session"] != null)
            {
                pa_ipv4 pa_ipv4 = (pa_ipv4)Session["pa_ipv4Session"];
                if(pa_ipv4.ExistingIps == null)
                {
                    pa_ipv4.ExistingIps = new List<ExistingIp>();
                }
                pa_ipv4.ExistingIps.Add(existingIp);
                ViewBag.pa_ipv4 = pa_ipv4.ExistingIps;

                return View("ExistingIpView", ViewBag.pa_ipv4);
            }
            else
            {
                pa_ipv4 pa_ipv4 = new pa_ipv4();
                Session["pa_ipv4Session"] = pa_ipv4;
                pa_ipv4.ExistingIps = new List<ExistingIp>();
                pa_ipv4.ExistingIps.Add(existingIp);
                ViewBag.pa_ipv4 = pa_ipv4.ExistingIps;

                return View("ExistingIpView", ViewBag.pa_ipv4);
            }

索引:

@model ViewModel
<div id="ExistingIpList">
                    @{Html.RenderPartial("ExistingIpView");}
                </div>
                <div id="addExisting">
                    @{Html.RenderPartial("AddExistingIp");}
                </div>

列出部分

@model IEnumerable<ExistingIp>

@if (Model != null)
{
    foreach (var ei in Model)
    {
        <div class="ui-grid-c ui-responsive">
            <div class="ui-block-a">
                <span>@ei.Subnet</span>
            </div>
            <div class="ui-block-b">
                <span>@ei.Cidr</span>
            </div>
            <div class="ui-block-c">
                <span>@ei.Mask</span>
            </div>
            <div class="ui-block-d">
                @ei.Id
                <a href="#" class="deleteExistingIp" cssclass="ui-btn ui-corner-all ui-shadow">Delete</a>
            </div>
        </div>
    }
}

部分添加到列表:

@using (Html.BeginForm("AddExistingIp", "PA_IPV4"))
{
    <div class="ui-grid-c ui-responsive">
        <div class="ui-block-a">
            <span>
                @Html.EditorFor(m => m.Subnet)
                @Html.ValidationMessageFor(m => m.Subnet)
            </span>
        </div>
        <div class="ui-block-b">
            <span>
                @Html.EditorFor(m => m.Cidr)
                @Html.ValidationMessageFor(m => m.Cidr)
            </span>
        </div>
        <div class="ui-block-c">
            <span>
                @Html.EditorFor(m => m.Mask)
                @Html.ValidationMessageFor(m => m.Mask)
            </span>
        </div>
        <div class="ui-block-d">
            <span>
                @Html.EditorFor(m => m.Id)
                @Html.ValidationMessageFor(m => m.Id)
            </span>
        </div>
    </div>
    <div data-role="main" class="ui-content">
        <div data-role="controlgroup" data-type="horizontal">
            <input type="submit" id="addExistingIp" cssclass="ui-btn ui-corner-all ui-shadow" value="Add" />
        </div>
    </div>
}

视图模型:

public Contact ContactDetails { get; set; }
[Required]
public bool ExistingAddress { get; set; }
public List<ExistingIp> ExistingIps { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string ExistingNotes { get; set; }

【问题讨论】:

  • 不完全确定您的要求,但如果一个部分包含添加新项目的表单,那么当您发布时,您需要重定向回 GET 方法以便重建视图。但是使用 ajax 发布表单,然后使用新项目更新 DOM 会更好的性能
  • 对不起,我会更新问题并尝试使其更清楚 - 基本上我想要做的是在索引中,填写通过 addPartialView 显示的现有 Ip 模型信息,然后它将发布到 ListPartialView 以通过会话更新列表,该会话将依次显示在索引上。
  • 这意味着当您发布到AddExistingIp并保存了该项目时,您需要重定向到Index() method,而不是返回视图。但是使用 ajax 的性能会好得多,而且你可以摆脱 Session 的糟糕使用
  • 您的意思是完全删除会话?在提交之前我没有数据库,它允许模型(很多)跨页面遍历并返回,读取和写入。有那么糟糕还是个人不喜欢?
  • @JammAndTea 他的意思是我在回答中做了一些事情。您必须 RedirectToAction("Index") 并在那里从 Session 获取列表并将其提供给 Index 视图。

标签: c# asp.net-mvc razor


【解决方案1】:

您可以修改AddExistingIp 以仅存储数据。并制作一个RedirectToActionIndex。在那里,您将从Session 获取数据并将其传递给模型。

[HttpPost]
public ActionResult AddExistingIp([Bind(Include = "Subnet, Cidr, Mask")]ExistingIp existingIp)
{
    if(Session["pa_ipv4Session"] != null)
    {
        pa_ipv4 pa_ipv4 = (pa_ipv4)Session["pa_ipv4Session"];
        if(pa_ipv4.ExistingIps == null)
        {
            pa_ipv4.ExistingIps = new List<ExistingIp>();
        }
        pa_ipv4.ExistingIps.Add(existingIp);
    }
    else
    {
        pa_ipv4 pa_ipv4 = new pa_ipv4();
        Session["pa_ipv4Session"] = pa_ipv4;
        pa_ipv4.ExistingIps = new List<ExistingIp>();
        pa_ipv4.ExistingIps.Add(existingIp);
    }

    return RedirectToAction("Index");
}

Index 操作看起来与此类似,您从 Session 获取数据并在您的模型中使用它

public ActionResult Index()
{
    var viewModel = new ViewModel();

    // take data from Session
    pa_ipv4 pa_ipv4 = Session["pa_ipv4Session"] as (pa_ipv4);
    // some verification    
    // add the list from Session to model
    viewModel.ExistingIps = pa_ipv4.ExistingIps;

    return View(viewModel);
}

另外,我认为你的Index 视图你应该在ExistingIpView 你应该通过Model 来显示。

@model ViewModel
<div id="ExistingIpList">
    @{Html.RenderPartial("ExistingIpView", Model.ExistingIps);}
</div>
<div id="addExisting">
    @{Html.RenderPartial("AddExistingIp");}
</div>

【讨论】:

  • 您的编辑应该可以解决这个问题,需要在页面加载时创建所有内容的新实例,干杯。
  • @JammAndTea 我不明白你的意思,你能告诉我更多细节吗?
  • 我不认为上面是正确的,renderpartial existingIpView 中的空引用,model.existingIps 因为它在启动时没有被创建,你不能遍历一个没有'的列表不存在。这应该/不能通过控制器来完成吗?
  • @JammAndTea 是的,这需要在Index Action 中完成,因为我提到“将从 Session 获取数据的索引”。
  • 我没有注意到,抱歉通知对我不起作用,但我确实尝试过,但我在另一个部分收到错误,需要传递类型为 existingIp 的模型项(对象这是在列表中)。我正在通过 @{Html.RenderPartial("AddExistingIp", new Project.Models.ExistingIp());} 执行此操作 - 这是唯一/最好的方法吗?
猜你喜欢
  • 2017-02-16
  • 2019-02-01
  • 2012-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多