.net MVC3中的下拉框

.net MVC3中的下拉框,.net,asp.net-mvc-3,razor,.net,Asp.net Mvc 3,Razor,我试图在我的视图中实现编辑地址 地址包含街道、城镇等的基本字符串。地址还包含国家id。我的国家数据库中有一个表 在控制器中,我为以下国家/地区创建一个选择列表: ViewBag.Countries = _countryRepo.GetAll().Select(c => new SelectListItem { Text = c.Name, Value = c.Id }); 现在在我看来,我希望能够使用这个选择列表来允许用户选择国家 我原来以为, @Html.DropDownList("c

我试图在我的视图中实现编辑地址

地址包含街道、城镇等的基本字符串。地址还包含国家id。我的国家数据库中有一个表

在控制器中,我为以下国家/地区创建一个选择列表:

ViewBag.Countries = _countryRepo.GetAll().Select(c => new SelectListItem { Text = c.Name, Value = c.Id });
现在在我看来,我希望能够使用这个选择列表来允许用户选择国家

我原来以为,

@Html.DropDownList("countryId", (IEnumerable<Country>)ViewBag.Countries, "Select")
因此,在显示视图时,我需要显示选择的国家/地区。我认为我不能在控制器中执行此操作,因为如果我选择这样的控制器:

 ViewBag.Countries = _countryRepo.GetAll().Select(c => new SelectListItem { Text = c.Name, Value = c.Id, Selected = c.Id == model.HeadOffice.Id ? true : false });
这只适用于总部

据我所知,有两种选择。具有两个不同的选择列表或在视图中手动生成选择列表:

<select name="HeadOffice.CountryId">
    @foreach(var c in (IEnumerable<Country>)ViewBag.Countries)
    {
         <option value="@c.Id" @(c.Id == Model.HeadOffice.Id ? "selected='true'" : "">@c.Name</option>
    }
</select>

@foreach(在(IEnumerable)ViewBag.Countries中的变量c)
{
@c、 名字
}

最好的方法是什么?两者似乎都错了,而且都不好。有没有更好的方法来解决这个问题?

看看下面的博文:

你将在博客文章中找到所有细节

编辑:

对于您的情况,以下代码应该可以正常工作:

public ActionResult Index() { 

    ViewBag.DLForHeadOffice = GetItems(model.HeadOffice.Id);
    ViewBag.DLForSecondOffice = GetItems(model.SecondOffice.Id);

    //continue your code
}


private IEnumerable<SelectListItem> GetItems(int id) {

    _countryRepo.GetAll().
        Select(c => 
            new SelectListItem { 
                Text = c.Name, 
                Value = c.Id, 
                Selected = c.Id == id ? true : false 
            }
        );       
}
public ActionResult Index(){
ViewBag.DLForHeadOffice=GetItems(model.HeadOffice.Id);
ViewBag.DLForSecondOffice=GetItems(model.SecondOffice.Id);
//继续你的代码
}
私有IEnumerable GetItems(int id){
_countryRepo.GetAll()。
选择(c=>
新建SelectListItem{
Text=c.名称,
值=c.Id,
所选=c.Id==Id?真:假
}
);       
}

看看下面的博文:

你将在博客文章中找到所有细节

编辑:

对于您的情况,以下代码应该可以正常工作:

public ActionResult Index() { 

    ViewBag.DLForHeadOffice = GetItems(model.HeadOffice.Id);
    ViewBag.DLForSecondOffice = GetItems(model.SecondOffice.Id);

    //continue your code
}


private IEnumerable<SelectListItem> GetItems(int id) {

    _countryRepo.GetAll().
        Select(c => 
            new SelectListItem { 
                Text = c.Name, 
                Value = c.Id, 
                Selected = c.Id == id ? true : false 
            }
        );       
}
public ActionResult Index(){
ViewBag.DLForHeadOffice=GetItems(model.HeadOffice.Id);
ViewBag.DLForSecondOffice=GetItems(model.SecondOffice.Id);
//继续你的代码
}
私有IEnumerable GetItems(int id){
_countryRepo.GetAll()。
选择(c=>
新建SelectListItem{
Text=c.名称,
值=c.Id,
所选=c.Id==Id?真:假
}
);       
}

我会使用一个ViewModel,它会在国家列表中显示一次,然后显示两个不同的列表。这样,您只需查询数据库,但仍能保持视图干净

视图模型:

public class MyViewModel 
{
  public Address HeadOffice { get; set; }
  public Address SecondOffice { get; set; }

  public IEnumerable<Country> Countries { get;set;}

  public IEnumerable<SelectListItem> HeadOfficeCountries
  {
     get 
     {
       return GetCountriesList(Countries, HeadOffice.Id);
     }
  }

  public IEnumerable<SelectListItem> SecondOfficeCountries
  {
     get 
     {
       return GetCountriesList(Countries, SecondOffice.Id);
     }
  }

  private IEnumerable<SelectListItem> GetCountriesList(IEnumerable<Country> countries, int forAddress)
  {
     return countries.Select(c => new SelectListItem { Text = c.Name, Value = c.Id, Selected = c.Id == forAddress ? true : false });
  }
}
公共类MyViewModel
{
公共广播总部{get;set;}
第二公共广播局{get;set;}
公共IEnumerable国家{get;set;}
公共数字总部国家
{
得到
{
返回GetCountriesList(国家,总部.Id);
}
}
公共数字二级办公室国家
{
得到
{
返回GetCountriesList(国家,SecondOffice.Id);
}
}
私有IEnumerable GetCountriesList(IEnumerable国家/地区,地址为int)
{
返回国家/地区.Select(c=>newselectListItem{Text=c.Name,Value=c.Id,Selected=c.Id==forAddress?true:false});
}
}

我会使用一个ViewModel,它会在国家列表中显示一次,然后显示两个不同的列表。这样,您只需查询数据库,但仍能保持视图干净

视图模型:

public class MyViewModel 
{
  public Address HeadOffice { get; set; }
  public Address SecondOffice { get; set; }

  public IEnumerable<Country> Countries { get;set;}

  public IEnumerable<SelectListItem> HeadOfficeCountries
  {
     get 
     {
       return GetCountriesList(Countries, HeadOffice.Id);
     }
  }

  public IEnumerable<SelectListItem> SecondOfficeCountries
  {
     get 
     {
       return GetCountriesList(Countries, SecondOffice.Id);
     }
  }

  private IEnumerable<SelectListItem> GetCountriesList(IEnumerable<Country> countries, int forAddress)
  {
     return countries.Select(c => new SelectListItem { Text = c.Name, Value = c.Id, Selected = c.Id == forAddress ? true : false });
  }
}
公共类MyViewModel
{
公共广播总部{get;set;}
第二公共广播局{get;set;}
公共IEnumerable国家{get;set;}
公共数字总部国家
{
得到
{
返回GetCountriesList(国家,总部.Id);
}
}
公共数字二级办公室国家
{
得到
{
返回GetCountriesList(国家,SecondOffice.Id);
}
}
私有IEnumerable GetCountriesList(IEnumerable国家/地区,地址为int)
{
返回国家/地区.Select(c=>newselectListItem{Text=c.Name,Value=c.Id,Selected=c.Id==forAddress?true:false});
}
}

您考虑过使用HTML助手吗

我在我们的类中有一些私有的静态字典变量,它们处理字典的缓存,这样我们就不必在每次呈现下拉列表时获取国家列表(这就是countryDictionary下面的内容)

 public static MvcHtmlString CountrySelectFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string emptyText, object htmlAttributes)
    {
        SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = emptyText != null ? emptyText : "", Value = "" } };
        return htmlHelper.DropDownListFor(expression, emptyText != null ? SingleEmptyItem.Concat(new SelectList(countryDictionary, "Key", "Value")) : new SelectList(countryDictionary, "Key", "Value"), htmlAttributes);
    }
