验证从会话中提取的 MVC 模型
Validating MVC model extracted from session
我正在制作一个 MVC 在线网络购物应用程序,因此在购物车页面之后我有 ProcessStepOne
用户应在其中填写数据的操作。
[Authentication]
public ActionResult ProcessStepOne()
{
ProcessOrderViewModel model = GetOrderData();
return View("ProcessOrderStepOne", model);
}
private ProcessOrderViewModel GetOrderData()
{
ProcessOrderViewModel model = (ProcessOrderViewModel)Session["Process"];
if(model==null)
{
model = new ProcessOrderViewModel();
}
return model;
}
我的 ProcessOrderViewModel
模型是:
public class ProcessOrderViewModel
{
public ProcessOrderViewModel()
{
this.PrivateIndividualData = new PrivateIndividualModel();
this.OrderDiscoutPrice = new OrderDiscountPriceModel();
}
public PrivateIndividualModel PrivateIndividualData { get; set; }
public OrderDiscountPriceModel OrderDiscoutPrice { get; set; }
}
我的观点 ProcessOrderStepOne
是:
@model ProcessOrderViewModel
<form id="formOrderData" method="post" action="@Url.Action("ProcessStepTwo")">
<div class="row">
<div class="col-xs-12 col-sm-6">
<div class="form-group">
<label> First Name </label>
@Html.TextBoxFor(x => x.PrivateIndividualData.FirstName, new { @class = "form-control" })
@Html.ValidationMessageFor(x => x.PrivateIndividualData.FirstName)
</div>
</div>
<div class="col-xs-12 col-sm-6">
<div class="form-group">
<label> Last Name </label>
@Html.TextBoxFor(x => x.PrivateIndividualData.Family, new { @class = "form-control" })
@Html.ValidationMessageFor(x => x.PrivateIndividualData.Family)
</div>
</div>
<div class="col-xs-12 col-sm-6">
<div class="form-group">
<label>Email</label>
@Html.TextBoxFor(x => x.PrivateIndividualData.Email, new { @class = "form-control" })
@Html.ValidationMessageFor(x => x.PrivateIndividualData.Email)
</div>
</div>
<div class="col-xs-12 col-sm-6">
<div class="form-group">
<label for="tel">@StringResources.GetResourceString("UserManagement", "Register_PhoneLabel")</label>
@Html.TextBoxFor(x => x.PrivateIndividualData.Telephone, new { @class = "form-control" })
@Html.ValidationMessageFor(x => x.PrivateIndividualData.Telephone)
</div>
</div>
</div>
</form>
因此,我的第二步只是检查用户输入的值,然后向他展示以供验证。如果一切正常,我将数据保存在会话中,以便用户可以 return 到之前的 ProcessStepOne
操作或继续使用 MakeOrder
操作下订单。
public ActionResult ProcessStepTwo(ProcessOrderViewModel model)
{
if (ModelState.IsValid)
{
Session["Process"] = model;
return View("ProcessOrderStepTwo", model);
}
return View("ProcessOrderStepOne", model);
}
视图是:
@model ProcessOrderViewModel
<section class="form-section">
<p>
<a href='@Url.Action("ProcessStepOne")'>CHANGE</a>
<span class="text-semibold">Name:</span> @Model.PrivateIndividualData.FirstName <br>
<span class="text-semibold">Last Name:</span> @Model.PrivateIndividualData.Family <br>
<span class="text-semibold">E-mail:</span> @Model.PrivateIndividualData.Email<br>
<span class="text-semibold">Телефон:</span>@Model.PrivateIndividualData.Telephone <br>
</p>
</section>
<a href='@Url.Action("MakeOrder")'>PROCEED TO MAKE ORDER</a>
而且,这是我刚刚从会话中获取数据的最后一个操作:
public ActionResult MakeOrder()
{
var data = (ProcessOrderViewModel)System.Web.HttpContext.Current.Session["Process"];
// make order with this data
return View("Thank You");
}
所以我的问题是:在 MakeOrder
操作中,我只是从会话中获取模型而没有进行任何验证。我怎样才能再次验证它,它是否正确地将数据存储在会话中,这样我就可以 return 进行修改或继续下订单。这是正确的做法吗,因为我想不出其他方法。
In the MakeOrder action I just take the model from the session without any verification. How can I validate it again?
您可以在控制器中使用 TryValidateModel 在从 Session 中检索模型后重新验证您的模型。然而,从我的测试来看,这种方法似乎只验证了模型深处的一个层次。考虑到这一点,您的代码将类似于以下内容:
public ActionResult MakeOrder()
{
var data = (ProcessOrderViewModel)System.Web.HttpContext.Current.Session["Process"];
bool individualDataValid = TryValidateModel(data.PrivateIndividualData);
bool discountDataValid = TryValidateModel(data.OrderDiscoutPrice);
if (individualDataValid && discountDataValid)
{
// make order with this data
return View("Thank You");
}
//Error condition
return View("Error");
}
Is it right storing the data in session so I can return to make modifications or proceed to make an order. Is this the right thing to do because I can't think of another way.
就个人而言,我会尽可能避免使用 Session。但是,我认为像您这样的 "Shopping Basket" 要求是完全合理的。我要说的是,从维护和测试的角度来看,如果您为 Session 访问创建一个包装器对象可能会更好。参见 Session variables in ASP.NET MVC。
这有以下好处:
- 您所有的会话访问都集中在一个地方。没有自由地分散在控制器之间。
- 您的解决方案中未使用 "Magic Strings" 进行会话访问。
- 作为一个额外的好处,因为您已经将会话访问抽象到一个对象中,所以您的控制器可以更多 "testable"(前提是它不是静态包装器)。
我正在制作一个 MVC 在线网络购物应用程序,因此在购物车页面之后我有 ProcessStepOne
用户应在其中填写数据的操作。
[Authentication]
public ActionResult ProcessStepOne()
{
ProcessOrderViewModel model = GetOrderData();
return View("ProcessOrderStepOne", model);
}
private ProcessOrderViewModel GetOrderData()
{
ProcessOrderViewModel model = (ProcessOrderViewModel)Session["Process"];
if(model==null)
{
model = new ProcessOrderViewModel();
}
return model;
}
我的 ProcessOrderViewModel
模型是:
public class ProcessOrderViewModel
{
public ProcessOrderViewModel()
{
this.PrivateIndividualData = new PrivateIndividualModel();
this.OrderDiscoutPrice = new OrderDiscountPriceModel();
}
public PrivateIndividualModel PrivateIndividualData { get; set; }
public OrderDiscountPriceModel OrderDiscoutPrice { get; set; }
}
我的观点 ProcessOrderStepOne
是:
@model ProcessOrderViewModel
<form id="formOrderData" method="post" action="@Url.Action("ProcessStepTwo")">
<div class="row">
<div class="col-xs-12 col-sm-6">
<div class="form-group">
<label> First Name </label>
@Html.TextBoxFor(x => x.PrivateIndividualData.FirstName, new { @class = "form-control" })
@Html.ValidationMessageFor(x => x.PrivateIndividualData.FirstName)
</div>
</div>
<div class="col-xs-12 col-sm-6">
<div class="form-group">
<label> Last Name </label>
@Html.TextBoxFor(x => x.PrivateIndividualData.Family, new { @class = "form-control" })
@Html.ValidationMessageFor(x => x.PrivateIndividualData.Family)
</div>
</div>
<div class="col-xs-12 col-sm-6">
<div class="form-group">
<label>Email</label>
@Html.TextBoxFor(x => x.PrivateIndividualData.Email, new { @class = "form-control" })
@Html.ValidationMessageFor(x => x.PrivateIndividualData.Email)
</div>
</div>
<div class="col-xs-12 col-sm-6">
<div class="form-group">
<label for="tel">@StringResources.GetResourceString("UserManagement", "Register_PhoneLabel")</label>
@Html.TextBoxFor(x => x.PrivateIndividualData.Telephone, new { @class = "form-control" })
@Html.ValidationMessageFor(x => x.PrivateIndividualData.Telephone)
</div>
</div>
</div>
</form>
因此,我的第二步只是检查用户输入的值,然后向他展示以供验证。如果一切正常,我将数据保存在会话中,以便用户可以 return 到之前的 ProcessStepOne
操作或继续使用 MakeOrder
操作下订单。
public ActionResult ProcessStepTwo(ProcessOrderViewModel model)
{
if (ModelState.IsValid)
{
Session["Process"] = model;
return View("ProcessOrderStepTwo", model);
}
return View("ProcessOrderStepOne", model);
}
视图是:
@model ProcessOrderViewModel
<section class="form-section">
<p>
<a href='@Url.Action("ProcessStepOne")'>CHANGE</a>
<span class="text-semibold">Name:</span> @Model.PrivateIndividualData.FirstName <br>
<span class="text-semibold">Last Name:</span> @Model.PrivateIndividualData.Family <br>
<span class="text-semibold">E-mail:</span> @Model.PrivateIndividualData.Email<br>
<span class="text-semibold">Телефон:</span>@Model.PrivateIndividualData.Telephone <br>
</p>
</section>
<a href='@Url.Action("MakeOrder")'>PROCEED TO MAKE ORDER</a>
而且,这是我刚刚从会话中获取数据的最后一个操作:
public ActionResult MakeOrder()
{
var data = (ProcessOrderViewModel)System.Web.HttpContext.Current.Session["Process"];
// make order with this data
return View("Thank You");
}
所以我的问题是:在 MakeOrder
操作中,我只是从会话中获取模型而没有进行任何验证。我怎样才能再次验证它,它是否正确地将数据存储在会话中,这样我就可以 return 进行修改或继续下订单。这是正确的做法吗,因为我想不出其他方法。
In the MakeOrder action I just take the model from the session without any verification. How can I validate it again?
您可以在控制器中使用 TryValidateModel 在从 Session 中检索模型后重新验证您的模型。然而,从我的测试来看,这种方法似乎只验证了模型深处的一个层次。考虑到这一点,您的代码将类似于以下内容:
public ActionResult MakeOrder()
{
var data = (ProcessOrderViewModel)System.Web.HttpContext.Current.Session["Process"];
bool individualDataValid = TryValidateModel(data.PrivateIndividualData);
bool discountDataValid = TryValidateModel(data.OrderDiscoutPrice);
if (individualDataValid && discountDataValid)
{
// make order with this data
return View("Thank You");
}
//Error condition
return View("Error");
}
Is it right storing the data in session so I can return to make modifications or proceed to make an order. Is this the right thing to do because I can't think of another way.
就个人而言,我会尽可能避免使用 Session。但是,我认为像您这样的 "Shopping Basket" 要求是完全合理的。我要说的是,从维护和测试的角度来看,如果您为 Session 访问创建一个包装器对象可能会更好。参见 Session variables in ASP.NET MVC。
这有以下好处:
- 您所有的会话访问都集中在一个地方。没有自由地分散在控制器之间。
- 您的解决方案中未使用 "Magic Strings" 进行会话访问。
- 作为一个额外的好处,因为您已经将会话访问抽象到一个对象中,所以您的控制器可以更多 "testable"(前提是它不是静态包装器)。