Post 一个列表<Interface> .net 核心 1.0
Post a List<Interface> .net core 1.0
我正在 .net 核心中构建一个动态表单创建器。 "form" 将包含许多不同的表单元素。所以表单模型看起来像这样:
public class FormModel {
public string FormName {get;set;}
public List<IElements> Elements{get;set;}
}
我有 类 用于 TextBoxElement
、TextAreaElement
、CheckBoxElement
,它们都实现了 IElemets
接口。每个元素都有 EditorTemplates
。呈现表单的代码效果很好。尽管由于接口的 List
而无法发布表单。
我一直在寻找如何实现自定义模型联编程序,并在网上看到了一些示例,但我没有让任何人工作。
如果有人能告诉我如何为此示例实现自定义模型绑定器,我将不胜感激。
B计划:
Post 形式为 json 到网络 api 并让 JSON.Net 隐藏它。我试过了,它奏效了。在 startup.cs 中我添加了:
services.AddMvc().AddJsonOptions(opts => opts.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto);
它 returns 在必须时键入,例如。元素列表中但不在 FormModel 中的对象。但我真的很想知道如何使用自定义模型活页夹来解决它。
好的,这对我有用。我仍在掌握新的模型绑定,所以我可能做了一些愚蠢的事情,但这是一个开始!
测试表格
<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>
界面
public interface IElement
{
string Value { get; set; }
}
文本框实现
public class Textbox : IElement
{
public string Value { get; set; }
}
复选框实现
public class Checkbox : IElement
{
public string Value { get; set; }
}
模型绑定器提供者
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);
}
}
}
}
连接模型粘合剂供应商
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.ModelBinderProviders.Insert(0, new ModelBinderProvider());
});
}
}
表格模型
public class FormModel
{
public string FormName { get; set; } // Not using this
public List<IElement> Elements { get; set; }
}
操作
注意三种类型,文本框、文本框和复选框。
我正在 .net 核心中构建一个动态表单创建器。 "form" 将包含许多不同的表单元素。所以表单模型看起来像这样:
public class FormModel {
public string FormName {get;set;}
public List<IElements> Elements{get;set;}
}
我有 类 用于 TextBoxElement
、TextAreaElement
、CheckBoxElement
,它们都实现了 IElemets
接口。每个元素都有 EditorTemplates
。呈现表单的代码效果很好。尽管由于接口的 List
而无法发布表单。
我一直在寻找如何实现自定义模型联编程序,并在网上看到了一些示例,但我没有让任何人工作。
如果有人能告诉我如何为此示例实现自定义模型绑定器,我将不胜感激。
B计划: Post 形式为 json 到网络 api 并让 JSON.Net 隐藏它。我试过了,它奏效了。在 startup.cs 中我添加了:
services.AddMvc().AddJsonOptions(opts => opts.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto);
它 returns 在必须时键入,例如。元素列表中但不在 FormModel 中的对象。但我真的很想知道如何使用自定义模型活页夹来解决它。
好的,这对我有用。我仍在掌握新的模型绑定,所以我可能做了一些愚蠢的事情,但这是一个开始!
测试表格
<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>
界面
public interface IElement
{
string Value { get; set; }
}
文本框实现
public class Textbox : IElement
{
public string Value { get; set; }
}
复选框实现
public class Checkbox : IElement
{
public string Value { get; set; }
}
模型绑定器提供者
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);
}
}
}
}
连接模型粘合剂供应商
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.ModelBinderProviders.Insert(0, new ModelBinderProvider());
});
}
}
表格模型
public class FormModel
{
public string FormName { get; set; } // Not using this
public List<IElement> Elements { get; set; }
}
操作
注意三种类型,文本框、文本框和复选框。