为什么没有在我的mvc项目中序列化此属性?

时间:2019-02-01 20:18:53

标签: c# asp.net-mvc json-deserialization

最终目标是从我的abstract中序列化一个View类型,以供我的Controller使用。

我的抽象类型具有enum属性,其名称与具体派生类型的名称相对应;这就是我确定选择哪种具体类型的方式。 enum的值通过反射在抽象类型的构造函数中设置:

[JsonConverter(typeof(BlockJsonConverter)]
public abstract class Block{

   [NotMapped, JsonProperty]
   public BlockType BlockType {get; set;}
   public string Name {get;set:}
   public int Height{get;set;}
   public int Width {get;set;}
   public int Depth {get;set;}

   protected Block(){
      BlockType = Enum.TryParse(GetType().Name, out BlockType blocktype)
             ?? blocktype : BlockType.Unknown
   }
}

public enum BlockType {
   Long, Short, Tall, Unknown
}

public class Long    : Block { /*...*/ }
public class Short   : Block { /*...*/ }
public class Tall    : Block { /*...*/ }
public class Unknown : Block { /*...*/ }

实体框架使用Block类,但是BlockType属性未存储在数据库中,因此BlockType属性标记为[NotMapped]属性;但是,由于我希望该属性从View到Controller往返,所以我用[JsonProperty]属性对其进行了标记。

我创建了一个TestModelBinder来处理从视图到控制器的反序列化:

public class TestModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, 
       ModelBindingContext bindingContext, Type modelType)
    {
        return base.CreateModel(controllerContext, bindingContext,
            GetModelType(controllerContext, bindingContext, modelType));
    }

    protected override ICustomTypeDescriptor GetTypeDescriptor(
      ControllerContext controllerContext,ModelBindingContext bindingContext)
    {
        var modelType = GetModelType(controllerContext, bindingContext, bindingContext.ModelType);
        return new AssociatedMetadataTypeTypeDescriptionProvider(modelType)
                      .GetTypeDescriptor(modelType);
    }

    private static Type GetModelType(ControllerContext controllerContext, ModelBindingContext bindingContext,
        Type modelType)
    {
        if (modelType.Name == "Block")
        {
• breakpoint
           // get the value from bindingContext for BlockType
           // and return the concrete type based on that
        }
        return modelType;
    }
}

当我碰到上面的断点时,bindingContext属性的BlockType中没有ValueProvider.FormValueProvider,而{{1} },BlockTypeNameHeight属性已按预期列出。

它们在EditorTemplate中的列出方式相同:

Width

...和Depth帮助器仅生成常规标签,基于类型(枚举,字符串等)的编辑器和验证消息。枚举的EditorTemplate如下:

@model Block
<div class="form-row">
    <div class="col">
        @Html.BootstrapEditorGroupFor(m => m.Name)
    </div>        
    <div class="col">
        @Html.BootstrapEditorGroupFor(m => m.BlockType)
    </div>
</div>
<div class="form-row">
    <div class="col">
        @Html.BootstrapEditorGroupFor(m => m.Height)
    </div>
    <div class="col">
        @Html.BootstrapEditorGroupFor(m => m.Width)
    </div>
    <div class="col">
        @Html.BootstrapEditorGroupFor(m => m.Depth)
    </div>
</div>

1 个答案:

答案 0 :(得分:0)

您的select元素似乎未呈现该元素的name。没有name属性,数据将无法与模型中的适当属性匹配。 您只需在浏览器中编辑HTML并在选择的输入中添加属性name="BlockType",然后尝试发布表单以查看其是否有效,即可对其进行仔细检查。