在MVC中从控制器传递值到共享视图

5
我需要将一些值从控制器发送到共享视图中,在页面顶部显示。
    [HttpPost]
    [Route("login")]
    public async Task<ActionResult> Login(LogInRequest logInRequest)
    {
        IEnumerable<UserClaim> UserClaims = null;
        User user = null;
        if (ModelState.IsValid)
        {
      user = await GetUserByEmailAndPassword(logInRequest.UserName, logInRequest.Password);
            if (user.Id != 0)
            {
                 showMenu = await ShowLoanMenu(logInRequest);
                if (showMenu)
                {
        ******** I need to send showMenu and user.Name to shared view
             return RedirectToAction(Constants.Views.SearchView, Constants.Views.LoanDriverController);
                }
            }
               .....
              return View(logInRequest);
    }

我不想使用TempData、ViewData、ViewBag或Session,我该如何通过查询字符串或将其添加到模型中发送数据。

以下是其中一种布局:

      <ul>
            <li class="logo">
                <img src="~/Content/Images/logo.png" alt="" />
            </li>
            <li class="nav-item">
                  ***  @if(showmenu is true)
                 {
                    <ul>
                        @Html.ActionLink("Loan Driver", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                    </ul>
                }
            </li>
        </ul>

这是另一种布局:

 <div class="header">
       <div class="master-container">
        <div class="heading">Garage</div>
        <div class="primary-nav">
            <ul>
                <li>******show name of the person</li>
                <li>@Html.ActionLink("Logout", "logout", "Home")</li>
               </ul>
           </div>
        </div>

2
你尝试过使用TempData而不是ViewBag吗? - chamara
1
@chamara TempData 运作良好。谢谢。 - Alma
1
TempData在刷新后会失去其值。 - Alma
@Alma。为用户身份添加声明,并通过扩展方法在视图中查找该声明,以便显示菜单。 - Nkosi
@Tony 我不允许使用这些。 - Alma
显示剩余12条评论
5个回答

1
在您的看法中,您可以像这样从查询字符串中读取值:
@Request.QueryString["name"]

然后,只需要在查询字符串中包含您想要的值即可。当您执行RedirectToAction时,可以很容易地处理它,例如:
return RedirectToAction("Details", new { id = id, name = "value" })

1
我猜你想要当前请求的数据,而不是所有请求的数据,所以接受的答案不是正确的方式。为了在单个请求的范围内与视图或子控制器共享数据,最简单的方法是将数据放入HttpContext.Items中。这样,在同一请求期间,所有视图和子控制器都可以共享这些数据。
HttpContext.Items["UIOptions"] = new UIOptions { ShowMenu = true }; 

你可以使用扩展来抽象化这个过程:

public static class HttpContextExtensions
    {
        public static UIOptions GetUIOptions(this HttpContext httpContext)
        {
            var options = httpContext.Items["UIOptions"] ?? (object) new UIOptions();
            httpContext.Items["UIOptions"] = options;
            return options;
        }
    }

在您的控制器中,设置选项。
HttpContext.GetUIOptions().ShowMenu= true

在你的视图中,像这样访问它:

ViewContext.HttpContext.GetUIOptions()

我通常会进一步抽象,使您可以使用属性进行配置,例如:

[UIOptions(ShowMenu=true)]
public ActionResult MyAction()
{
    return View();
}

所以你编写了一个ActionFilter,它检查操作上的属性,并在ActionExecuting阶段使用属性属性设置httpContext.GetUIOptions()对象的属性。


0
你需要将共享模型传递给你的布局。假设共享模型的定义如下:
public class SharedModel
{
  public string Name {get; set;}
  public bool IsLoggedIn {get; set;}
}

所有其他模型都需要从SharedModel继承,例如AccountModel。

public class AccountModel : SharedModel
{
  public string Password {get; set;}
  public string Username {get; set;}
}

因此,当您将特定模型传递给视图时,共享模型也将传递到共享布局。

 [HttpPost]
    [Route("login")]
    public async Task<ActionResult> Login(LogInRequest logInRequest)
    {
      AccountModel aM = new AccountModel();
      aM.Name = "Murtaza";
      aM.IsLoggedIn = false;
      ....
      ....
      return View(aM):
     }


0
创建一个通用类,定义一个公共静态属性,并从控制器中设置其值,在视图中按如下方式访问: 通用类:
public static class GeneralUtility
{
    /// <summary>
    /// Username
    /// </summary>
    public static string Username = "";
}

控制器:

GeneralUtility.Username ="sandip";

视图:

@if(GeneralUtility.Username=="sandip")
{
    // rest of the logic
}

我认为OP需要的是一个布尔值而不是一个字符串...如果用户已经通过身份验证,用户名始终可用 ;) 这是一个很好的处理方式...我总是在我的项目中包含一个静态类,可以这样使用。+1! - BillRuhl
2
如果您使用静态字符串来显示用户名,则会更改为每个登录的用户 @_@。 - Rafael Marques

0
在这种情况下,相对于静态字段或静态类中的属性,Session 更加适用。您可以为HttpContext.User.Indetity添加扩展方法来显示用户名。
public static class UserExtension
{
    public static void SetDisplayName(this IIdentity identity, string fullName)
    {
        if(HttpContext.Current.User.Identity.IsAuthenticated)
            HttpContext.Current.Items[HttpContext.Current.User.Identity.Name] = fullName;
    }

    public static string GetDisplayName(this IIdentity identity)
    {
        return HttpContext.Current.Items[HttpContext.Current.User.Identity.Name] as string;
    }
}

在控制器中:

public async Task<ActionResult> Login(LogInRequest logInRequest)
{
    IEnumerable<UserClaim> UserClaims = null;
    User user = null;
    if (ModelState.IsValid)
    {
        user = await GetUserByEmailAndPassword(logInRequest.UserName, logInRequest.Password);
        if (user.Id != 0)
        {
            showMenu = await ShowLoanMenu(logInRequest);
            if (showMenu)
            {
                User.Identity.SetDisplayName(user.Name);

并在共享视图中:

<div class="primary-nav">
   <ul>
      <li>User.Identity.GetDisplayName()</li>

OP已经说明不想使用session:我不想使用TempData、ViewData、ViewBag或Session。 - Sandip - Frontend Developer
System.Web.Caching 怎么样? - Mohsen Esmailpour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接