对于MVC来说还是一个新手,我用我认为非常直接的方式遇到了一些绊脚石。
我的_Layout中有一个部分_Header视图。在这里,我想显示一个下拉列表,其中包含根据登录用户填充的项目列表。
在我项目的每个控制器中,我想检索所选的值并显示依赖于此的数据。
我尝试过多次尝试,但仍然陷入不同的位置。我正沿着创建基本控制器的路线来保存我的项目列表和所选项目值(两者都是静态的)。然后,在我的AccountController中,我可以在登录时填充这些值。我可以从其他控制器访问所有这些...但是如何填充我的_Header中的下拉列表?我似乎无法访问这些内容。我甚至走了正确的路线?在经典的ASP中我会将它们存储在viewstate中..
更新 - 根据Marco的建议
从控制器设置的viewbag值在视图中不可用(虽然可访问) - 它总是返回null。我暂时将选择列表更改为一个简单的int,以简化操作。代码
ViewPageBase -
public abstract class ViewPageBase : RazorPage
{
public int SelectedValue
{
get { return (ViewBag.SelectedValue == null ? 0 : ViewBag.SelectedValue); }
set { ViewBag.SelectedValue = value; }
}
}
public abstract class ViewPageBase<TModel> : RazorPage<TModel>
{
public int SelectedValue
{
get { return (ViewBag.SelectedValue == null ? 0 : ViewBag.SelectedValue); }
set { ViewBag.SelectedValue = value; }
}
}
BaseController -
public class BaseController : Controller
{
public int SelectedValue
{
get { return (ViewBag.SelectedValue == null ? 0 : ViewBag.SelectedValue); }
set { ViewBag.SelectedValue = value; }
}
}
AccountController:BaseController -
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (!ModelState.IsValid)
return View(model);
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false);
if (result.Succeeded)
{
SelectedValue = 10;
_logger.LogInformation(1, "User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.IsLockedOut)
{
_logger.LogWarning(2, "User account locked out.");
return View("Lock");
}
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
_Layout -
@{ await Html.RenderPartialAsync("_Header"); }
在_Header中,我只是想读@SelectedValue但是这总是为null(在我的情况下为0,因为我做了空检查)。
答案 0 :(得分:0)
您可以使用以下方法
我认为这有帮助。
答案 1 :(得分:0)
您需要创建一个自定义剃刀视图基类,您的所有视图都将从该基类继承。这是关于它是如何完成的文章:
http://haacked.com/archive/2011/02/21/changing-base-type-of-a-razor-view.aspx/
基本上你会创建一个继承自WebViewPage的类。在此课程中,您将声明一个包含选择列表的属性:
public abstract class CustomWebViewPage : WebViewPage
{
private SelectList _mySelectList;
public SelectList MySelectList
{
get
{
try
{
_mySelectList = (SelectList)ViewBag.MySelectList;
}
catch (Exception)
{
_mySelectList = null;
}
return _mySelectList;
}
}
}
public abstract class CustomWebViewPage<TModel> : WebViewPage<TModel>
{
private SelectList _mySelectList;
public SelectList MySelectList
{
get
{
try
{
_mySelectList = (SelectList)ViewBag.MySelectList;
}
catch (Exception)
{
_mySelectList = null;
}
return _mySelectList;
}
}
}
正如您所看到的,正在从ViewBag中检索此选择列表的值。它不一定是,但这是我最容易证明这个想法。您可以在所做的基本控制器中设置视图包的值。现在每个视图都可以访问此属性。
您唯一要做的就是告诉您的解决方案使用您的新类构建MVC视图。您可以通过在Web配置中添加以下行来执行此操作:
<pages pageBaseType="Project.Namespace.Views.CustomWebViewPage">
其中Project.Namespace.Views是新自定义类所在的命名空间。请注意,此行位于
内<system.web.webPages.razor>
标签,需要将其添加到与您的视图相关的所有web.configs - Views文件夹中的web.configs。
完成所有这些后,您只需执行以下操作:
@MySelectList
在您的视图中访问您的选择列表。祝你好运!