Dictionary<short, Dictionary<EnFunction, bool>> 模型绑定不起作用
Dictionary<short, Dictionary<EnFunction, bool>> model binding not work
我无法将模型绑定到控制器。请给我任何建议。
模型、控制器和视图 类 如下。提交模型时,字典 属性 等于 null.
public class GroupRights //model
{
public List<DtoGrup> groups { get; set; }
public Dictionary<short, Dictionary<EnFunction, bool>> groupRights { get; set; } // group function HasPermission
}
public enum EnFunction
{
LPDU_login,
LPDU_changePassword,
LPDU_transitList,
LPDU_PosEventList,
....
}
控制器
public ActionResult GroupRights()
{
TocCommonService.CommonServiceClient client = new TocCommonService.CommonServiceClient();
GroupRights gr = new GroupRights();
gr.groups = client.GetAllOperatorGroups().ToList();
gr.groupRights = new Dictionary<short, Dictionary<EnFunction, bool>>();
foreach (var g in gr.groups)
{
Dictionary<EnFunction, bool> permission = new Dictionary<EnFunction, bool>();
foreach (var func in Enum.GetValues(typeof(EnFunction)).Cast<EnFunction>())
{
permission.Add(func, client.hasPermission(new DtoGrup() { GROUPID = g.GROUPID }, func));
}
gr.groupRights.Add(g.GROUPID, permission);
}
return View(gr);
}
查看
@model TocWebApplication.Models.GroupRights
@{
int id = 0;
}
@using (Html.BeginForm("ChangePermissionOfGroup", "Home", FormMethod.Post))
{
<table>
<thead>
<tr>
<th></th>
@foreach (var gr in Model.groups)
{
<th>@gr.GROUPNAME (@gr.GROUPID)</th>
}
</tr>
</thead>
<tbody>
@foreach (var func in Enum.GetValues(typeof(EnFunction)).Cast<EnFunction>())
{
<tr>
<td>@(func.ToString())</td>
@for (int j = 0; j < Model.groups.Count(); j++)
{
<td>@Html.CheckBoxFor(model => model.groupRights[Model.groups[j].GROUPID][func])</td>
}
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-primary">Save changes</button>
<button class="btn">Cancel</button>
}
对于 Key
和 Value
都是简单值类型(例如 Dictionary<string, bool>
)的所有词典,DefaultModelBinder
需要 name/value属性的格式(在您的情况下)
<input name="groupRights[0].Key" value="1" ... />
<input name="groupRights[0].Value[0].Key" value="LPDU_login" ... />
<input name="groupRights[0].Value[0].Value" value="True" ... />
<input name="groupRights[1].Key" value="2" ... />
<input name="groupRights[1].Value[0].Key" value="LPDU_changePassword" ... />
<input name="groupRights[1].Value[0].Value" value="False" ... />
没有 HtmlHelper
方法可以生成正确的属性并绑定到您的 groupRights
,您需要手动生成 html。
相反,创建一个视图模型来表示您想要在 view.If 中显示的数据我已经正确解释了这一点,您想要显示一个 table 显示每个 EnFunction
值向下,每个 DtoGrup
跨越,并在每个单元格中显示一个复选框以确定为每个 DtoGrup
.
选择哪个 EnFunction
public class GroupRightsVM // represents a table cell
{
public short GroupID { get; set; }
public bool IsSelected { get; set; }
}
public class RightsVM // represents a table row
{
public RightsVM()
{
Groups = new List<GroupRightsVM>()
}
public EnFunction Right { get; set; }
public List<GroupRightsVM> Groups { get; set; } // represents the cells in a row
}
public class PermissionsVM // Represents the table
{
public PermissionsVM()
{
Permissions = new List<RightsVM>()
}
public IEnumerable<string> Headings { get; set; } // represents the table headings
public List<RightsVM> Permissions { get; set; } // represents all rows
}
并在视图中
<thead>
<tr>
<th></th>
@foreach(var heading in Model.Headings)
{
<th>@heading</th>
}
</tr>
</thead>
<tbody>
@for(int i = 0; i < Model.Rows.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(m => m.Permissions[i].Right)
@Html.DisplayFor(m => m.Permissions[i].Right)
</td>
@for(int j = 0; j < Model.Permissions[i].Groups.Count; j++)
{
<td>
@Html.HiddenFor(m => m.Permissions[i].Groups[j].GroupID)
@Html.CheckboxFor(m => m.Permissions[i].Groups[j].IsSelected)
</td>
}
</tr>
}
</tbody>
在 GET 方法中,初始化 PermissionsVM
的实例并根据您的数据模型填充它并将其传递给视图,例如
var groups = client.GetAllOperatorGroups()
var model = new PermissionsVM();
model.Headings = groups.Select(x => String.Format("{0} {{1})", x.GROUPNAME, x.GROUPID));
foreach (var func in Enum.GetValues(typeof(EnFunction)).Cast<EnFunction>())
{
RightsVM r = new RightsVM();
r.Right = func;
foreach (var g in groups)
{
GroupRightsVM gr = new GroupRightsVM();
gr.GroupID = g.GROUPID;
gr.IsSelected = ...
r.Groups.Add(gr);
}
model.Persmissions.Add(r);
}
return View(model);
并且在POST方法中
public ActionResult GroupRights(PermissionsVM model)
我无法将模型绑定到控制器。请给我任何建议。 模型、控制器和视图 类 如下。提交模型时,字典 属性 等于 null.
public class GroupRights //model
{
public List<DtoGrup> groups { get; set; }
public Dictionary<short, Dictionary<EnFunction, bool>> groupRights { get; set; } // group function HasPermission
}
public enum EnFunction
{
LPDU_login,
LPDU_changePassword,
LPDU_transitList,
LPDU_PosEventList,
....
}
控制器
public ActionResult GroupRights()
{
TocCommonService.CommonServiceClient client = new TocCommonService.CommonServiceClient();
GroupRights gr = new GroupRights();
gr.groups = client.GetAllOperatorGroups().ToList();
gr.groupRights = new Dictionary<short, Dictionary<EnFunction, bool>>();
foreach (var g in gr.groups)
{
Dictionary<EnFunction, bool> permission = new Dictionary<EnFunction, bool>();
foreach (var func in Enum.GetValues(typeof(EnFunction)).Cast<EnFunction>())
{
permission.Add(func, client.hasPermission(new DtoGrup() { GROUPID = g.GROUPID }, func));
}
gr.groupRights.Add(g.GROUPID, permission);
}
return View(gr);
}
查看
@model TocWebApplication.Models.GroupRights
@{
int id = 0;
}
@using (Html.BeginForm("ChangePermissionOfGroup", "Home", FormMethod.Post))
{
<table>
<thead>
<tr>
<th></th>
@foreach (var gr in Model.groups)
{
<th>@gr.GROUPNAME (@gr.GROUPID)</th>
}
</tr>
</thead>
<tbody>
@foreach (var func in Enum.GetValues(typeof(EnFunction)).Cast<EnFunction>())
{
<tr>
<td>@(func.ToString())</td>
@for (int j = 0; j < Model.groups.Count(); j++)
{
<td>@Html.CheckBoxFor(model => model.groupRights[Model.groups[j].GROUPID][func])</td>
}
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-primary">Save changes</button>
<button class="btn">Cancel</button>
}
对于 Key
和 Value
都是简单值类型(例如 Dictionary<string, bool>
)的所有词典,DefaultModelBinder
需要 name/value属性的格式(在您的情况下)
<input name="groupRights[0].Key" value="1" ... />
<input name="groupRights[0].Value[0].Key" value="LPDU_login" ... />
<input name="groupRights[0].Value[0].Value" value="True" ... />
<input name="groupRights[1].Key" value="2" ... />
<input name="groupRights[1].Value[0].Key" value="LPDU_changePassword" ... />
<input name="groupRights[1].Value[0].Value" value="False" ... />
没有 HtmlHelper
方法可以生成正确的属性并绑定到您的 groupRights
,您需要手动生成 html。
相反,创建一个视图模型来表示您想要在 view.If 中显示的数据我已经正确解释了这一点,您想要显示一个 table 显示每个 EnFunction
值向下,每个 DtoGrup
跨越,并在每个单元格中显示一个复选框以确定为每个 DtoGrup
.
EnFunction
public class GroupRightsVM // represents a table cell
{
public short GroupID { get; set; }
public bool IsSelected { get; set; }
}
public class RightsVM // represents a table row
{
public RightsVM()
{
Groups = new List<GroupRightsVM>()
}
public EnFunction Right { get; set; }
public List<GroupRightsVM> Groups { get; set; } // represents the cells in a row
}
public class PermissionsVM // Represents the table
{
public PermissionsVM()
{
Permissions = new List<RightsVM>()
}
public IEnumerable<string> Headings { get; set; } // represents the table headings
public List<RightsVM> Permissions { get; set; } // represents all rows
}
并在视图中
<thead>
<tr>
<th></th>
@foreach(var heading in Model.Headings)
{
<th>@heading</th>
}
</tr>
</thead>
<tbody>
@for(int i = 0; i < Model.Rows.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(m => m.Permissions[i].Right)
@Html.DisplayFor(m => m.Permissions[i].Right)
</td>
@for(int j = 0; j < Model.Permissions[i].Groups.Count; j++)
{
<td>
@Html.HiddenFor(m => m.Permissions[i].Groups[j].GroupID)
@Html.CheckboxFor(m => m.Permissions[i].Groups[j].IsSelected)
</td>
}
</tr>
}
</tbody>
在 GET 方法中,初始化 PermissionsVM
的实例并根据您的数据模型填充它并将其传递给视图,例如
var groups = client.GetAllOperatorGroups()
var model = new PermissionsVM();
model.Headings = groups.Select(x => String.Format("{0} {{1})", x.GROUPNAME, x.GROUPID));
foreach (var func in Enum.GetValues(typeof(EnFunction)).Cast<EnFunction>())
{
RightsVM r = new RightsVM();
r.Right = func;
foreach (var g in groups)
{
GroupRightsVM gr = new GroupRightsVM();
gr.GroupID = g.GROUPID;
gr.IsSelected = ...
r.Groups.Add(gr);
}
model.Persmissions.Add(r);
}
return View(model);
并且在POST方法中
public ActionResult GroupRights(PermissionsVM model)