我正在构建一个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”控制器方法。为什么?谁能解释一下我做错了什么?
修改
我做了一个快速的调试会话,我可以确认调试将我发送回“Send Items”控制器方法,而不是点击“DisplayItems”方法。
答案 0 :(得分: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 :(得分:1)
我可能不喜欢这个,但你可以做的一件事是用[HttpGet]
和[HttpPost]
标记你的Action方法,这样执行将遵循不同的路径,具体取决于它是否&#39 ; s原始页面get
或表单post
- 返回,如:
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
(将方法设置为&#39;发布&#39;而不是默认&#39; get&#39;)真的做同样的事情,只需指明它应该是post
而不是get
,它应该路由到相同的操作方法,但使用post标记而不是get标记。