Это потребует изменения в вашем перечислении DayOfWeek, но я предпочитаю делать это как флаг (менее грязный, только одно значение и т. Д.). Интересно, что Microsoft также использует дни недели в документации enum flags .
Перечисление DayOfWeek с использованием битовых флагов:
[Flags]//<-- Note the Flags attribute
public enum DayOfWeek
{
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64,
}
Модель:
public class Document
{
public string Name { get; set;}
//Note that WeekDays is no longer a collection.
public DayOfWeek WeekDays { get; set; }
}
Вид:
<% foreach(DayOfWeek dayOfWeek in Enum.GetValues(typeof(DayOfWeek))) { %>
<label>
<!-- The HasFlag stuff is optional and is just there to show how it would be populated if you're doing a `GET` request. -->
<input type="checkbox" name="WeekDays[]" value="<%= (int)dayOfWeek%>" <%= Model.WeekDays.HasFlag(dayOfWeek) ? "checked='checked'" : "" %>" />
<%= dayOfWeek %>
</label>
<% } %>
Контроллер:
[HttpPost]
public ActionResult MyPostedPage(MyModel model)
{
//I moved the logic for setting this into a helper because this could be re-used elsewhere.
model.WeekDays = Enum<DayOfWeek>.ParseToEnumFlag(Request.Form, "WeekDays[]");
...
}
Быстрый помощник для ParseToEnumFlag:
public static class Enum<T>
{
public static T ParseToEnumFlag(NameValueCollection source, string formKey)
{
//MVC 'helpfully' parses the checkbox into a comma-delimited list. We pull that out and sum the values after parsing it back into the enum.
return (T)Enum.ToObject(typeof(T), source.Get(formKey).ToIEnumerable<int>(',').Sum());
}
}
Справка:
Причина, по которой значения флагов перечисления находятся в геометрическом ряду ( 1,2,4,8 ... ), заключается в том, что при сложении значений существует только одна возможная комбинация. Например, мы бы знали, что 31
могут быть только Пн, Вт, Ср, Тур и Пт (1 + 2 + 4 + 8 + 16).
Обновление - 3 сентября 2012
Кажется, я пропустил ToIEnumerable (), который является расширением в нашем исходном коде. Он принимает строку с разделителями и преобразует ее в IEnumerable, поэтому он идеально подходит для чисел с разделителями-запятыми. Спасибо @ escist за заголовок.
public static IEnumerable<T> ToIEnumerable<T>(this string source, char delimiter)
{
return source.Split(new char[] { delimiter }, StringSplitOptions.RemoveEmptyEntries).Select(x => (T)Convert.ChangeType(x, typeof(T)));
}