首页 > 解决方案 > 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">&times;</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 时,它会引发异常。

标签: model-view-controller.net-coreimodelbinder

解决方案


我已经使用 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
        });
    }

}

推荐阅读