我想问一下,有没有办法为Create()
HttpPost方法中的属性ENTRY_DATE
和AUDIT_TIME
设置自动DateTime.Now
值?表单已创建,并且工作正常。如果手动插入日期时间。但是,如果我设置一个自动值并且会遇到
"一个或多个验证错误"..
这是我的模型(我不明白如何制作视图模型):
public partial class TRRESPONDENT
{
public TRRESPONDENT()
{
this.TRFOLLOWUPRESPONDENTs = new HashSet<TRFOLLOWUPRESPONDENT>();
}
[Required(ErrorMessage = "Respondent ID is required!")]
[Display(Name = "Respondent ID")]
public string RESPONDENT_ID { get; set; }
[Required(ErrorMessage = "Please select a BINUS Center!")]
[Display(Name = "Binus Center")]
public string BC_ID { get; set; }
[Required(ErrorMessage = "Name cannot be empty!")]
[Display(Name = "Name")]
[StringLength(100,ErrorMessage = "Name length cannot be more than 100 characters!")]
public string FULL_NAME { get; set; }
.... // more properties
[Required(ErrorMessage = "Please pick a City Location!")]
[Display(Name = "City")]
public int CITY_ID { get; set; }
// The following 2 properties need to be set
[Display(Name = "Entry Date")]
public DateTime ENTRY_DATE { get; set; }
public DateTime AUDIT_TIME { get; set; }
....
public virtual LTCITY LTCITY { get; set; }
public virtual LTSOURCERESPONDENT LTSOURCERESPONDENT { get; set; }
public virtual MSBINUSCENTER MSBINUSCENTER { get; set; }
public virtual ICollection<TRFOLLOWUPRESPONDENT> TRFOLLOWUPRESPONDENTs { get; set; }
}
这是我的观点
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.LabelFor(model => model.RESPONDENT_ID)
@Html.EditorFor(model => model.RESPONDENT_ID)
@Html.ValidationMessageFor(model => model.RESPONDENT_ID)
@Html.LabelFor(model => model.BC_ID, "Binus Center")
@Html.DropDownList("BC_ID", null)
@Html.ValidationMessageFor(model => model.BC_ID)
@Html.LabelFor(model => model.FULL_NAME)
@Html.EditorFor(model => model.FULL_NAME)
@Html.ValidationMessageFor(model => model.FULL_NAME)
.... // more form controls
@Html.LabelFor(model => model.CITY_ID, "City")
@Html.DropDownList("CITY_ID", null)
@Html.ValidationMessageFor(model => model.CITY_ID)
@Html.HiddenFor(model => model.ENTRY_DATE)
@Html.HiddenFor(model => model.AUDIT_TIME)
<input type="submit" value="Create" class="btn btn-default" />
}
这是我的控制器:
public class RespondentController : Controller
{
private RespondentBINUSEntities db = new RespondentBINUSEntities();
public ActionResult Create()
{
ViewBag.CITY_ID = new SelectList(db.LTCITies, "CITY_ID", "CITY_NAME", 1);
var entry = new Models.TRRESPONDENT
{
ENTRY_DATE = DateTime.Now,
AUDIT_TIME = DateTime.Now,
};
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "RESPONDENT_ID,BC_ID,BINUSIAN_ID,FULL_NAME,EMAIL,PHONE_NUMBER,ADDRESS,CITY_ID,ZIP_CODE,SOURCE_ID,ENTRY_DATE,PACKAGE,AUDIT_USER_NAME,AUDIT_TIME,AUDIT_ACTIVITY")] TRRESPONDENT tRRESPONDENT)
{
if (ModelState.IsValid)
{
db.TRRESPONDENTs.Add(tRRESPONDENT);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CITY_ID = new SelectList(db.LTCITies, "CITY_ID", "CITY_NAME", tRRESPONDENT.CITY_ID);
return View(tRRESPONDENT);
}
}
您没有说明错误消息的详细信息,但毫无疑问,这是因为您将01/01/0001
的值保存到一个DATETIME
的字段(该字段仅接受01/01/1753
到12/31/9999
之间的日期)而不是DATETIME2
。
日期值01/01/0001
(这是DateTime
的默认值)的原因是,您没有将模型传递给视图,因此使用默认值。GET中的代码需要
public ActionResult Create()
{
ViewBag.CITY_ID = new SelectList(db.LTCITies, "CITY_ID", "CITY_NAME", 1);
var entry = new Models.TRRESPONDENT
{
ENTRY_DATE = DateTime.Now,
AUDIT_TIME = DateTime.Now,
};
return View(entry); // return your model
}
但是,不应在视图中使用数据模型,而应创建仅包含所需属性的视图模型。ENTRY_DATE
等值应仅在将数据模型保存到数据库之前立即设置。有关创建视图模型的信息,请参阅什么是 MVC 中的视图模型?。
创建视图模型的基本步骤是
- 创建一个新文件夹(比如)
ViewModels
并将您的数据模型复制到和 并将其重命名(说)RespondentVM
- 从数据模型中删除所有
[Display]
属性(它们是 查看特定属性) - 删除用户不会在 视图(例如
ENTRY_DATE
和AUDIT_TIME
),但属性除外 是应重命名为ID
的对象 ID,因此其 自动绑定,假设您使用默认路由(请注意其 不清楚你是否有 ID 属性 - 我假设它RESPONDENT_ID
,但这int
应该是 数据库 -即[Key]public int RespondentId { get; set; }
)。我也 建议您重命名所有属性以遵循命名 约定 -EntryDate
,而不是ENTRY_DATE
。 - 更改要
nullable
的所有值类型并添加[Required]
属性以防止发布不足攻击(例如public int CITY_ID { get; set; }
变得public int? CityID { get; set; }
- 为
SelectList
等添加其他属性 当前分配给ViewBag
属性,例如public IEnumerable<SelectListItem> CityList { get; set; }
然后,您的控制器方法将是
public ActionResult Create()
{
RespondentVM model = new RespondentVM();
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(RespondentVM model) // note a [Bind]` attribute is not required
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
// Initialize an instance of your data model and set its properties based on the view model
TRRESPONDENT respondent = new TRRESPONDENT()
{
FULL_NAME = model.FullName,
CITY_ID = model.CityID,
....
// Set default values
ENTRY_DATE = DateTime.Now,
....
}
db.TRRESPONDENTs.Add(respondent);
db.SaveChanges();
return RedirectToAction("Index");
}
// Common code for populating SelectLists etc - DRY!
private void ConfigureviewModel(RespondentVM model)
{
// Note - delete the 4th parameter of the SelectList constructor
model.CityID = new SelectList(db.LTCITies, "CITY_ID", "CITY_NAME");
}
以及有关视图代码的一些额外注释。
- 如果 ID 属性已命名,则不需要隐藏输入
ID
并且您使用默认路由 - 由于您具有
[Display(Name = "..")]
属性,因此在视图中 它只是@Html.LabelFor(m => m.PropertyName)
,而不是@Html.LabelFor(m => m.PropertyName, "some text")
- 要生成下拉列表,请使用
@Html.DropDownListFor(m => m.CityID, Model.CityList, "Please select", new { ... });
- 您 当前实现不会提供正确的 2 路模型绑定或 客户端验证。