张贴清单 .net核心1.0
我在.net核心中构建了一个动态表单创建器。一个“表单”将包含许多不同的表单元素。所以表格模型将是这个样子:张贴清单<Interface> .net核心1.0
public class FormModel {
public string FormName {get;set;}
public List<IElements> Elements{get;set;}
}
我有类TextBoxElement
,TextAreaElement
,CheckBoxElement
全部实现IElemets
接口。我有每个元素EditorTemplates
。用于渲染表单的代码很有用。尽管张贴表单不起作用,因为接口的List
。
我一直在寻找如何实现自定义模型联编程序,并在网络上看到一些例子,但我没有得到任何人的工作。
如果有人能告诉我如何为本示例实现自定义模型联编程序,我将不胜感激。
B计划: 将表单作为json发布到web api并让JSON.Net将其隐藏。我已经尝试过,它的工作。在startup.cs我补充说:
services.AddMvc().AddJsonOptions(opts => opts.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto);
它返回类型,当它必须,例如。元素列表中的对象,但不在FormModel上。但我真的很想知道如何用自定义模型绑定器来解决它。
好的,这对我很有用。我仍然在处理新的模型绑定,所以我可能会做一些愚蠢的事情,但这是一个开始!
TEST FORM
<form method="post">
<input type="hidden" name="Elements[0].Value" value="Hello" />
<input type="hidden" name="Elements[0].Type" value="InterfacePost.Model.Textbox" />
<input type="hidden" name="Elements[1].Value" value="World" />
<input type="hidden" name="Elements[1].Type" value="InterfacePost.Model.Textbox" />
<input type="hidden" name="Elements[2].Value" value="True" />
<input type="hidden" name="Elements[2].Type" value="InterfacePost.Model.Checkbox" />
<input type="submit" value="Submit" />
</form>
INTERFACE
public interface IElement
{
string Value { get; set; }
}
TEXTBOX实施
public class Textbox : IElement
{
public string Value { get; set; }
}
CHECKBOX实施
public class Checkbox : IElement
{
public string Value { get; set; }
}
模型绑定PROVIDER
public class ModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(IElement))
{
return new ElementBinder();
}
// else...
return null;
}
}
模型绑定
public class ElementBinder : IModelBinder
{
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(IElement))
{
var type = bindingContext.ValueProvider.GetValue($"{bindingContext.ModelName}.Type").FirstValue;
if (!String.IsNullOrWhiteSpace(type))
{
var element = Activator.CreateInstance(Type.GetType(type)) as IElement;
element.Value = bindingContext.ValueProvider.GetValue($"{bindingContext.ModelName}.Value").FirstValue;
bindingContext.Result = ModelBindingResult.Success(element);
}
}
}
}
HOOK UP模型绑定PROVIDER
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.ModelBinderProviders.Insert(0, new ModelBinderProvider());
});
}
}
FORM MODEL
public class FormModel
{
public string FormName { get; set; } // Not using this
public List<IElement> Elements { get; set; }
}
ACTION
请注意三种类型,即文本框,文本框和复选框。
我试过这个例子。 bindingContext.ValueProvider.GetValue返回null bindingContext.ModelName是一个空字符串 –
没关系我错过了html中的name =“Elements [0] .Type” –
模型绑定怎么知道实例张贴在列表中的元素哪些类型? – Lucero
不知道为什么有人投这个票。我想你将不得不发布一些额外的信息,让你的自定义模型联编程序知道什么类的实例化。 –
我认为JSON。NET可以通过序列化/反序列化类型名称来处理类型。如果您使用JSON,那么也许您可以利用一些方法。 –