Model view controller dotnet core中多个局部视图的模型绑定

Model view controller dotnet core中多个局部视图的模型绑定,model-view-controller,.net-core,imodelbinder,Model View Controller,.net Core,Imodelbinder,我想使用一个公共局部视图和其他多个基于不同模型绑定的模型类型的局部视图来设计公共模型绑定 我有一个基本对话框模型和两个派生模型 public class DialogModel { public int DialogType { get; set; } public string ViewName { get; set; } } public class DialogModel1: DialogModel { } public class DialogModel2: Di

我想使用一个公共局部视图和其他多个基于不同模型绑定的模型类型的局部视图来设计公共模型绑定

我有一个基本对话框模型和两个派生模型

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>
@model.cy3.Models.DialogModel
@模型名称
&时代;
@等待Html.partialSync(Model.View)
取消
好啊
这个公共局部视图获取DialogModel的模型,我正在基于视图名称从公共局部视图渲染另一个局部视图

这是我的对话框类型1的局部视图

 @model ChurchPharmacy3.Models.DialogModel1
<!--Model of DialogModel1-->
@model.cy3.Models.DialogModel1
对话框类型2的局部视图也是如此

@model ChurchPharmacy3.Models.DialogModel2
<!--Model of DialogModel1-->
@model.cy3.Models.DialogModel2

当我将模型强制转换为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
        });
    }

}
以下是上述问题的解决方案

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
        });
    }

}
public类DialogModelBinder:IModelBinder
{
公共任务BindModelAsync(ModelBindingContext bindingContext)
{
if(bindingContext==null)
抛出新ArgumentNullException(nameof(bindingContext));
JObject=null;
使用(StreamReader=newstreamreader(bindingContext.ActionContext.HttpContext.Request.Body))
{
使用(var jsonReader=newjsontextreader(reader))
{
jObject=jObject.LoadAsync(jsonReader.Result);
}
}
var modelType=(int)jObject.SelectToken(“dialogType”);
if(modelType==(字节)DialogType.Dialog1)
{
var obj=反序列化对象(jObject.ToString());
bindingContext.Result=ModelBindingResult.Success(obj);
}
if(modelType==(字节)DialogType.Dialog1)
{
var obj=反序列化对象(jObject.ToString());
bindingContext.Result=ModelBindingResult.Success(obj);
}
其他的
{
var obj=反序列化对象(jObject.ToString());
bindingContext.Result=ModelBindingResult.Success(obj);
}
返回Task.CompletedTask;
}
私有静态T反序列化对象(字符串json)
{
返回Newtonsoft.Json.JsonConvert.DeserializeObject(Json,新的Newtonsoft.Json.JsonSerializerSettings
{
TypeNameHandling=Newtonsoft.Json.TypeNameHandling.Auto
});
}
}