【问题标题】:@Html.DropDownListFor fails in partial view but not in Full Page View@Html.DropDownListFor 在部分视图中失败,但在全页视图中失败
【发布时间】:2013-05-30 12:30:46
【问题描述】:

我的 PartialView DropDownListFor 出现错误:

The ViewData item that has the key PlanId is of type System.int32 but must be of type   
IEnumerable<SelectListItem>

@Html.DropDownListFor(model => model.PlanId, (SelectList)ViewBar.PlanNameSelectList, new {@class = "short" })  

当我转到最初保存此代码的页面时,不会弹出此错误。只要我取出代码中的 DropDownListFor 元素,我所做的就是将之前与另一个 partialView 一起工作的代码的核心部分删掉。那个partialView我不需要它们,但是现在我需要它们,问题就来了。

如果能帮助我解决这个问题,我将不胜感激。其他资源,例如对部分的调用,如下所示

@Html.Partial("location", new MAO.Models.ViewModels.CreateTemplateModel{})

这是模型

public class CreateTemplateModel {
    [Required(ErrorMessage = "{0} is required.")]
    [RegularExpression("^[0-9]+$", ErrorMessage="Template Id can only contain numbers")]
    [Display(Name = "Template ID")]
    public string TNumber { get; set; }

    [Required(ErrorMessage = "{0} is required.")]
    [RegularExpression("^.[0-9]{4}(-[0-9]{3})?$", ErrorMessage = "H# Must follow either @XXXX or @XXXX-XXX pattern")]
    [Display(Name = "HNumber")]
    public string HNumber { get; set; }

    [RequiredIfOtherIsEmpty("NewPlanName", ErrorMessage = "Please enter a Plan Name")]
    [Display(Name = "Select Existing Plan Name")]
    public int PlanId { get; set; }

    [MaxLength(500, ErrorMessage="{0} can't be longer than 500 characters")]
    [Display(Name = "Enter New Plan Name")]
    public string NewPlanName { get; set; }

    [RequiredIfOtherIsEmpty("NewParentOrganization", ErrorMessage = "Please enter a Parent Organization")]
    [Display(Name = "Select Existing Parent Organization")]
    public string ParentOrganization { get; set; }

    [MaxLength(500, ErrorMessage = "{0} can't be longer than 500 characters")]
    [Display(Name = "Enter New Parent Organization")]
    public string NewParentOrganization { get; set; }

    [Required(ErrorMessage = "{0} is required.")]
    public int TemplateTypeId { get; set; }
}

有一个很长的控制器,所以我不打算发布它。如果控制器的某些部分会有所帮助,我可以发布这些部分以及我可能忘记包含的其他任何内容

【问题讨论】:

  • 视图和局部视图的强类型模型有区别吗?
  • 我刚刚开始从事这一切工作,并且接受过 0 次经典培训,所以说实话,我什至不知道强类型在 C# 和模型中的含义。
  • 没问题!强类型视图意味着模型绑定到它。如果您的视图是强类型的,您会在顶部看到一个类似于@model MAO.Models.ViewModels.CreateTemplateModel 的模型声明。顺便说一句,当您渲染局部时,您正在创建一个新模型。有什么东西会使该模型饱和吗?
  • 回答第一部分。是的,这是一个强类型模型。我不确定饱和度是什么意思。如果这意味着一个模型链接到两个页面,那么是。为了保持原始页面的完整性,我删除了一部分代码。
  • 模型将两者联系起来,但它只是一个空模型,对吗?有什么可以填的吗?

标签: c# asp.net-mvc ienumerable html.dropdownlistfor asp.net-mvc-partialview


【解决方案1】:

根据您的 cmets,我怀疑您在返回局部视图时从未重新绑定下拉列表。您的部分控制器操作应该以与呈现完整视图的控制器操作相同的方式构建您的下拉列表。比较两者并确保它们匹配。

更新:您的局部视图操作应如下所示:

public ActionResult Location()
{
    ViewBag.PlanNameSelectList = new SelectList(plans.Distinct(), "Id", "Name", plans.FirstOrDefault(plan => plan.Name == selectedPlan));
    attachSelectLists(ViewBag); 
    return PartialView("Location");
}

你目前在做什么

@Html.Partial("location", new MAO.Models.ViewModels.CreateTemplateModel{})

正在使用新的 CreateTemplateModel 对象呈现局部视图“位置”,而不是现有对象。相反,一个更好的方法是复制你的控制器动作。专门为您的局部视图创建一个新视图(目前这是一个更简单的用例)。

public ActonResult TestPartialView()

不要使用呈现部分的@Html.Partial,而是尝试调用您的新控制器操作,这将为您构建下拉列表。

@Html.RenderAction("TestPartialView").

这将调用您的新控制器操作并在页面上呈现部分内容,同时保留控制器逻辑。如果你使用@Html.Partial,它只会渲染局部视图,传入你给它的任何对象,在这种情况下,它是一个新的、空的 CreateTemplateModel。

【讨论】:

  • 所以我需要一个全新的独立控制器用于局部视图,而不是将局部视图和 regview 都连接到同一个控制器?
  • 当然可以。您可以根据某些逻辑流程在同一个控制器中渲染它们。但是,如果它们没有返回相同的数据,则它们需要单独返回,并且您不想使用 return View() 来返回部分视图。
  • 我确实返回了相同的数据。我希望我能理解后端在做什么,这样我现在就不能表现得像个笨蛋。我有一个公共 ActionResult Create(){attachSelectList(ViewBag); return View();} 我知道这是在页面加载时自动调用的,或者我至少假设它在页面加载/调用时被调用。我如何让 partialView 不因选择列表对两者都具有受控工作而失败。我应该创建另一个方法,但重载它以便它传递一个值来区分两者吗?
  • partialView 未达到控制器中的 Create。如果我转到我从中删除它的页面,就会达到此方法。你知道为什么会这样吗?
  • 如果你为局部视图创建一个新的控制器动作,它永远不会命中 Create()。相反,它会击中您的新控制器动作。在我的示例中,它将是 TestPartialView()
猜你喜欢
  • 2015-11-20
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
  • 2015-09-10
  • 1970-01-01
  • 1970-01-01
  • 2015-09-18
  • 2013-10-28
相关资源
最近更新 更多