C# Mvc ViewBag - 无法将 null 转换为“bool”,因为它是不可为 null 的值类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19553466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mvc ViewBag - Cannot convert null to 'bool' because it is a non-nullable value type
提问by rism
I want to set a bool to true in the controller when producing a certain view and then alter the header of the view accordingly. This should be dead simple but instead Im getting:
我想在生成某个视图时在控制器中将 bool 设置为 true,然后相应地更改视图的标题。这应该很简单,但我得到了:
Cannot perform runtime binding on a null reference Exception Details: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot perform runtime binding on a null reference
无法对空引用执行运行时绑定异常详细信息:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:无法对空引用执行运行时绑定
All I'm doing is in controller:
我所做的只是在控制器中:
[AllowAnonymous]
public ActionResult Register()
{
ViewBag.IsRegistration = true;
return View();
}
and then in view:
然后在视图中:
@if (ViewBag.IsRegistration)
{
<legend>Register using another service.</legend>
}
else
{
<legend>Use another service to log in.</legend>
}
but it fails on:
但它失败了:
@if (ViewBag.IsRegistration)
UPDATE
更新
Relevant Controller Code:
相关控制器代码:
[AllowAnonymous]
public ActionResult Register()
{
ViewBag.IsRegistration = "true";
return View();
}
The register view:
寄存器视图:
@model Mvc.Models.RegisterViewModel
@{
Layout = "~/Views/Shared/_AccountLayout.cshtml";
ViewBag.Title = "Register";
}
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
</hgroup>
<div class="row">
<div class="col-lg-6">
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<fieldset class="form-horizontal">
<legend>Create a new account.</legend>
<div class="control-group">
@Html.LabelFor(m => m.UserName, new { @class = "control-label" })
<div class="controls">
@Html.TextBoxFor(m => m.UserName)
</div>
</div>
<div class="control-group">
@Html.LabelFor(m => m.Password, new { @class = "control-label" })
<div class="controls">
@Html.PasswordFor(m => m.Password)
</div>
</div>
<div class="control-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "control-label" })
<div class="controls">
@Html.PasswordFor(m => m.ConfirmPassword)
</div>
</div>
<div class="form-actions no-color">
<input type="submit" value="Register" class="btn" />
</div>
</fieldset>
}
</div>
<div class="col-lg-6"></div>
<section id="socialLoginForm">
@Html.Action("ExternalLoginsList", new { ReturnUrl = ViewBag.ReturnUrl })
</section>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
The ExternalLoginsList partial:
ExternalLoginsList 部分:
@using Glimpse.Core.Extensions
@using Microsoft.Owin.Security
@model ICollection<AuthenticationDescription>
@if (Model.Count == 0)
{
<div class="message-info">
<p>There are no external authentication services configured</p>
</div>
}
else
{
using (Html.BeginForm("ExternalLogin", "Account", new { ReturnUrl = ViewBag.ReturnUrl }))
{
@Html.AntiForgeryToken()
<fieldset id="socialLoginList">
@if (!string.IsNullOrEmpty(ViewBag.IsRegistration))
{
<legend>Register using another service.</legend>
}
else
{
<legend>Use another service to log in.</legend>
}
<p>
@foreach (AuthenticationDescription p in Model) {
<button type="submit" class="btn" id="@p.AuthenticationType" name="provider" value="@p.AuthenticationType" title="Log in using your @p.Caption account">@p.AuthenticationType</button>
}
</p>
</fieldset>
}
}
采纳答案by acfrancis
Try:
尝试:
@if (ViewBag.IsRegistration == true)
回答by Flood Gravemind
Booleans in Viewbag are always tricky. Try this instead
Viewbag 中的布尔值总是很棘手。试试这个
[AllowAnonymous]
public ActionResult Register()
{
ViewBag.Registration = "x";//x or whatever
return View();
}
@if (!String.IsNullorEmpty(ViewBag.Registration))
{
<legend>Register using another service.</legend>
}
else
{
<legend>Use another service to log in.</legend>
}
回答by Boluc Papuccuoglu
Try this:
尝试这个:
Replace the line in your controller:
替换控制器中的行:
ViewBag.IsRegistration = true;
with
和
ViewBag.IsRegistration = new bool?(true);
and replace the line in your view:
并替换您视图中的行:
@if (ViewBag.IsRegistration)
with
和
@if ((ViewBag.IsRegistration as bool?).Value)
Effectively you are putting a nullable bool in the ViewBag and then unwrapping it.
实际上,您将一个可为空的 bool 放入 ViewBag 然后展开它。
回答by Nenad
Simply check for null
before checking for true
:
null
在检查之前简单地检查true
:
if (ViewBag.IsRegistration != null && ViewBag.IsRegistration)
回答by rism
Ok so as per Floods suggestion in comments, I need to pass the arguments around. The ViewBag from the parent View does not flow through to partial views.
好的,根据评论中的 Floods 建议,我需要传递参数。来自父视图的 ViewBag 不会流到局部视图。
So in the code for the Register View I needed to change from
所以在注册视图的代码中,我需要从
<section id="socialLoginForm">
@Html.Action("ExternalLoginsList", new {ReturnUrl = ViewBag.ReturnUrl})
</section>
to
到
<section id="socialLoginForm">
@Html.Action("ExternalLoginsList",
new {ReturnUrl = ViewBag.ReturnUrl,
IsRegistering = @ViewBag.IsRegistering })
</section>
Then go into my account controller and change from:
然后进入我的帐户控制器并更改:
[AllowAnonymous]
[ChildActionOnly]
public ActionResult ExternalLoginsList(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return (ActionResult)PartialView("_ExternalLoginsListPartial", new List<AuthenticationDescription>(AuthenticationManager.GetExternalAuthenticationTypes()));
}
to
到
[AllowAnonymous]
[ChildActionOnly]
public ActionResult ExternalLoginsList(string returnUrl, string isRegistering) {
ViewBag.IsRegistering = (isRegistering.ToLower() == "true");
ViewBag.ReturnUrl = returnUrl;
return (ActionResult)PartialView("_ExternalLoginsListPartial", new List<AuthenticationDescription>(AuthenticationManager.GetExternalAuthenticationTypes()));
}
Then in the ExternalLogins I can just:
然后在 ExternalLogins 我可以:
@if (ViewBag.IsRegistering)
as necessary.
有必要的。
So Im effectively passing the IsRegistering bool from controller to main view then back up to action method on controller then into ViewBag which allow me to access the bool in the child partial view.
所以我有效地将 IsRegistering bool 从控制器传递到主视图,然后返回到控制器上的操作方法,然后进入 ViewBag,这允许我访问子局部视图中的 bool。
Many thanks.
非常感谢。
回答by Imran
Try TempData instead of ViewBag.
尝试使用 TempData 而不是 ViewBag。
Change your code from
更改您的代码
Controller
控制器
ViewBag.IsRegistration=true;
to
到
TempData["IsReg"]=true;
and in View
并在视图中
@if((bool)TempData["IsReg"])
It seems that you are using the value in child partial view and you are adding the data in parent action.The values in viewbag cannot pass out data from one action to anothers action's view. While TempData use session it can be used to pass data to one action to another actions view.
似乎您正在使用子局部视图中的值,并且正在父操作中添加数据。viewbag 中的值无法将数据从一个操作传递到另一个操作的视图。当 TempData 使用 session 时,它可用于将数据传递给一个动作到另一个动作视图。
回答by Spartak N.
Maybe so:
可能是吧:
@if ((ViewBag.IsRegistration != null) && (ViewBag.IsRegistration is bool) && (bool)ViewBag.IsRegistration)
{
}
回答by jfren484
I know this is an old question, but I think I have an elegant answer, so in case anyone reads this after searching, here is mine:
我知道这是一个老问题,但我想我有一个优雅的答案,所以万一有人在搜索后读到这个,这是我的:
@if (ViewBag.IsRegistration ?? false)