【问题标题】:Validating MVC model extracted from session验证从会话中提取的 MVC 模型
【发布时间】:2017-11-08 00:21:29
【问题描述】:

我正在制作一个 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>

所以,我的第二步只是检查用户输入的值,然后向他展示以进行验证。如果一切正常,我将数据保存在会话中,以便用户可以返回到之前的 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 操作中,我只是从会话中获取模型而没有任何验证。我怎样才能再次验证它,并且在会话中存储数据是否正确,以便我可以返回进行修改或继续下订单。这是正确的做法吗,因为我想不出其他方法。

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-4 session


    【解决方案1】:

    在 MakeOrder 操作中,我只是从会话中获取模型而无需任何验证。如何再次验证?

    您可以在控制器中使用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");
    }
    

    在会话中存储数据是否正确,以便我可以返回进行修改或继续下订单。这是正确的做法吗,因为我想不出其他方法。

    就我个人而言,如果可以的话,我会避免使用 Session。但是,我认为像您这样的“购物篮”要求是完全合理的。我想说的是,从维护和测试的角度来看,如果您为 Session 访问创建一个包装器对象可能会更好。见Session variables in ASP.NET MVC

    这有以下好处:

    • 您的所有会话访问都集中在一个地方。没有散​​布在控制器之间。
    • 在您的解决方案中没有使用“魔术字符串”进行会话访问。
    • 另外,由于您已将会话访问抽象到对象中,因此您的控制器可以更“可测试”(前提是它不是静态包装器)。

    【讨论】:

      猜你喜欢
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-02
      • 2015-02-26
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多