在ASP.NET MVC中将复杂对象从视图传递到控制器/视图

3

在我的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也会变成null。我认为这里存在绑定问题。我认为编写自定义模型绑定器需要将每个属性转换,并且当添加新字段时,绑定器类也应该更改,因此我不想让自定义模型绑定器执行此操作。在这种情况下,有没有其他方法将数据传递给控制器?或者可以编写自定义模型绑定器,以便写入的代码更少,并且当添加新属性时,绑定器类将不需要更改?
评论后编辑:我的目标基本上是在不在控制器的操作中查询存储库/数据库的情况下,从一个视图传递一个实例到另一个视图。

@arh,为什么你不想在传递对象时返回到数据库呢?个人而言,我更喜欢这种方法,因为它将一切都分开了。我只会传递id。这样流量也会少很多。 - griegs
2个回答

4

回答的第一个版本:

你的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动作。


看,我完全同意你的观点。我只是想说,在这种情况下,我不认为这是问题所在。然而,我确实相信他需要将所有内容都包装在一个表单中,但我认为主要问题在于它没有起作用的原因是“new TaskFormModel() { Ta...}”他应该去掉括号“()”。 - griegs
据我所知,new TaskFormModel() { Task = item, LoginInfo = Model.LoginInfo } == new TaskFormModel { Task = item, LoginInfo = Model.LoginInfo } - LukLed
我不知道前者能不能工作。我在C#中尝试过,但出现了错误。 - griegs
啊,没错,这里的问题确实是Resharper。LukLed真厉害。 - griegs
谢谢大家,我想我应该再做一些澄清。我实际想要实现的是在不再次访问存储库/数据库的情况下,将一个实例从一个视图传递到另一个视图中,直接在我的控制器操作中完成。 - rovsen
显示剩余7条评论

1
在我看来,你正在做一些错误的事情。 据我所知:你正在尝试实例化一个新对象,将其传递给浏览器并再次获取它。 好吧,你不能这样做。
如果你想要编辑的对象已经存在于你的存储中,那么你应该通过id引用它来修改你的ActionLink,并在你的Edit操作中实例化它。
看看工具创建的默认强类型索引视图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接