发布列表< Interface> .net核心1.0

发布列表< Interface> .net核心1.0

问题描述:

我正在.net核心中创建动态表单创建者。 表单将包含许多不同的表单元素。因此,表单模型将如下所示:

I'm building a dynamic form creator in .net core. A "form" will consist of many different form elements. So the form model will look something like this:

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

我有 TextBoxElement TextAreaElement CheckBoxElement 都实现了 IElemets 界面。每个元素都有 EditorTemplates 。呈现表单的代码效果很好。尽管由于接口的 List 而无法发布表单。

I have classes for TextBoxElement, TextAreaElement, CheckBoxElement that all implement the IElemets interface. And I have EditorTemplates for each element. The code to render the form works great. Though posting the form does not work because of the List of Interfaces.

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

I've been looking on how to implement a custom model binder, and seen some few examples on the web but I did not get anyone to work.

如果有人可以向我展示如何实施

I would appreciate if someone could show me how to implement a custom model binder for this example.

计划B:
将表单以json格式发布到网络api中,然后让JSON.Net对其进行隐藏。我已经尝试过了,而且效果很好。在startup.cs中,我添加了:

Plan B: Post form as json to a web api and let JSON.Net covert it. I have tried it and it worked. In startup.cs i added:

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

在需要时返回类型。元素列表中的对象,而不是FormModel上的对象。但是我真的很想知道如何使用自定义模型联编程序来解决它。

It returns type when it has to, eg. the objects in the Elements-list but not on the FormModel. But i really would like to know how to solve it with a custom model binder instead.

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

Ok, this works for me. I'm still getting to grips with the new model binding so I may be doing something silly but it's a start!

<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 IMPLEMENTATION

public class Textbox : IElement
{
    public string Value { get; set; }
}



复选框实现



CHECKBOX IMPLEMENTATION

public class Checkbox : IElement
{
    public string Value { get; set; }
}



模型绑定提供程序



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



模型绑定器



MODEL BINDER

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模型绑定提供程序



HOOK UP MODEL BINDER 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



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

ACTION

Notice the three types, Textbox, Textbox and Checkbox.