ASP.NET Core 8.0中如何在EditorTemplate获取模型容器?
解决ASP.NET Core 8.0 EditorTemplate中获取模型容器的问题
在ASP.NET Core中,原.NET Framework里的ViewData.ModelMetadata.Container属性已被移除,想要获取模型容器实例,不能通过创建新的ModelExplorer实现,需获取当前绑定的ModelExplorer并访问其Parent属性。
修正后的EditorTemplate核心代码
// 获取当前属性标记的MediaPickerAttribute var attribute = ViewData.ModelMetadata.ContainerType .GetProperty(ViewData.ModelMetadata.PropertyName) .GetCustomAttributes(typeof(MediaPickerAttribute), false) .Cast<MediaPickerAttribute>() .FirstOrDefault(); // 获取容器模型实例(MediaEditDto对象) var currentExplorer = ViewData.ModelMetadata.GetExplorer(ViewContext); object container = currentExplorer.Parent.Model; List<MediaDTO> valueObject = new List<MediaDTO>(); if (attribute?.SelectedValuesProperty != null) { valueObject = ViewData.ModelMetadata.ContainerType .GetProperty(attribute.SelectedValuesProperty) .GetValue(container) as List<MediaDTO>; }
关键要点
- 正确获取ModelExplorer:通过
ViewData.ModelMetadata.GetExplorer(ViewContext)拿到当前绑定的ModelExplorer,它的Parent属性对应容器模型的ModelExplorer,取Model即可得到MediaEditDto实例。你之前创建新ModelExplorer的方式会丢失父级关联,导致返回null。 - 空值安全处理:添加
attribute?.SelectedValuesProperty的空值判断,避免空引用异常。 - 代码优化:用
Cast<MediaPickerAttribute>替代Select(a => a as MediaPickerAttribute),简化类型转换逻辑。
额外代码修正
- 容器模型
MediaEditDto:初始化语句缺少括号,修正为:
public class MediaEditDto { // 其他属性... [MediaPicker(SelectedValuesProperty = nameof(RelatedMedia), Multiple = true, YoutubeAllowed = false)] [Display(Name = nameof(Resources.Photo.RelatedMedia), ResourceType = typeof(Resources.Photo))] public List<Guid>? PhotosIds { get; set; } public List<MediaDTO>? RelatedMedia { get; set; } = new List<MediaDTO>(); // 补全括号 }
- 编辑视图
Edit.cshtml:Html.EditorFor需添加@符号:
<div class="row"> <div class="form-group "> <label asp-for="Dto.PhotosIds" class="col-sm-3 control-label"></label> <div class="col-md-9"> @Html.EditorFor(model => model.Dto.PhotosIds) <!-- 添加@ --> <span asp-validation-for="Dto.PhotosIds" class="text-danger has-error help-block"></span> </div> </div> </div>
内容的提问来源于stack exchange,提问作者Jerzy P
相关产品推荐
相关产品推荐

