3

我在.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,那麼也許您可以利用一些方法。 –

回答

4

好的,這對我很有用。我仍然在處理新的模型綁定,所以我可能會做一些愚蠢的事情,但這是一個開始!

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」 –