public static MvcHtmlString CountrySelectFor(此HtmlHelper HtmlHelper、表达式表达式、字符串emptyText、对象htmlAttributes)
{
SelectListItem[]SingleEmptyItem=new[]{new SelectListItem{Text=emptyText!=null?emptyText:,Value=”“};
返回htmlHelper.DropDownList for(expression,emptyText!=null?SingleEmptyItem.Concat(新选择列表(countryDictionary,“Key”,“Value”)):新选择列表(countryDictionary,“Key”,“Value”),htmlAttributes;
}
在这里,注册放置HTML助手的命名空间后,可以使用:

 <%: Html.CountrySelectFor(model => Model.HeadOffice.CountryId) %>
Model.HeadOffice.CountryId)%>
仅供参考,下面是countryList的代码片段。下面的“缓存”行不适用于您,这些是我们为管理应用程序缓存而创建的一些自定义类

 private static Dictionary<int, string> countryList
    {
        get
        {
            IList<Models.Country> countries = Caching.HTTPCache.Get(Caching.Common.CountryCacheName) as IList<Models.Country>;

            if (countries == null)
            {
                countries = Models.Country.Get(); //Loads all countries from the DB
                Caching.HTTPCache.Add(Caching.Common.CountryCacheName, countries , new TimeSpan(0, 0, Caching.Common.CountryCacheDuration, 0, 0)); //Adds the results to the cache
            }

            return countries .ToDictionary(t => t.CountryId, t => t.CountryName);
        }
    }
private静态字典countryList
{
得到
{
IList countries=Caching.HTTPCache.Get(Caching.Common.CountryCacheName)作为IList;
如果(国家==null)
{
countries=Models.Country.Get();//从数据库加载所有国家/地区
Caching.HTTPCache.Add(Caching.Common.CountryCacheName,countries,new TimeSpan(0,0,Caching.Common.CountryCacheDuration,0,0));//将结果添加到缓存中
}
返回countries.ToDictionary(t=>t.CountryId,t=>t.CountryName);
}
}

您考虑过使用HTML助手吗

我在我们的类中有一些私有的静态字典变量,它们处理字典的缓存,这样我们就不必在每次呈现下拉列表时获取国家列表(这就是countryDictionary下面的内容)

 public static MvcHtmlString CountrySelectFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string emptyText, object htmlAttributes)
    {
        SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = emptyText != null ? emptyText : "", Value = "" } };
        return htmlHelper.DropDownListFor(expression, emptyText != null ? SingleEmptyItem.Concat(new SelectList(countryDictionary, "Key", "Value")) : new SelectList(countryDictionary, "Key", "Value"), htmlAttributes);
    }
publicstaticm