在_Layout上添加对控制器的调用?

时间:2014-04-05 23:32:34

标签: javascript asp.net-mvc twitter-bootstrap

我有一个我的MVC网站使用的布局页面。它没有模型或任何相关的控制器方法。

但现在我想添加一个"搜索"顶部的方框。我无法添加正常的表格"因为它被覆盖了,或者覆盖了内容页面上的任何其他形式。所以我想我可能必须使用Javascript ...调用一个javascript函数然后将查询发送到控制器,然后将用户移动到结果屏幕。

这是正确的方法吗?或者我可以以某种方式使用布局页面中的普通控制器方法调用吗?

1 个答案:

答案 0 :(得分:2)

我们假设你有这些模型:

public class SearchModel
{
    public string SearchTerm { get; set; }
}

public class LoginModel
{
    public string UserName { get; set; }

    public string Password { get; set; }
}

而且你也有这些控制器:

public class HomeController : Controller
{   
    public ActionResult Search(SearchModel model)
    {
        return View();
    }
}

public class AccountController : Controller
{   
    public ActionResult Login(LoginModel model)
    {
        return View();
    }
}

你可以使用这样的东西作为布局视图:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewBag.Title</title>
</head>
<body>

    @using(Html.BeginForm("search", "home", FormMethod.Post, new {}))
    {
        <input type="search" name="SearchTerm" placeholder="Find..." />
        <button type="submit">GO</button>
    }

    @if(!Request.IsAuthenticated)
    {
        using(Html.BeginForm("login", "account", FormMethod.Post, new {}))
        {
            <input type="text" name="UserName" placeholder="..." />
            <input type="password" name="Password" placeholder="..." />
            <button type="submit">GO</button>
        }
    }

    @RenderBody()

</body>
</html>

模型绑定器非常智能,可以将请求参数与正确的模型属性相匹配,即使您没有使用@Html帮助程序来创建HTML控件。您遇到的问题是如何处理无效的登录尝试。似乎典型的工作流程是进行正常的登录操作 - 如果用户在导航栏登录表单中输入了无效的凭据,则可以将用户转储到正确的登录页面。

另一种选择是将搜索和登录表单嵌入为子操作:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewBag.Title</title>
</head>
<body>

    @Html.Action("search", "home")

    @Html.Action("login", "account")

    @RenderBody()

</body>
</html>

如果你走这条路线,你会修改控制器以返回部分视图。这是AccountController的一个实现:

public class AccountController : Controller
{   
    [HttpGet, AllowAnonymous]
    public ActionResult Login(string returnUrl = "")
    {
        return View();
    }

    [HttpPost, AllowAnonymous]
    public ActionResult Login(LoginModel model)
    {
        if(ModelState.IsValid)
        {
            /* valid user credentials */
            return RedirectToAction("index", "home");
        }

        return View(model);
    }

    [AllowAnonymous, ChildActionOnly]
    public ActionResult NavbarLogin()
    {
        return PartialView();
    }
}

注意最后一个动作方法;将其标记为ChildActionOnly可防止浏览器直接请求操作。该方法的视图可能如下所示:

@model Your.Fully.Qualified.Namespace.Models.LoginModel

@using(Html.BeginForm("login", "account", FormMethod.Post, new { }))
{
    @Html.LabelFor(m => m.UserName)
    @Html.TextBoxFor(m => m.UserName)
    @Html.ValidationMessageFor(m => m.UserName)

    @Html.LabelFor(m => m.Password)
    @Html.PasswordFor(m => m.Password)
    @Html.ValidationMessageFor(m => m.Password)

    <button type="submit">Login</button>
}

强类型帮助程序的优点是MVC将创建Unobtrusive Validation库利用的验证data-属性;在布局中包含jqueryval包,任何具有强类型帮助器的视图都会自动获得客户端验证。

在此示例中,&#34;导航栏登录&#34;发布到正常登录操作,因此无效凭据将导致用户显示登录页面,而不是他们最初查看的页面。