这将需要更改您的 DayOfWeek 枚举,但我更喜欢将其作为一个标志(不那么混乱,只有一个值等)。有趣的是,微软还在他们的enum flags documentation 中使用了一周中的几天。
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)。
更新 - 2012 年 9 月 3 日
看来我错过了 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)));
}