SelectList不使用硬编码名称

时间:2014-12-27 09:51:16

标签: c# asp.net-mvc selectlist

是否有快速方式可以在不使用硬编码名称的情况下创建SelectList:

myViewModelVM.Companies = new SelectList(companies , "Id", "CompanyName");

其余代码:

public class MyViewModelVM
{
    public SelectList Companies { get; set; }
}

MyEntities myEntities = new MyEntities();
List<Company> companies = myEntities.Companies.ToList();

修改

到目前为止,我得到了这个:

myViewModelVM.Companies  = new SelectList(
                              companies.Select(n => new SelectListItem() 
                                 { Text = n.Id.ToString(), Value = n.CompanyName }), 
                                 "Text", "Value"
                           );  

虽然这仍然是harcode,TextValue是标准值

2 个答案:

答案 0 :(得分:1)

除非您想使用customattributes修饰模型类,否则您需要使用某种约定将Id和CompanyName映射到Value和Text。

这使用较少的硬连线,并为您提供扩展映射的选项。我将SelectList子类化,您可以添加任何类型。它将名称为id的属性映射到Value,并将其中包含Name的属性映射到Text

public class SelectListAuto<T>: SelectList
{
    public SelectListAuto(IEnumerable list):base(list, GetId(typeof(T)), GetName(typeof(T)))
    {
    }

    static string GetId(Type t) {
       // you can have all kind logic to autowire up, ie use some convention
       return t.GetProperties()
              .Where(p => p.Name.Equals("Id",StringComparison.OrdinalIgnoreCase))
              .Select(p=>p.Name).First();
    }

    static string GetName(Type t) {
       // you can have all kind logic to autowire up, ie use some convention
       return t.GetProperties()
              .Where(p => p.Name.IndexOf("Name", StringComparison.OrdinalIgnoreCase) > -1 )
              .Select(p=>p.Name).First();
    }
}

典型用法如下:

var l = new List<Company> { 
   new Company {Id =1, CompanyName="test"},
   new Company {Id =2, CompanyName="foo"},
   new Company {Id =1, CompanyName="bar"}
};

var sl = new SelectListAuto<Company>(l);

另一个选择是使用属性装饰模型类:

public class Company
{
  [Value]
  public int Id { get;set;}
  [Text]
  public string CompanyName {get;set;}
}

// CustomAttribute
public class Value:Attribute {}

SelectListAuto我们会选择具有Customattribute的属性,如下所示:

static string GetId(Type t) {
   // you can have all kind logic to autowire up, ie use some convention
   t.GetProperties().Select(p => p.CustomAttributes).Dump();
   return t.GetProperties()
          .Where(p => p.Name
                      .Equals("Id",StringComparison.OrdinalIgnoreCase) ||
                      p.CustomAttributes.Any(ca => ca.AttributeType == typeof(Value)) 
   ).Select(p=>p.Name).First();
}

答案 1 :(得分:0)

MyViewModelVM.Companies = new SelectList(companies , "Id", "CompanyName");

其余代码:

public class MyViewModelVM
{
    public SelectList Companies { get; set; }
}

MyEntities myEntities = new MyEntities();
List<Company> companies = myEntities.Companies.ToList();

SelectList compList = new SelectList()
foreach(var item in companies)
{
   complist.Add(item[0], item[1]); //please take care of the proper syntax here.
  //or
   complist.Add(item.items[0], item.items[1].toString());

  //but this way you can add without hardcoding field names
}