【问题标题】:ASP.Net MVC: pass information to HTTPost ControllerASP.Net MVC:将信息传递给 HTTPost 控制器
【发布时间】:2016-05-31 09:28:42
【问题描述】:

这是我的场景:我有一个名为 MaterialPaymentRequest 的模型。它由几个MaterialPaymentRequestSubItem 组成,所以PaymentRequest 是父级,MaterialPaymentRequestSubItem 是它的子级。 考虑一下当我有一个MaterialPaymentRequest 并且我想给它添加一个孩子。 目前它在MaterialPaymentRequestSbuItemController 中的方法如下所示:

public ActionResult CreateChild(int parentId)
{
    if (parentId==null)
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

    var parenetRequest = (from request in db.MaterialPaymentRequests
        where request.Id==parentId
        select request);

    ViewBag.MaterialPaymentRequestId = new SelectList(parenetRequest, "Id", "Description", parentId);
    ViewBag.ParentID = parentId;
    return View();
}

我的问题在视图内部,用户可以更改其父级,因为我有一个无法冻结或使其只读的下拉列表:

@Html.DropDownList("MaterialPaymentRequestId", String.Empty)

我尝试使用ViewModel,在发布后我设置了我孩子的 parentID,但是这样我不知道如何将 ParentId 传递给 http-post 控制器方法。

我在使用ViewMode之前的回发方式是这样的:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateChild([Bind(Include = "Id,Name,Unit,UnitPrice,MaterialPaymentRequestId,Quantity")] MaterialPaymentRequestSubItem materialpaymentrequestsubitem)
{
    if (ModelState.IsValid)
    {
        ...
    }
    ....
}

我见过像this 这样使用Html.Hidden 的方法,但我认为它不够安全,因为用户可以在用户端操作信息。

有没有更好的方法来做到这一点?

我可以通过这样的声明将信息传递给接受 parentID 作为参数的控制器吗?

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateChild(int parentID, [Bind(Include = "Id,Name,Unit,UnitPrice,MaterialPaymentRequestId,Quantity")] MaterialPaymentRequestSubItem materialpaymentrequestsubitem)
{
    if (ModelState.IsValid)
    {
        ...
    }
    ....
}

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-5


    【解决方案1】:

    要使 HTML 辅助输入控件在客户端只读,请使用以下命令:

    @Html.DropDownList("MaterialPaymentRequestId", String.Empty, new { @readonly = "readonly" })
    

    如果您不想使用客户端隐藏字段,我建议您使用 Session 变量在服务器端维护 parentId 内容状态。

    Session["parentId"] = parentId;
    
    // just an example to extract Session variable
    int parentId = Session["parentId"] != null ? Convert.ToInt32(Session["ParentId"]) : return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    

    但是,如果您需要视图中的隐藏字段,请在隐藏字段中使用编码文本并针对其值进行验证架构(例如 Base64 或更好的编码),因此访问您网站的任何用户都无法轻易更改客户端中的值-一边。

    查看:

    @Html.Hidden("ParentID", @ViewBag.ParentID);
    
    // or if you have a viewmodel, pass viewmodel's value here
    @Html.HiddenFor(model => model.ParentID);
    

    控制器方法:

    public ActionResult CreateChild(int parentId)
    {
        ...
        // convert parentId into Base64
        ViewBag.ParentID = Convert.ToBase64String(parentId);
        return View(ViewBag); // model binding
    }
    
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult CreateChild([Bind(Include = "Id,Name,Unit,UnitPrice,MaterialPaymentRequestId,Quantity,ParentID")] MaterialPaymentRequestSubItem materialpaymentrequestsubitem)
    {
         ...
         // get Parent ID
         int parentId = (int)Convert.FromBase64String(ParentID);
    
         // write your own algorithm to validate hidden field's value
         ...
         if (ModelState.IsValid) 
         {
              // redirect to create child elements
              return RedirectToAction("CreateChild", "Controller", new { @id = parentId });
         }
    }
    

    希望这个解释对你有用,CMIIW。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 2011-01-01
      • 1970-01-01
      • 2011-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多