0

我有以下地址 ViewModel:

public class AddressViewModel
{
    [StringLength(20, MinimumLength = 2, ErrorMessage = "Country name is too short")]
    public String Country { get; set; }

    public String City { get; set; }
    public String Street { get; set; }
    public String Number { get; set; }
    public String ApartmentBuilding { get; set; }
    public String Sector { get; set; }
}

以及呈现它的视图:

<div class="control-group offset2 span6">
    @Html.LabelFor(m => m.Country)
    <div class="controls">
        @{
            var countryCtrlName = Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName("Country");
            Html.RenderAction("List", "Country", new { ControlName = countryCtrlName });
        }
        @Html.ValidationMessageFor(m => m.Country)
    </div>
</div>

Html.RenderAction("List") 调用一个控制器方法,该方法从数据库中获取所有国家,并使用下拉列表呈现和呈现部分,这是视图:

@model IEnumerable<SelectListItem>
@{var controlName = (string)ViewBag.ControlName;}
@Html.DropDownList(controlName, Model, new {@class = ViewBag.CssClass})

即使我的 DropdownList 控件使用正确的名称呈现并因此在 POST 时映射到正确的 ViewModel,输入控件也没有使用必要的 data-val 属性进行装饰以启用客户端验证(我相信这是因为模型部分是 IEnumerable 而不是包含国家名称的字符串属性。

地址视图模型通过我的应用程序用作许多视图的嵌套属性。关于如何使其验证的任何想法?

编辑:根据@Robert 的回答更新了 ViewModel:

public class AddressViewModel { [StringLength(20, MinimumLength = 2, ErrorMessage = "Country name is too short")] public String Country { get; 放; }

public String City { get; set; }
public String Street { get; set; }
public String Number { get; set; }
public String ApartmentBuilding { get; set; }
public String Sector { get; set; }

public IEnumerable<CountryViewModel> CountryList {get; set;}

//Constructor to pass the list of countries
public AddressViewModel(IEnumerable<CountryViewModel> countries)
{
    this.CountryList = countries;
}

}

4

2 回答 2

1

您是否尝试过制作 CountryModel 并有一个单独的控制器来处理您的下拉列表。让控制器返回一个局部视图,您可以将其放在您想要的任何页面上。在 CountryModel 上拥有一个带有 IEnumerable 的属性?

地址视图:

@model AddressModel

@Html.Partial("nameOfPartialView", CountryModel)

模型:

public class CountryModel
{
    public IEnumerable<Countries> Countries { get; set; }
}

控制器:

public ActionResult Countries()
{
    var countries = //get the list from the database
    return PartialView(countries);
}

国家下拉列表的部分视图:

@model CountryModel
@{var controlName = (string)ViewBag.ControlName;}
@Html.DropDownListFor(Model => Model.Countries)

接受国家的控制器:

public ActionResult GetCountry(int CountryId)
{
     //do something with the selected country
}
于 2013-03-06T21:10:06.010 回答
0

我认为您对问题所在是正确的:您没有将带注释的模型传递给局部视图,而是IEnumerableSelectListItem. 框架不知道您显示的内容代表什么:它只知道如何称呼它。

我可以看到这样做很方便,但它有点违反 MVC 的精神。在这种情况下,您的“模型”并不是真正的模型,它只是传递标记项列表(列表项)的一种方式。

我会用整体AddressViewModel作为你的模型。这样,您将保留数据注释中的信息,这些信息告诉您该属性的要求是什么。

于 2013-03-06T21:08:52.097 回答