在asp.net-mvc中创建可重用部分的最佳方法

时间:2010-02-03 16:34:48

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

我在网站的各个部分都有一个表格。

用户输入他们的地址,并提交保存地址的表格。 我想把它包起来,所以我可以重复使用它,因为我需要在几个地方完全相同的功能。

我正在考虑这样做:

  1. 使用表单创建部分视图,但将操作位置url作为参数传入。

  2. 创建一个单独的类/方法来处理服务器端验证(UI已经使用jquery进行了自己的验证)

  3. 已在db层中处理保存/编辑。

  4. 任何人都有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

ASP.NET MVC使用约定优于配置,因此您可以使用此命令将地址表单提交给不同的操作,具体取决于其原始请求的位置。所以如果你没有采取行动:

public ActionResult Foo()
{
  return View();
}

[AcceptVerbs(HttpVerbs.Post)]
public void Foo(string address)
{
//code to update address
}

您的Foo.aspx视图将包含您的地址局部视图,并且您正在使用辅助方法在局部视图中创建表单:

<% using(Html.BeginForm()){ %>
.
.
.
<%}%>

然后当表单发布时,您可以期望它调用您接受HTTP Post的Foo操作。

现在,如果创建一个名为Bar.aspx的新视图,其中还包含您的地址部分视图,其中包含两个新操作来提供您的网页,然后接受帖子数据:

public ActionResult Bar()
{
  return View();
}

[AcceptVerbs(HttpVerbs.Post)]
public void Bar(string address)
{
//code to update address
}

你不需要将任何数据传递给你的局部视图来告诉它在哪里发布,因为框架使用命名约定来解决它,即当从/ MyController / Foo提供时,Html.BeginForm将呈现出来/ MyController / Foo作为发布的动作。与/ MyController / Bar相同

希望有点清楚!

答案 1 :(得分:0)

我经常只是在多个地方创建表单,使用单独的ViewModel并将其连接起来以触发相关命令。 但是我并没有过分担心项目中那么高的重复 - 这是个人偏好的事情。

我建议在你的情况下,使用部分视图,假设视图模型上有一个名为Address的对象,在其绑定的名称前面使用前缀。

视图模型上的那个对象可以是所有视图模型上使用的共享对象,这些模型需要一个地址,比如称为“地址”的方便,类型为“AddressViewModelComponent”。

 public class SomeViewModel
    {
        public string SomeFormValue
        {
            get;
            set;
        }

        public string SomeOtherFormValue
        {
            get;
            set;
        }

        public AddressViewModelComponent Address
        {
            get;
            set;
        }

    }

    public class AddressViewModelComponent
    {
        public string AddressLineOne
        {
            get;
            set;
        }

        public string AddressLineTwo
        {
            get;
            set;
        }

        // Etc
    }

这样您就可以在需要它的任何视图模型上放置一个地址,并且您的部分视图可能包含以下内容:

<li><%= Html.TextBox("Address.AddressLineOne") %></li>
<li><%= Html.TextBox("Address.AddressLineTwo") %></li>      

您的实际视图形式将如下所示:

<% using(Html.BeginForm()) %>
<ul>
<li><%= Html.TextBox("SomeFormValue") %></li>
<li><%= Html.TextBox("SomeOtherFormValue") %></li>

<% Html.RenderPartial("AddressForm"); %>
</ul>
<%} %>

默认模型绑定器知道在视图模型上查找名为“Address”的对象,并使用相关属性填充该视图模型上的属性。

这可能是矫枉过正的,我从来没有找到一个我需要在我的项目中“共享”表单的实例,但上面可能是我开始查看是否要这样做的地方。 / p>

答案 2 :(得分:0)

如果表单是独立的,您可以考虑仅在一个控制器中使表单可用。向包含重定向值的表单添加隐藏字段。发布数据并且控制器更新数据库中的记录后,它可以读取重定向字段中的值,然后重定向到另一个控制器。

脱离我的头顶,这样的事情。显然需要充实一点:

AddressController:

public ActionResult Edit(int id)
{
    return Edit(id, "Address", "Index");  // return to the Index page
}

public ActionResult Edit(int id, string controller, sting action)
{
  Address address = MyDatabase.GetAddress(id);
  ViewData["Action"] = action;
  ViewData["Controller"] = controller;
  return View(address);
}

public ActionResult Edit(Address address)
{
    MyDatabase.Save(address);

    // Read redirect from Form
    string action = Request.Form["Action"];
    string controller = Request.Form["Controller"];
    return RedirectToAction(action, controller);
}

如果您想使用名为Controller2的其他控制器中的表单,您可以使用以下内容:

public ActionResult EditAddressHere(int AddressID)
{
    return RedirectToAction("Edit", "Address", new { id = AddressID, controller = "Controller2", action = "Saved" } );
}

public ActionResult Saved()
{
    return View();
}

我没有包含视图,但它应该足够简单,可以将控制器和操作数据存储在表单的隐藏字段中。