1

我没有要求有一种能在所有的背景被配置(用于最终在数据库中)不同的客户端不同的形式创建动态形成与.net.core

我的初始想法是创建一个对象为“形式”其中有一个“FormItem的词典”来描述表单字段。

我可以再新了通过执行以下操作动态形式(这将来自于数据库/服务):

private Form GetFormData() 
    { 
     var dict = new Dictionary<string, FormItem>(); 
     dict.Add("FirstName", new FormItem() 
     { 
      FieldType = Core.Web.FieldType.TextBox, 
      FieldName = "FirstName", 
      Label = "FieldFirstNameLabel", 
      Value = "FName" 
     }); 
     dict.Add("LastName", new FormItem() 
     { 
      FieldType = Core.Web.FieldType.TextBox, 
      FieldName = "LastName", 
      Label = "FieldLastNameLabel", 
      Value = "LName" 
     }); 
     dict.Add("Submit", new FormItem() 
     { 
      FieldType = Core.Web.FieldType.Submit, 
      FieldName = "Submit", 
      Label = null, 
      Value = "Submit" 
     }); 

     var form = new Form() 
     { 
      Method = "Post", 
      Action = "Index", 
      FormItems = dict 
     }; 

     return form; 
    } 

在我的控制,我可以得到表单数据并传递到视图

 public IActionResult Index() 
    { 
     var formSetup = GetFormData(); // This will call into the service and get the form and the values 

     return View(formSetup); 
    } 

我召唤出一个的HtmlHelper每个FormItems的视图中

@model Form 
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 

@using FormsSpike.Core.Web 
@{ 
    ViewData["Title"] = "Home Page"; 
} 

@using (Html.BeginForm(Model.Action, "Home", FormMethod.Post)) 
{ 
    foreach (var item in Model.FormItems) 
    { 
     @Html.FieldFor(item); 
    } 
} 

然后,在发回时,我必须循环遍历表单变量并再次匹配它们。这感觉很古老的学校,我希望可以在某种模型活页夹中完成。

[HttpPost] 
    public IActionResult Index(IFormCollection form) 
    { 
     var formSetup = GetFormData(); 

     foreach (var formitem in form) 
     { 
      var submittedformItem = formitem; 

      if (formSetup.FormItems.Any(w => w.Key == submittedformItem.Key)) 
      { 
       FormItem formItemTemp = formSetup.FormItems.Single(w => w.Key == submittedformItem.Key).Value; 
       formItemTemp.Value = submittedformItem.Value; 
      } 
     } 
     return View("Index", formSetup); 
    } 

这样我就可以运行一些映射,它会在后台更新数据库。

我的问题是,这只是感觉不对:○{

而且我用一个很简单的HtmlHelper,但我真的不能使用标准htmlHelpers(如LabelFor)创建形式存在是没有模型结合..

public static HtmlString FieldFor(this IHtmlHelper html, KeyValuePair<string, FormItem> item) 
    { 
     string stringformat = ""; 
     switch (item.Value.FieldType) 
     { 
      case FieldType.TextBox: 
       stringformat = $"<div class='formItem'><label for='item.Key'>{item.Value.Label}</label><input type='text' id='{item.Key}' name='{item.Key}' value='{item.Value.Value}' /></ div >"; 
       break; 
      case FieldType.Number: 
       stringformat = $"<div class='formItem'><label for='item.Key'>{item.Value.Label}</label><input type='number' id='{item.Key}' name='{item.Key}' value='{item.Value.Value}' /></ div >"; 
       break; 
      case FieldType.Submit: 
       stringformat = $"<input type='submit' name='{item.Key}' value='{item.Value.Value}'>"; 
       break; 
      default: 
       break; 
     } 

     return new HtmlString(stringformat); 
    } 

另外,验证不会作为工作属性(例如用于RequiredAttribute标签RegExAttribute)不存在。

我对此有错误的方法吗?还是有更完善的方式来完成这样的表格?

有没有一种方法来创建这可以从原始的设置来创建,仍然保持所有的MVC丰富的动态视图模型?

+0

你有没有有没有找到解决办法? –

回答

0

您可以使用我的FormFactory库执行此操作。

默认情况下,它反映了对视图模型产生PropertyVm[]阵列:

```

var vm = new MyFormViewModel 
{ 
    OperatingSystem = "IOS", 
    OperatingSystem_choices = new[]{"IOS", "Android",}; 
}; 
Html.PropertiesFor(vm).Render(Html); 

```

但你也可以编程方式创建的属性,所以你可以从数据库加载设置,然后创建PropertyVm

这是来自Linqpad脚本的片段。

```

//import-package FormFactory 
//import-package FormFactory.RazorGenerator 


void Main() 
{ 
    var properties = new[]{ 
     new PropertyVm(typeof(string), "username"){ 
      DisplayName = "Username", 
      NotOptional = true, 
     }, 
     new PropertyVm(typeof(string), "password"){ 
      DisplayName = "Password", 
      NotOptional = true, 
      GetCustomAttributes =() => new object[]{ new DataTypeAttribute(DataType.Password) } 
     } 
    }; 
    var html = FormFactory.RazorEngine.PropertyRenderExtension.Render(properties, new FormFactory.RazorEngine.RazorTemplateHtmlHelper()); 

    Util.RawHtml(html.ToEncodedString()).Dump(); //Renders html for a username and password field. 
} 

```

即使世界一demo site与您可以设置各种功能的例子(如嵌套集合,自动完成,datepickers等)