1

我正在构建一个 MVC 应用程序,我想提交一个表单。所以我做了这样简单的事情。这是“DisplayItems”视图:

@model List<MyApp.Models.Inventory>

@{
    ViewBag.Title = "Display Items";
}

@using (Html.BeginForm())
{
    <table>
        <tr>
            <th>Object Name</th>
            <th>Number In Stock</th>
            <th>Quantity To Send</th>
            <th>Reserved for First Template</th>
            <th>Reserved for Second Template</th>
            <th>Reserved for Third Template</th>
            <th>Number so far</th>
            <th>Input quantity</th>
        </tr>
        @for (int i = 0; i < Model.Count(); i++)
        {
            <tr>
                <td>@Html.DisplayFor(_x => _x[i].m_Obj.m_ObjName)</td>
                <td>@Html.DisplayFor(_x => _x[i].m_QtyToSendShow)</td>
                <td>@Html.DisplayFor(_x => _x[i].m_NbInStock)</td>
                <td>@Html.DisplayFor(_x => _x[i].m_QtyFirstTemplate)</td>
                <td>@Html.DisplayFor(_x => _x[i].m_QtySecondTemplate)</td>
                <td>@Html.DisplayFor(_x => _x[i].m_QtyThirdTemplate)</td>
                <td>@Html.DisplayFor(_x => _x[i].m_QtyHold)</td>
                <td>@Html.TextBoxFor(_x=>_x[i].m_QtyToSend)</td>
            </tr>
        }
    </table>
    <input type="submit" name="_submitButton" value="Confirm"/>  
}

没什么特别的。但是,当用户单击“确认”按钮时,应用程序会不断返回到 PREVIOUS 视图,该视图是用户指定搜索的过滤引擎。

这是名为“SendItems”的先前视图:

@{
    ViewBag.Title = "Send items";
}

<h2>Send Items</h2>

<p>
    @using (Html.BeginForm())
    {
        Html.RenderAction("AdvancedSearch", "PartialViews");
    }

    @Html.ActionLink("Back to Selection", "MenuSelection")
</p>

部分视图是绑定到具有许多字段和输入按钮的模型的视图。单击按钮输入时,控制器方法如下所示:

public ActionResult SendItems(SearchEngineObject _searchObj, string _submitButton)
{
    if (_submitButton == "Search")
    {
        bool isValid = ValidateSearchFields(_searchObj);

        if (!isValid)
        {
            ViewData["ErrorMessage"] = m_MessageError;

            return View();
        }

        m_ListToManage = m_InventoryManager.ListAvailableInventoryItems(_searchObj);

        if (m_ListInventoryToManage.Count == 0)
        {
            ViewData["ErrorMessage"] =
                "There are no inventory items belonging to the parameters you selected; " +
                "please change your values and try again.";

            return View();
        }

        return View("DisplayItems", m_ListInventoryToManage);
    }

    return View();
}

因此,当点击 SendItems 视图的输入按钮时,控制器会验证字段,然后根据过滤器检索库存项目列表并将其发送到“DisplayItems”视图。

但是刚进入视图,如果我单击“确认”按钮,它会直接将我发送回“SendItems”视图,而我希望它转到“DisplayItems”控制器方法。为什么?谁能解释我做错了什么?

编辑

我做了一个快速调试会话,我可以确认调试将我发送回“发送项目”控制器方法,而不是点击“显示项目”方法。

4

2 回答 2

1

让我们谈谈如何组织事情以避免每个操作方法的分配超过 1 个。

我不确定我的模型是否正确,但是让我们假设您有一个项目列表,并且您希望用户选择一个项目来显示详细信息,好吗?

更新:有一个POST List为了过滤列表。

您的服务器端会像这样:

public class ItemController : Controller
{
  public ActionResult List()
  {
    //fetch from db
    return View(yourViewModel);
  }

  [HttpPost]
  public ActionResult List(string firstLilPig, int secondLilPig, string thirdLilPig)
  {
    //fetch from db using the little pigs as filters
    return View(yourViewModel);
  }

  public ActionResult Details(int id)
  {
    //fetch one item using the id
    return View(theItemViewModel);
  }
}

这样做,您将有 2 个视图:/Item/List.cshtml/Item/Details.cshtml。您不会对POST List. 它使用相同的 /Item/List.cshtml,变化的是视图模型(您为它传递的数据)。

最后,您浏览/超链接的 URL 如下所示:

  • http://.../item/list
  • http://.../item/details/1

更新

根据您的用例,我推荐以下结构:

搜索
方法:GET
参数:无
查看:搜索

列表
方法:POST
参数:过滤条件
查看:列表或搜索,如果结果为空

请求
方法:POST
参数:项目 ID 和数量列表(来自结果表)
查看:无。将内容保存到数据库并重定向到结果

结果
方法:GET
参数:无视
图:结果。显示上一个请求的结果

笔记:

  1. 顺序为:搜索 > 列表 > 请求 > 结果。列表可能会重定向回搜索
  2. Request > Result 遵循PRG原则。这样,如果用户在结果页面上按 F5,则不会重新提交请求。
  3. 您应该在 Request 的视图模型上工作。它会有一个 ItemRequest 数组,其中有 ItemID 和 Quantity 作为属性。
于 2013-05-16T14:54:33.087 回答
1

我可能对此不满意,但您可以做的一件事是用[HttpGet]and标记您的 Action 方法[HttpPost],以便执行将遵循不同的路径,具体取决于它是原始页面get还是 form post-back,如下所示:

public class HomeController : Controller
{
    // The original page render will go here
    [HttpGet]
    public ActionResult Index()
    {
        return View(new MyModel());
    }

    // The form postback will go here
    [HttpPost]
    public String Index(MyModel model)
    {
        return "Something";
    }
}

这是一个使用常规 HTML 的简单模型:

<div>
    <form method="post">
        <input type="text" name ="FirstName" value ="@Model.FirstName" />
        <input type="submit" value="submit" />
    </form>
</div>

但是你也可以用你的方法做同样的事情Html.BeginForm(将方法设置为'post'而不是默认的'get'),只需指出它应该是 apost而不是 a get,并且它应该路由到相同的操作方法,但使用 post 标签而不是 get 标签。

于 2013-05-16T14:58:15.607 回答