任何人都可以告诉我为什么,如果我的模型清楚地表明我的价值观是“真实”或“虚假”MVC仍然认为它说“真,假”。我认为这是因为它使Request与我的模型混淆;但是,我明确告诉它使用模型。
如上图所示,模型值为“true”。但是,在下图中,它认为值是“真,假”。我怎样才能使用“true?”
模型
public class TagCategorySearchViewModel
{
public long Id { get; set; }
public string Name { get; set; }
public List<TagSearchViewModel> Tags { get; set; }
}
public class TagSearchViewModel
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
控制器
[Authorize]
public ActionResult FilterPrereqGrid(EditStudentPrerequisitesViewModel model, int page = 1)
{
model.Prerequisites = new List<PrerequisiteListViewModel>();
var businessPartner = _bpManager.GetBusinessPartnerByMapGuid(model.BusinessPartnerMapGuid);
model.Prerequisites.AddRange(_epManager.GetFullPrerequisitesLeftJoinedWithExperience(model.ExperienceId, businessPartner?.Id));
// fix for how MVC binds checkboxes... it send "true,false" instead of just true, so we need to just get the true
for (int i = 0; i < model.TagCategories?.Count(); i++)
{
for (int j = 0; j < model.TagCategories[i].Tags?.Count(); j++)
{
model.TagCategories[i].Tags[j].IsSelected = bool.Parse((Request.QueryString[$"TagCategories[{i}].Tags[{j}].IsSelected"] ?? "false").Split(',')[0]);
}
}
var selectedTagIds = model.TagCategories?.SelectMany(x => x.Tags).Where(x => x.IsSelected == true).Select(x => x.Id).ToArray();
// filter by selected tags
if (selectedTagIds.Any())
{
model.Prerequisites = (from p in model.Prerequisites
let prereqTagIds = p.Prerequisite.PrerequisiteTags.Select(et => et.TagId)
where selectedTagIds.All(x => prereqTagIds.Contains(x))
select p).ToList();
}
model.Prerequisites = (from m in model.Prerequisites
let ownerDocs = _deManager.GetDocumentsByOwnerAndSourceId(model.BusinessPartnerMapGuid, m.Prerequisite.Id).OrderByDescending(e => e.CreatedDate)
select new PrerequisiteListViewModel
{
Prerequisite = m.Prerequisite,
Selected = m.Selected,
Mandatory = m.Mandatory,
HasExpiration = m.Prerequisite.HasExpiration,
BusinessExpirationPeriod = m.Prerequisite.ExpirationPeriod == 0 ? "None" : m.Prerequisite.ExpirationPeriod.ToString(),
DocOwnerGuid = (ownerDocs.Any() ? model.BusinessPartnerMapGuid : Guid.Empty),
DocRowGuid = (ownerDocs.Any() ? ownerDocs.First().DocRowguid : Guid.Empty),
HasDocuments = ownerDocs.Any()
}).ToList();
int rowsPerPage = 1;
model.TotalRecords = model.Prerequisites.Count();
model.Prerequisites = model.Prerequisites.Skip(page * rowsPerPage - rowsPerPage).Take(rowsPerPage).ToList();
return PartialView("~/Views/BusinessExperience/_EditPrerequisites.cshtml", model);
}
答案 0 :(得分:2)
这是设计上的。 Html.CheckBoxFor
扩展程序实际上呈现如下内容:
<input type="checkbox" .. />
<input type="hidden" />
因此,这两个都与您渲染的属性具有相同的名称。选中后,复选框返回&#34; True&#34;,但如果未选中,则复选框不返回任何内容。这是复选框与表单帖子一起使用的方式。为了确定没有检查任何内容,MVC框架包含一个隐藏字段,以便返回&#34; False&#34;什么时候不检查,但是&#34;真,假&#34;检查时(因为具有相同名称的多个项目从表单帖子以这种方式返回)。然后MVC模型绑定转换&#34; True,False&#34;为真。
您可以使用值true呈现自己的<input type="checkbox" />
,并且只返回true,但如果未选中,则不会呈现任何内容。请注意......
答案 1 :(得分:0)
这实际上有效,遗憾的是我不能只做明显的方式而且必须写出这一切!
@model List<Prep2PracticeWeb.Models.ViewModels.TagCategorySearchViewModel>
@if (Model != null)
{
<div class="tag-categories">
@for (int i = 0; i < Model.Count(); i++)
{
@Html.HiddenFor(x => Model[i].Id)
@Html.HiddenFor(x => Model[i].Name)
<h4 data-toggle="collapse" data-target="#CollapsableTagCategory_@Model[i].Id" aria-expanded="false" aria-controls="CollapsableTagCategory_@Model[i].Id">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="glyphicon glyphicon-chevron-down"></span>
@Model[i].Name
</h4>
<div id="CollapsableTagCategory_@Model[i].Id" class="tag-container collapse">
@if (Model[i].Tags != null)
{
for (int j = 0; j < Model[i].Tags.Count(); j++)
{
@Html.HiddenFor(x => Model[i].Tags[j].Id)
@Html.HiddenFor(x => Model[i].Tags[j].Name)
@* the following commented out line won't work because MVC is funny *@
@*<label>@Html.CheckBoxFor(x => Model[i].Tags[j].IsSelected) @Model[i].Tags[j].Name</label>*@
<label>
<input @(Model[i].Tags[j].IsSelected ? @"checked=""checked""" : string.Empty) data-val="true" data-val-required="The IsSelected field is required." id="TagCategories_@(i)__Tags_@(j)__IsSelected" name="TagCategories[@i].Tags[@j].IsSelected" type="checkbox" value="true"> @Model[i].Tags[j].Name
<input name="TagCategories[@i].Tags[@j].IsSelected" type="hidden" value="false">
</label>
}
}
</div>
}
</div>
}
更新:我意识到GET在这种情况下不是一个合适的策略,因为查询字符串只能在服务器返回500错误之前很久。我切换到POST,这缓解了这个问题。