model-view-controller - dotnet core 中多个局部视图的模型绑定
问题描述
我想根据具有不同模型绑定的模型类型,使用一个通用局部视图和其他多个局部视图来设计通用模型绑定。
我有一个基本对话模型和两个派生模型。
public class DialogModel
{
public int DialogType { get; set; }
public string ViewName { get; set; }
}
public class DialogModel1: DialogModel
{
}
public class DialogModel2: DialogModel
{
}
我有一种操作方法,我正在发布基于模型类型的 JSON 数据。
public IActionResult OpenDialog(DialogModel model)
{
string view = string.Empty;
switch (model.DialogType)
{
case 1:
model.View = "MyDialogPartialView1";
DialogModel1 model1 = (DialogModel1)model;
//mode1 properties set;
view = this.RenderViewAsync("CommonDialogPartialView", model1, true).Result;
break;
case 2:
model.View = "MyDialogPartialView2";
DialogModel2 model2 = (DialogModel2)model;
//mode2 properties set;
view = this.RenderViewAsync("CommonDialogPartialView", model2, true).Result;
break;
default:
break;
}
return new JsonResult(new { view });
}
我正在根据对话框类型设置局部视图的视图名称并将其转换为相关模型并呈现公共局部视图“CommonDialogPartialView”并返回响应文本。
我在客户端附加了这个响应文本。
我常见的部分视图 HTML。
@model ChurchPharmacy3.Models.DialogModel
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content" id="popup_body">
<div class="modal-header bg-info">
<h5 class="modal-title" id="exampleModalLongTitle">@Model.Title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
@await Html.PartialAsync(Model.View)
<!--This partial view can be "MyDialogPartialView1" or "MyDialogPartialView2" -->
</div>
<div class="modal-footer bg-light">
<button type="button" class="btn btn-secondary">Cancel</button>
<button type="button" class="btn btn-primary">Ok</button>
</div>
</div>
</div>
这个通用的局部视图获取 DialogModel 的模型,我正在根据视图名称从通用局部视图渲染另一个局部视图。
这是我对 Dialog type 1 的部分看法。
@model ChurchPharmacy3.Models.DialogModel1
<!--Model of DialogModel1-->
对于 Dialog 类型 2 的部分视图也是如此。
@model ChurchPharmacy3.Models.DialogModel2
<!--Model of DialogModel1-->
当我将模型转换为 DialogModel1 或 DialogModel2 时,它会引发异常。
解决方案
我已经使用 IModelBinder 并且能够解决上述问题。
这是上述问题的解决方案。
public class DialogModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException(nameof(bindingContext));
JObject jObject = null;
using (StreamReader reader = new StreamReader(bindingContext.ActionContext.HttpContext.Request.Body))
{
using (var jsonReader = new JsonTextReader(reader))
{
jObject = JObject.LoadAsync(jsonReader).Result;
}
}
var modelType = (int)jObject.SelectToken("dialogType");
if (modelType == (byte)DialogType.Dialog1)
{
var obj = DeserializeObject<Dialog1>(jObject.ToString());
bindingContext.Result = ModelBindingResult.Success(obj);
}
if (modelType == (byte)DialogType.Dialog1)
{
var obj = DeserializeObject<Dialog2>(jObject.ToString());
bindingContext.Result = ModelBindingResult.Success(obj);
}
else
{
var obj = DeserializeObject<DialogModel>(jObject.ToString());
bindingContext.Result = ModelBindingResult.Success(obj);
}
return Task.CompletedTask;
}
private static T DeserializeObject<T>(string json)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json, new Newtonsoft.Json.JsonSerializerSettings
{
TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto
});
}
}
推荐阅读
- excel - 从 Excel 创建 Outlook 约会(Office 2013 和 Office 2016)
- java - 如何从 Android 依赖项中排除 jar 文件?
- php - 在 woocommerce 变化的下拉菜单中显示价格
- jquery - 如何使用数据表插件按日期(从最旧到最新)排序列
- php - 使用另一个数组创建新的唯一数组
- ionic-framework - 离子存储:奇怪的行为?
- ruby-on-rails - Rails 应用模型中的 ModelName.real
- visual-studio-2015 - 在您的 SSDT 数据库项目中混合服务器数据库和本地数据库
- excel - 添加工作表后,VBA Excel 代码停止执行
- html - 是否允许在单独的影子根中使用重复的 ID?