张贴清单 .net核心1.0

问题描述:

我在.net核心中构建了一个动态表单创建器。一个“表单”将包含许多不同的表单元素。所以表格模型将是这个样子:张贴清单<Interface> .net核心1.0

public class FormModel { 
    public string FormName {get;set;} 
    public List<IElements> Elements{get;set;} 
} 

我有类TextBoxElementTextAreaElementCheckBoxElement全部实现IElemets接口。我有每个元素EditorTemplates。用于渲染表单的代码很有用。尽管张贴表单不起作用,因为接口的List

我一直在寻找如何实现自定义模型联编程序,并在网络上看到一些例子,但我没有得到任何人的工作。

如果有人能告诉我如何为本示例实现自定义模型联编程序,我将不胜感激。

B计划: 将表单作为json发布到web api并让JSON.Net将其隐藏。我已经尝试过,它的工作。在startup.cs我补充说:

services.AddMvc().AddJsonOptions(opts => opts.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto); 

它返回类型,当它必须,例如。元素列表中的对象,但不在FormModel上。但我真的很想知道如何用自定义模型绑定器来解决它。

+0

模型绑定怎么知道实例张贴在列表中的元素哪些类型? – Lucero

+0

不知道为什么有人投这个票。我想你将不得不发布一些额外的信息,让你的自定义模型联编程序知道什么类的实例化。 –

+0

我认为JSON。NET可以通过序列化/反序列化类型名称来处理类型。如果您使用JSON,那么也许您可以利用一些方法。 –

好的,这对我很有用。我仍然在处理新的模型绑定,所以我可能会做一些愚蠢的事情,但这是一个开始!

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

请注意三种类型,即文本框,文本框和复选框。

enter image description here

+0

我试过这个例子。 bindingContext.ValueProvider.GetValue返回null bindingContext.ModelName是一个空字符串 –

+0

没关系我错过了html中的name =“Elements [0] .Type” –