MVC5绑定问题

时间:2015-03-18 12:02:16

标签: asp.net-mvc-5

我正在尝试在我正在重写的网站上设置一些基本导航,但我遇到了一堵砖墙,并且不明白为什么这不起作用。我在其他六个地方做了类似的事情,但它没有用。

我想要做的是,如果我的文章有下一个或以前的ID,我想要显示带有适当的前进/后退导航箭头的导航栏或允许用户导航页面的任何内容。

ViewModel

public class NavViewModel
{
    public int NextID { get; set; }
    public int PreviousID { get; set; }
    public string NextString { get; set; }
    public string PreviousString { get; set; }
    public bool SelectedMode { get; set; }

    public NavViewModel() { }
 }

视图

@Html.HiddenFor(model => model.NavigationViewModel.PreviousID)
@Html.HiddenFor(model => model.NavigationViewModel.NextID)
<div class="post-nav">
    @if (@Model.NavigationViewModel.PreviousString != null)
    {
        using (Html.BeginForm("SinglePost", "Article", FormMethod.Post, new { @nvm = Model.NavigationViewModel }))
        {
            <input type="submit" class="btn btn-default" value="@Model.NavigationViewModel.PreviousString" />
        }
    }
    @if (@Model.NavigationViewModel.NextString != null)
    {
        using (Html.BeginForm("SinglePost", "Article", FormMethod.Post, new { nvm = @Model.NavigationViewModel }))
        {
            <input type="submit" class="btn btn-default" value="@Model.NavigationViewModel.NextString" />
        }
    }
</div>

和控制器

    [HttpPost]
    public ActionResult SinglePost(NavViewModel nvm)
    {
        return RedirectToAction("SinglePost", "Article", new { postID = nvm.PreviousID });
    }

我尝试过传回bool,ID,ViewModel,它们都是null或包含空值。 我在PartialView中使用了这段代码,因为它无法正常工作,所以我将它移动到调用视图的一个级别,它具有相同的结果。

2 个答案:

答案 0 :(得分:0)

尝试将隐藏的输入移动到表单

<div class="post-nav">
    @if (@Model.NavigationViewModel.PreviousString != null)
    {
        using (Html.BeginForm("SinglePost", "Article", FormMethod.Post, new { @nvm = Model.NavigationViewModel }))
        {
            @Html.HiddenFor(model => model.NavigationViewModel.PreviousID)
            <input type="submit" class="btn btn-default" value="@Model.NavigationViewModel.PreviousString" />
        }
    }
    @if (@Model.NavigationViewModel.NextString != null)
    {
        using (Html.BeginForm("SinglePost", "Article", FormMethod.Post, new { nvm = @Model.NavigationViewModel }))
        {
            @Html.HiddenFor(model => model.NavigationViewModel.NextID)
            <input type="submit" class="btn btn-default" value="@Model.NavigationViewModel.NextString" />
        }
    }
</div>

答案 1 :(得分:0)

您已声明要导航到下一个和上一个项目,因此使用表单和输入并提交到POST方法是不合适的。而是使用链接导航到GET方法,传递上一个或下一个项目的ID。

@if (@Model.NavigationViewModel.PreviousString != null)
{
    @Html.ActionLink(Model.NavigationViewModel.PreviousString, "SinglePost", "Article", new { postID = Model.NavigationViewModel.PreviousID }, null)
}
@if (@Model.NavigationViewModel.NextString != null)
{
    @Html.ActionLink(Model.NavigationViewModel.NextString , "SinglePost", "Article", new { postID = Model.NavigationViewModel.NextID }, null)
}

当您检查为<form>标记生成的html时,代码不起作用的原因将很明显。您生成属性nvm="YourAssembly.NavigationViewModel"(不是路线值)。如果您使用正确的重载来生成路由值,那将是

using (Html.BeginForm("SinglePost", "Article", new { @nvm = Model.NavigationViewModel }))

它仍然会失败,因为它会生成类似于(取决于你的路线)action="/Article/SinglePost?nvm=YourAssembly.NavigationViewModel"的内容,所以当你回发时,DefaultModelBinder会尝试分配字符串&#34; YourAssembly.NavigationViewModel& #34;参数nvm,但nvm是一个复杂的对象,而不是字符串,因此绑定将失败。

您可以使用

使POST方法有效
using (Html.BeginForm("SinglePost", "Article", Model.NavigationViewModel))

然而,这只会通过回发不必要的数据来降低性能,如果您的模型包含属于复杂对象或集合的属性,那么无论如何它都会失败,所以不要这样做。

最后,如果你想让链接看起来像一个按钮,那么使用css设置它的样式。