我已将模型切换回一个字段:
//模型
public class LetterViewModel
{
public string LetterText;
}
//控制器
public ActionResult Index()
{
var model = new LetterViewModel();
model.LetterText = "Anything";
return View(model);
}
[HttpPost]
public ActionResult Index(LetterViewModel model)
{
//model.LetterText == null
return View(model);
}
//视图
@model Test.Models.LetterViewModel
@{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Create a Letter";
}
@using (Html.BeginForm())
{
<div id="Bottom">
@Html.TextAreaFor(m => m.LetterText)
<input type="submit" value="Ok" class="btn btn-default" />
</div>
}
当我检查开发工具中的网络选项卡时,它显示输入的值包含在请求中。但是,当触发HttpPost控制器时,该字段为空。
答案 0 :(得分:9)
DefaultModelBinder
不设置字段的值,仅设置属性。您需要将模型更改为包含属性
public class LetterViewModel
{
public string LetterText { get; set; } // add getter/setter
}
答案 1 :(得分:0)
如果您没有将字段转换为属性的选项,也可以使用自定义活页夹而不是默认活页夹。
循环表单输入并使用反射设置它们。 MemberInformation
是我的班级,但您可以使用FieldInfo
。
这不是一个对象图,但如果我需要这种能力,我会提高我的答案。 foreach
中的元组使用c#7.0。它还假定您在此GET
之前保存了之前POST
的对象。
using CommonBusinessModel.Metadata;
using GHCOMvc.Controllers;
using System;
using System.Linq;
using System.Web.Mvc;
namespace AtlasMvcWebsite.Binders
{
public class FieldModelBinder : DefaultModelBinder
{
// this runs before any filters (except auth filters)
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var form = controllerContext.HttpContext.Request.Form;
Type type = typeof(GHCOBusinessModel.GHCOPPAType);
AtlasKernelBusinessModel.VersionedObject instance = PolicyController.Policy;
foreach ((var value, var member) in (from string input in form
let fi = type.GetField(input)
where fi != null
let mi = new MemberInformation(fi, instance)
where !mi.ReadOnly
select (form[input], mi)))
member.SetValue(value);
return instance;
}
}
}
答案 2 :(得分:0)
您需要在参数之前将[FromBody]添加到Action
[HttpPost]
public ActionResult Index([FromBody]LetterViewModel model)
{
//model.LetterText == null
return View(model);
}