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;}
}

我有 类 用于 TextBoxElementTextAreaElementCheckBoxElement,它们都实现了 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; }
}

操作

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