模型绑定和继承ASP MVC 5

尼基塔

基类:AbstractBuildBlock,派生:TextBlock,ImageBlock,EmptyBlock等。

在这里阻止:网站->页面[someIndex]->行[someIndex]-> BuildBlocks

字段BuildBlocks的类型为AbstractBuildBlock,因此,当我将站点保存到BuildBlocks中的DB时,每个记录都有一个描述符AbstractBuildBlock。我尝试在BuildBlockRepository中执行下一个操作:

    switch(obj.ContentType)
            {
                case "text":
                    obj = obj as TextBlock;
                    context.BuildBlocks.Add(obj);
                    break;
            }

之后obj = obj as TextBlock objnull原因是obj的类型为AbstractBuildBlock。我在msdn上发现此代码应该可以工作:

BaseClass a = new DerivedClass()
DerivedClass b = a as DerivedClass

因此,我需要在模型绑定时重现此代码。这是ajax请求:

$('.saveSite').click(function () {
    $.ajax({
        url: '/Site/Update',
        data: { site: getSite() },
        method: 'POST',
        success: function (data) {
            console.log('Success save');
        },
        error: function (data) {
            debugBox(data);
        }
    });
});

和针对该请求的mvc操作

    public string Update(Site site)
    {
        siteRepository.Add(site);
        return "Success";
    }

因此,我以json形式发送Site,也以json形式发送此站点中的BuildBlocks,但是它们的(块)类型当然不是AbstractBuildBlock,它们都是TextBlock,ImageBlock等,并且具有带值的字段。

问题:站点具有BuildBlocks字段,其类型为AbstractBuildBlock,并且模型绑定程序执行以下操作:

buildBlock = new AbstractBuildBlock(); //loose derived classes fields and posibility to convert it in DerivedClass
buildBlocks.push(buildBlock)

但我需要这样的东西

switch(buildBlock.contenType) {
    case "text" : buildBlock = new TextBlock();buidlBlocks.push(buildBlock);
}
尼基塔

JSON NET自定义反序列化器根本不起作用

ASP MVC 5如何借助JSON NET从请求中读取对象

看一下上面两个链接中的答案,描述了正确的ajax调用

和下面的服务器代码

MVC动作

public string Update(Site site)
    {
        TextBlock block = site.Pages[0].Rows[0].BuildBlocks[0] as TextBlock;
        siteRepository.Add(site);
        return "Success";
    }

我已经在Infrastructure文件夹中创建了AbstractJsonCreationConverter

public abstract class AbstractJsonCreationConverter<T> : JsonConverter
{
    protected abstract T Create(Type objectType, JObject jsonObject);

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
      object existingValue, JsonSerializer serializer)
    {
        var jsonObject = JObject.Load(reader);
        var target = Create(objectType, jsonObject);
        serializer.Populate(jsonObject.CreateReader(), target);
        return target;
    }

    public override void WriteJson(JsonWriter writer, object value,
   JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

并在同一文件夹中的具体类

public class JsonBuildBlockConverter : AbstractJsonCreationConverter<AbstractBuildBlock>
{
    protected override AbstractBuildBlock Create(Type objectType, JObject jsonObject)
    {
        var type = jsonObject["contentType"].ToString();
        switch(type)
        {
            case "text":
                return new TextBlock();
            default:
                return null;
        }
    }
}

还有基础设施的一堂课

internal class SiteModelBinder : System.Web.Mvc.IModelBinder
{
    public object BindModel(ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext)
    {
        // use Json.NET to deserialize the incoming Position
        controllerContext.HttpContext.Request.InputStream.Position = 0; // see: https://stackoverflow.com/a/3468653/331281
        Stream stream = controllerContext.RequestContext.HttpContext.Request.InputStream;
        var readStream = new StreamReader(stream, Encoding.UTF8);
        string json = readStream.ReadToEnd();
        return JsonConvert.DeserializeObject<Site>(json, new JsonBuildBlockConverter());
    }
}

最后一个类是ModelBinder,它将被调用以解析Site类型的变量,要使其正常工作,您需要在ApplicationStart()中的Global.asax.cs中注册它。

 protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        ModelBinders.Binders.Add(typeof(Site), new SiteModelBinder()); //RegisterModelBinder for Site
    }

这是所有的了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ASP.NET MVC 5模型绑定编辑视图

来自分类Dev

ASP.NET MVC 5模型绑定不起作用

来自分类Dev

ASP.NET MVC 5模型绑定列表为空

来自分类Dev

ASP.NET MVC 5模型绑定列表为空

来自分类Dev

继承的类和剃刀 asp.net mvc 5

来自分类Dev

ASP.NET MVC 5 ViewModel绑定

来自分类Dev

ASP.NET MVC 5模型绑定多个JSON对象(knockoutjs)

来自分类Dev

ASP.NET MVC 5-JSON-(动态?)模型绑定-REST服务-Webhooks-Chargebee

来自分类Dev

如何从ASP.NET MVC5中的JSON绑定模型中的属性

来自分类Dev

Asp.Net MVC 5模型状态

来自分类Dev

MVC5 Ninject绑定和HttpContext

来自分类Dev

MVC5 Ninject绑定和HttpContext

来自分类Dev

MVC5 Azure Blob 和模型

来自分类Dev

Json和ASP.NET MVC模型绑定

来自分类Dev

MVC和剔除模型绑定

来自分类Dev

MVC5 RadioButtonFor模型属性未正确绑定

来自分类Dev

MVC5模型绑定-子对象全为空

来自分类Dev

MVC 5-MultiSelectList,使用模型“ SelectList”属性绑定值

来自分类Dev

MVC5绑定问题

来自分类Dev

ASP.NET 5和MVC的目的

来自分类Dev

从Asp.NET MVC 5中的Controller继承

来自分类Dev

具有继承,嵌套viewModels和部分视图的MVC Complex模型绑定

来自分类Dev

ASP MVC 5测试RedirectToAction

来自分类Dev

asp.net 5 MVC 6模型问题

来自分类Dev

使用模型优先的ASP.NET MVC 5身份

来自分类Dev

如何从ASP.NET MVC 5中的模型创建表单?

来自分类Dev

ASP.NET MVC 5中的模型错误

来自分类Dev

ASP.NET MVC 5模型导航属性错误

来自分类Dev

为什么表单不提交与ASP.NET MVC 5中的模型。(另一个模型绑定错误)