【问题标题】:Asp.net MVC 5 passing model object to controller via ActionLinkAsp.net MVC 5 通过 ActionLink 将模型对象传递给控制器
【发布时间】:2016-10-18 00:48:44
【问题描述】:

我需要一些关于如何完成这项工作的帮助/建议。 我需要通过 ActionLink 将模型从视图传递到控制器

@Html.ActionLink("Radera", "DeleteTraffic", new { model = Model, trafficId = traffic.Id }, new { @class = "btn btn-link NoBorder NoBackGround" })

控制器中的方法如下所示。

public ActionResult DeleteTraffic(CalendarModel model, int trafficId)
    {

        return View("EditDay", model);
    }

我还没有在方法中添加任何代码,我只是在调试它以使调用工作。当我按下按钮时模型为空,然而,trafficId 已正确设置。那我做错了什么?

编辑 1: 我已经根据这里的建议更改了代码。

@using (Html.BeginForm("DeleteTraffic", "Calendar", new {trafficId = traffic.Id})) {<input type="submit" value="Radera" class="btn btn-link NoBorder NoBackGround"/>}

[HttpPost]
    [ValidateAntiForgeryToken]
    [ActionName("DeleteTraffic")]
    public ActionResult DeleteTraffic(int trafficId)
    {



        return View("EditDay", Model);
    }

但 DeleteTraffic 永远不会重新处理,而是调用此页面的主要操作。

// GET: Calendar
    public ActionResult Calendar()
    {


        CalendarModel model = new CalendarModel {SelectedDate = DateTime.Today};
        if (Request.HttpMethod == "POST")
        {
            if (!string.IsNullOrEmpty(Request.Form.Get("submit.SelectDate")))
            {
                model.SelectedDate = Convert.ToDateTime(Request.Form["selectedDate"]);
                model.TrafficDates = TrafficData.GeTrafficDatesPerMonth(model.SelectedDate);
                Model = model;
                return View("EditDay", Model);
            }

        }
        Model = model;
        return View(Model);
    }

我是否应该将 trafficId 塞入一个隐藏字段并将此操作用于所有操作? MVC 有时看起来很不灵活......

【问题讨论】:

  • new { Model, trafficId = traffic.Id } 但如果模型的任何属性是复杂对象或集合,它将无法正确绑定(并且您可能超过查询字符串限制。为什么您认为您需要这样做 - 您应该只是传递模型的ID 属性,而不是整个模型。删除永远不应该是 GET。您应该使用表单并发布 ID 值
  • 我可以只发送 trafficId 并忽略模型。我这样做的原因是在处理完删除后返回编辑站点。加载站点时,模型对象是必不可少的,这就是我来回传递它的原因。我可以将它存储在会话变量中,但我不知道是否有更好的方法。我不想做表单和发布的原因是 CalendarModel 包含大量数据,我不希望应用程序在用户每次按下按钮时都继续重建
  • 更好的方法是再次从数据库中获取它。如果它确实包含大量数据,那么由于查询字符串的限制,您几乎肯定会抛出异常。但正如我所指出的,Delete 必须是 POST,而不是 GET。
  • 那么我如何将 ActionLink 变成帖子?我需要在控制器中的方法上添加一个属性吗?
  • @using(Html.BeginForm("DeleteTraffic", "yourControllerName", new { trafficId = traffic.Id })) { &lt;input type="submit" value="Radera" /&gt; } 并用[HttpPost] 标记方法(您可能还需要AntiForgeryToken

标签: asp.net-mvc-5


【解决方案1】:

首先,诸如“删除”之类的事情绝不应该由 GET 处理。删除是原子的,应该使用 POST 或 DELETE(最好是)动词来完成。通常,您也不应该在没有用户确认的情况下删除某些内容,因此处理此问题的最简单和正确的方法是让“删除”链接将用户带到一个要求他们确认删除该项目的视图。那么,在这个视图中,您将通过表单帖子提交要删除的项目的 ID:

public ActionResult Delete(int id)
{
    var foo = db.Foos.Find(id);
    if (foo == null)
    {
        return new HttpNotFoundResult();
    }

    return View(foo);
}

[HttpPost]
[ValidateAntiForgeryToken]
[ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
    var foo = db.Foos.Find(id);
    if (foo == null)
    {
        return new HttpNotFoundResult();
    }

    db.Foos.Remove(foo);
    db.SaveChanges();

    return RedirectToAction("Index");
}

然后,对于您的 GET 操作,您将添加一个 Delete.cshtml 文件:

@model Namespace.To.Foo

<p>Are you sure you want to delete the foo, "@Model.Name"?</p>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(m => m.Id)

    @Html.ActionLink("Cancel", "Index")
    <button type="submit">Delete</button>
}

如果您不想更改页面,您也可以使用 JavaScript 确认和 AJAX 来执行此操作:

@Html.ActionLink("Radera", "DeleteTraffic", new { id = item.Id }, new { @class = "btn btn-link NoBorder NoBackGround delete", data_id = item.Id })

然后:

<script>
    $('.delete').on('click', function () {
        var $deleteLink = $(this);
        if (confirm('Are you sure?')) {
            $.post('/url/for/delete/', { id = $deleteLink.data('id') }, function () {
                $deleteLink.closest('tr').remove();
            });
        }
    });
</script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 2015-05-05
    • 2011-12-16
    • 1970-01-01
    相关资源
    最近更新 更多