【问题标题】:Passing complex object from view to controller/view in ASP.NET MVC在 ASP.NET MVC 中将复杂对象从视图传递到控制器/视图
【发布时间】:2010-12-28 13:44:07
【问题描述】:

在我的 MVC 应用程序中,我在将数据从视图传递到控制器时遇到了问题。我有相当复杂的域类:

public class TaskBase : PersistableObject
{
    public virtual TaskCategory Category { get; set; }
    public virtual IList<TaskNote> Notes { get; set; }
    public virtual string TaskTitle { get; set; }
    public virtual string TaskBody { get; set; }
    public virtual DateTime? CreationTime { get; set; }
    public virtual User CreatedBy { get; set; }
    public virtual int CompletionRatio { get; set; }
}

public class MainTask : TaskBase
{
    public virtual IList<TaskBase> ChildTasks { get; set; }
    public virtual User AssignedTo { get; set; }
    public virtual IList<TaskHistory> History { get; set; }
}

public class TaskFormModel : ViewDomainBase
{
    public MainTask Task { get; set; }
    public LoginForm LoginInfo { get; set; }
}

在我看来,我想将 TaskFormModel 的一个实例传递给控制器​​。

<%= Html.ActionLink<TaskController>("Edit Task", (x) => x.Edit(new TaskFormModel() { Task = item, LoginInfo = Model.LoginInfo }))%>

这里是控制器动作:

public ActionResult Edit (TaskFormModel taskInfo)
{
    return View(ViewPageName.TaskDetailsForm, task.Task);
}

在此操作方法中,即使我从视图中传递非空实例,taskInfo 也会为空。我想我在这里有一个绑定问题。我认为,编写自定义模型绑定器需要转换每个属性,并且当添加新字段时,绑定器类也应该更改,所以我不希望自定义模型绑定器这样做。在这种情况下,还有其他方法可以将数据传递给控制器​​吗?或者可以对自定义模型绑定器进行编码,以便编写更少的代码并且在添加新属性时不需要更改绑定器类?

评论后编辑:我想要实现的基本上是将实例从一个视图传递到另一个视图,而不在我的控制器操作中查询存储库/数据库。

【问题讨论】:

  • @arh,为什么在传递对象时不想回到数据库?我个人更喜欢这种方法,因为它可以让所有东西分开。我只会传递ID。流量也少了很多。

标签: asp.net-mvc data-binding


【解决方案1】:

第一版答案:

你的 GET 编辑方法应该是这样的:

public ActionResult Edit (int id)
{
    var model = taskRepository.GetTaskEditModel(id);
    return View(ViewPageName.TaskDetailsForm, model);
}

和 ActionLink:

<%= Html.ActionLink("Edit Task", "Edit", "Task", new { model.Task.id })%>

如果你想将复杂的对象传递给控制器​​,你应该将它们包装成 html 形式并传递给 POST 动作。

【讨论】:

  • 我相信@arch 的编辑操作是正确的。他将整个对象传递给 ActionResult。我以前做过完全一样的。问题中不清楚的是首先如何将任务分配给视图。他是否将对象传递给编辑操作或进行查找。如果是查找,那么您的答案是有效的,如果不是,那么一切都很好。
  • 问题不够清楚。很高兴知道作者正在努力实现什么。他还可以使用 [HttpGet] 或 [HttpPost] 属性来装饰动作。
  • 是的,同意。他可以用 HttpPost 进行装饰,但在他提供的代码中,这不是必需的,但就像你说的那样,目前还不清楚。
  • ActionLink 用法表明它是 GET 方法。将复杂对象传递给 GET 方法在这里看起来不是一个好主意。
  • 看,我 100% 同意你的看法。我只是说,在这种情况下,我认为这不是问题所在。但是我确实相信他需要将所有内容包装在一个表单中,但我认为这里的主要问题以及它不起作用的原因是“new TaskFormModel() { Ta ...”他应该放弃 ()。跨度>
【解决方案2】:

在我看来,你做错了什么。 据我了解:您正在尝试实例化一个新对象,将其传递给浏览器并将其取回。 好吧,你不能。

如果您要编辑的对象已经存在于您的存储中,那么您应该更改 ActionLink 以通过 id 引用它,并在您的 Edit 操作中实例化它。

看看工具创建的默认强类型索引视图。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多