最终目标是从我的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} },BlockType
,Name
和Height
属性已按预期列出。
它们在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>
答案 0 :(得分:0)
您的select元素似乎未呈现该元素的name
。没有name
属性,数据将无法与模型中的适当属性匹配。
您只需在浏览器中编辑HTML并在选择的输入中添加属性name="BlockType"
,然后尝试发布表单以查看其是否有效,即可对其进行仔细检查。