在ASP.NET MVC3中,如何渲染多个模型支持的多个PartialViews?

时间:2011-04-25 21:22:22

标签: asp.net-mvc-3 razor models

在MVC3 Razor中,如何创建具有多个表单的页面,以便每个表单都是使用自己的模型呈现的局部视图?

我们一直在尝试各种形式的Html.RenderPartial(),传入部分视图名称以及我们通过ViewBag访问的模型实例,但我们尝试的每种方法似乎都很严重问题,所以我们必须对这应该如何在一个理想的世界中运作产生根本的误解。

我们在类似主题上发现了一些SO响应(like this one),推荐一个“超级模型”,其中包含对我们的部分视图可能需要使用的每个子模型的引用,但我们找不到如何你会实际使用那些子模型的数据,例如在尝试编写EditorTemplates时。

编辑:让我稍微澄清一下我的问题。我们能够渲染部分视图甚至动作(使用RenderAction作为Mark S.推荐)。但是,我们的主要问题是,当这些表单提交回来时,例如在部分视图区域中保存模型的状态,Controller似乎不知道我们引用的模型。我们应该如何调用控制器?

我们尝试了几种渲染这些局部视图的方法。我们的第一次尝试是这样的:

@using (Html.BeginForm("SaveAccountInfo", null, FormMethod.Post, new { id = "section1-form" }))
{
    @Html.EditorForModel("AccountInfo", (OurModels.AccountInfo) ViewBag.account_info)
}

ViewBag.account_info包含此一个局部视图的模型数据。

我们也尝试过:

@{Html.RenderPartial("FormAccountInfo", (OurModels.AccountInfo) ViewBag.account_info);}

现在:

@{Html.RenderAction("FormAccountInfo", "Main", new { account_info = (OurModels.AccountInfo) ViewBag.account_info }); }

但无论我们使用哪种方法在页面上呈现这一个表单,当该表单被提交进行处理时,我们似乎无法通过模型访问任何提交的数据?我觉得我们正在做一些非常愚蠢的事情,但我们是MVC的新手。

2 个答案:

答案 0 :(得分:1)

不要陷入抽象中,从渲染页面到调用控制器方法的时间,你只是在HTML和HTTP中工作。

如果您想回发其他方法,可以采用多种方法。您可以在页面上有多个HTML表单,或者可以使用jQuery之类的东西来执行帖子。哪个控制器操作选择您的帖子以及发回的数据由HTML页面上的表单及其内容决定。 MVC处理程序将接收请求,并尝试将请求URL和内容绑定到与其匹配的可用操作之一。

要“回发模型”,您需要将数据发送回合适的操作,以便模型绑定器可以读取它。这可能是JSON数据(如果您使用的是MVC 3)或具有名称 - 值对的表单。控制器虽然对请求数据的页面或其创建方式一无所知。它甚至不知道请求是否由页面发出。

您可以通过创建一个包含表单的普通HTML页面来自行尝试,该表单设置为发布到您的一个MVC控制器的URL。只要表单字段的名称与控制器操作的参数上的属性名称匹配,MVC就会绑定它并调用操作。

如果您有复杂的视图,您可能会发现jQuery帖子是可行的方法,一些客户端方法从页面收集数据并创建要发回的JSON对象。使用该方法可以非常精确地控制发回的数据,而对于表单则有限制(例如重叠数据等)。

编辑 - 回复评论

这是一个仅使用原始HTML来展示一个非常简单的案例的例子:

Public Class HomeController

    'Other action methods...

    <HttpPost()>
    Function SayHello(myName As String) As ActionResult
        Return Content("Hello " & myName)
    End Function

End Class

和HTML表单(我在索引视图上对此进行了修改,但它可以绝对放在任何地方)

<form action="/Home/SayHello" method="post">
    <input type="text" name="myName" />
    <input type="submit" />
</form>

我在<input>上设置了名称以匹配参数名称,这为MVC提供了帮助。虽然只有一个值被回发,但我可以将其命名为其他东西。但是,如果我这样做:

<form action="/Home/SayHello" method="post">
    <input type="text" name="aName" />
    <input type="text" name="anotherName" />
    <input type="submit" />
</form>

...然后模型绑定器不知道它应该使用哪个值,并且你得到的值没有正确设置。

但是改为:

<form action="/Home/SayHello" method="post">
    <input type="text" name="myName" />
    <input type="text" name="anotherName" />
    <input type="submit" />
</form>

...而且模型绑定器现在能够使用该名称来正确识别要使用的值和要忽略的值。

在强类型操作的情况下:

Public Class HomeController

    <HttpPost()>
    Function SayHello(person As SimplePerson) As ActionResult
        Return Content("Hello " & person.FirstName)
    End Function

End Class

Public Class SimplePerson
    Public Property FirstName As String
    Public Property Surname As String
End Class

您需要具有与属性名称对应的表单名称。我的aName / anotherName表单会发回正确的形状,但模型绑定器不会设置任何属性,因为它不知道是什么。然而,这将起作用:

<form action="/Home/SayHello" method="post">
    <input type="text" name="FirstName" />
    <input type="text" name="Surname" />
    <input type="submit" />
</form>

答案 1 :(得分:0)

您可以使用Html.RenderAction()方法。它提供了许多功能,允许您进行渲染和操作,并让它调用从数据存储中获取自己的信息。以下是文档的链接:http://msdn.microsoft.com/en-us/library/system.web.mvc.html.childactionextensions.renderaction.aspx