我正在尝试使用c#mvc验证表单,我已经通过验证设置了模型。
我添加了模型联编程序以连接来自表单的请求,然后将其发送到提交控制器进行验证。
当if语句检查对象绑定程序是否正确时,它将代码视为有效。关于使用服务器端验证来检查表单中的信息的操作有何误解?
型号:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace messageBoard.Models
{
public class Messages
{
[Required]
[StringLength(250)]
public string Sender { get; set; }
[Required]
public string Receiver { get; set; }
public int Year { get; set; }
public string Form { get; set; }
[Required]
public DateTime StartDate { get; set; }
[Required]
public DateTime Expiry { get; set; }
[Required]
[StringLength(250)]
public string Title { get; set; }
[Required]
public string Message { get; set; }
}
}
控制器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using messageBoard.Models;
namespace messageBoard.Controllers
{
public class Messagebinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
HttpContextBase objContext = controllerContext.HttpContext;
string sender = objContext.Request.Form["txtSender"];
string reciever = objContext.Request.Form["txtReciever"];
string form = objContext.Request.Form["txtForm"];
string strYear = objContext.Request.Form["txtYear"];
Int32 year = Int32.Parse(strYear);
string strStart = objContext.Request.Form["txtStartDate"];
DateTime startParse = DateTime.Parse(strStart);
string strExpiry = objContext.Request.Form["txtExpiry"];
DateTime expiryParse = DateTime.Parse(strExpiry);
string title = objContext.Request.Form["txtTitle"];
string message = objContext.Request.Form["txtMessage"];
Messages obj = new Messages()
{
Sender = sender,
Receiver = reciever,
Form = form,
Year = year,
StartDate = startParse,
Expiry = expiryParse,
Title = title,
Message = message
};
return obj;
}
}
public class MessagesController : Controller
{
// GET: Messages
public ActionResult Load()
{
Messages obj = new Messages {
Sender = "Ross McKenzie",
Receiver = "Noah McKenzie",
Year = 8,
Form ="8NM",
StartDate = new DateTime(2018, 10, 22),
Expiry = new DateTime(2018, 10, 31),
Title = "Noah",
Message = "This is the first message for the test of the internal message board, oh and I love you Noah"
};
return View("Messages",obj);
}
public ActionResult Enter()
{
return View("EnterMessages",new Messages());
}
public ActionResult Submit([ModelBinder(typeof(Messagebinder))] Messages obj)
{
if(ModelState.IsValid)
{
return View("Messages", obj);
}
else
{
return View("EnterMessages");
}
}
}
}
答案 0 :(得分:0)
我建议控制者应该简单并做出简单的决定。这是来自ASP.NET MVC 5的我的一个
首先,我使用依赖注入将业务服务接口注入到构造函数中。我还使用了所有控制器通用代码都存在的基类,因此我将业务接口传递给该基类,该类仍可以引用该接口。您需要阅读IoC及其实现方法。微软有一个简单的我可以使用的软件,但还有其他一些。
public SparesSectionsController(IBusinessService bs) : base(bs)
{
}
对于CRUD操作,我有成对的动作以及一个列出了CREATE,EDIT,DELETE记录的索引。这是一个用于编辑现有记录的
[HttpGet]
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
SparesSection sparesSection = await _bs.SparesSection_GetAsync(id.Value);
if (sparesSection == null)
{
return HttpNotFound();
}
return View(sparesSection);
}
相应的POST操作将所有必填字段绑定为操作参数的一部分。
为简单起见,但可能是较差的做法,我将模型状态传递给业务层,以便可以添加任何其他字段或常规错误。最好在较低级别定义的单独类中定义退货业务层错误,然后将其添加到“模型状态”中。后一种方法打破了对MVC的依赖性,并抽象了业务层以用作Web界面或其他独立业务源。
请注意,ViewMessage是基类属性,它只是将一些文本放入TempData属性中。然后,如果视图中的_Layout不为null,则_Layout显示该消息。这种方法允许重定向过程中跨操作的持久性,而ViewBag则不能这样做
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "SparesSectionId,SparesSectionTitle")] SparesSection sparesSection)
{
if (ModelState.IsValid)
{
await _bs.SparesSection_UpdateAsync(sparesSection, ModelState);
if (ModelState.IsValid)
{
ViewMessage = "Saved " + sparesSection.SparesSectionTitle;
return RedirectToAction("Index");
}
}
return View(sparesSection);
}
视图轻巧紧凑
@model YourProjectName.Models.SparesSection
@{
ViewBag.Title = "Edit Spares Section";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container w-50">
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.SparesSectionId)
<div class="form-group">
@Html.LabelFor(model => model.SparesSectionTitle, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.SparesSectionTitle, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.SparesSectionTitle, "", new { @class = "text-danger" })
</div>
<div class="d-flex">
<div class="ml-auto">
<input type="submit" value="Save" class="btn btn-primary btn-sm btn-default" />
</div>
</div>
</div>
}
</div>
对于我的模型,因为这是一个小类,所以我直接使用实体框架,并使用局部类对其进行扩展。对于更大或更复杂的数据,我建议使用单独的视图模型,从EF数据中获取一个获取的模型,以及其他任何资源
//-----------------------------------------------------------------------
#region Spares Section
[MetadataType(typeof(SparesSectionMetaData))]
public partial class SparesSection { }
public class SparesSectionMetaData
{
[ScaffoldColumn(false)]
[DefaultValue(0)]
[Required]
public int SparesSectionId { get; set; }
[DisplayName("Spares Section Title")]
[StringLength(100, MinimumLength = 2, ErrorMessage = "2-100 characters")]
[Required]
public string SparesSectionTitle { get; set; }
}