`Model.plans.Count` 抛出类型为'System.NullReferenceException` 的异常
`Model.plans.Count` threw an exception of type 'System.NullReferenceException`
我正在尝试将字符串对象列表显示为复选框。我有两个项目,ASP.NET Core MVC 应用程序项目和 ASP.NET Core Web API 都 运行 在 5.0 NET Core 上运行。在 MVC 项目中,我正在调用 Web API 项目,它将在其中创建一个新的对象列表。然后在我的 MVC 项目中我做了一个项目引用来调用视图中的控制器。当我 运行 应用程序时,MVC 将命中它调用 API 项目的行。在我的 API 控制器的 GetPlan()
方法中存储新创建的对象后,我尝试在我的 MVC 视图中将这些创建的对象显示为复选框。但是,当我这样做时,它说 Model.plans.Count
抛出了 System.NullReferenceException
类型的异常。然后进一步查看它,它只会告诉我:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Microsoft.AspNetCore.Mvc.Razor.RazorPage.Model.get returned null.
我不明白为什么我在已经创建了新对象的情况下返回 null。
MVC 项目:
Controller
我打电话给 API:
public IActionResult SecIndex()
{
// call planapi
var result = _planServiceClient.RetrievePlans().Result;
_logger.Log(LogLevel.Information, "Reached the Second Page View....");
return View();
}
然后是我的 API 项目:
Model class for ViewPhoneNumberInput
:
public class ViewPhoneNumberInput
{
[Required(ErrorMessage = "You did not enter your phone number! Please enter your phone number!")]
public String PhoneNumber { get; set; }
public List<Plans> plans { get; set; }
}
我的计划模型class:
public class Plans
{
public int PlanId { get; set; }
public string PlanName { get; set; }
}
Controller
对于 api:
[HttpGet]
[Route("AvailablePlans")]
public ActionResult GetPlan()
{
var _model = new ViewPhoneNumberInput();
_model.plans = new List<Plans>();
_model.plans.Add(new Plans { PlanId = 1, PlanName = "Internet" });
_model.plans.Add(new Plans { PlanId = 2, PlanName = "TV & Streaming" });
_model.plans.Add(new Plans { PlanId = 3, PlanName = "Mobile" });
_model.plans.Add(new Plans { PlanId = 4, PlanName = "Home Security" });
_model.plans.Add(new Plans { PlanId = 5, PlanName = "Home Phone" });
var plansAvailable = JsonSerializer.Serialize(_model.plans);
_logger.Log(LogLevel.Information, "Response-Body: {@Response-Body}", plansAvailable);
return Ok(_model.plans);
}
上面 _model.plans
将保存创建的新对象的值,所以我去我的 MVC 视图项目调用它,这样我就可以显示它,但这就是它说 Model.plans.Count
引发了类型为“System.NullReferenceException”的异常。
View
对于 MVC 项目:
@model Plan.API.Models.ViewPhoneNumberInput
<h2>Second page</h2>
@using (Html.BeginForm())
{
for (int i = 0; i < Model.plans.Count; i++)
{
<input type="checkbox" id="@Model.plans[i].PlanId" name="Model.plans[i].PlanId" />
<label for="Model.plans[i].PlanId"> @Model.plans[i].PlanName </label> <br />
}
@Html.TextBoxFor(r => r.PhoneNumber)
<input id="Button" type="submit" value="Next" />
<p> @Html.ValidationMessageFor(r => r.PhoneNumber) </p>
}
为什么它告诉我这个而不是实际保存来自 API 控制器的新创建的值?
在实施下面的建议时,我能够看到 PhoneNumber 的值,但对于 Plans,它显示为空(当鼠标悬停在 post SecIndex 中的 phoneNumberInput
上时)。
我的检索计划():
public async Task<List<Plan.API.Models.Plans>> RetrievePlans()
{
var response = await _httpClient.GetAsync("api/plans/AvailablePlans");
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<List<Plan.API.Models.Plans>>(result);
return json;
}
我的更新 SecIndex() with Post SecIndex()
:
public IActionResult SecIndex()
{
// call planapi
var result = _planServiceClient.RetrievePlans().Result;
_logger.Log(LogLevel.Information, "Reached the Second Page View....");
return View(new Plan.API.Models.ViewPhoneNumberInput { plans = result });//So that you don't need to change the model in the view and the parameter type in the HttpPost Action.
}
[HttpPost]
public IActionResult SecIndex(Plan.API.Models.ViewPhoneNumberInput phoneNumberInput)
{
try
{
if (ModelState.IsValid)
{
_logger.Log(LogLevel.Information, "User successfully entered their phone number.");
return RedirectToAction("FinalIndex", "Final");
}
else
{
_logger.Log(LogLevel.Error, "User missed to enter their phone number");
throw new Exception("User did not enter a phone number in the textfield!");
}
}
catch(Exception ex)
{
_logger.LogError(ex, "Empty textfield!");
return View(phoneNumberInput);
}
}
SecIndex.cshtml
@model Plan.API.Models.ViewPhoneNumberInput
<h2>Second page</h2>
@using (Html.BeginForm())
{
for (int i = 0; i < Model.plans.Count; i++)
{
<input type="checkbox" id="@Model.plans[i].PlanId" />
<input hidden value="@Model.plans[i].PlanId" />
<input hidden value="@Model.plans[i].PlanName" />
<label for="Model.plans[i].PlanId"> @Model.plans[i].PlanName </label>
<br />
}
@Html.TextBoxFor(r => r.PhoneNumber)
<input id="Button" type="submit" value="Next" />
<p> @Html.ValidationMessageFor(r => r.PhoneNumber) </p>
}
<script>
$('form').submit(function () {
var count = 0;
$('input[type=checkbox]').each(function () {
if (this.checked) {
this.nextElementSibling.name = "plans["+count+"].PlanId";
this.nextElementSibling.nextElementSibling.name = "plans[" + count + "].PlanName";
count++;
}
});
});
</script>
我的 API GetPlan 控制器:
[HttpGet]
[Route("AvailablePlans")]
public List<Plans> GetPlan()
{
var _model = new ViewPhoneNumberInput();
_model.plans = new List<Plans>();
_model.plans.Add(new Plans { PlanId = 1, PlanName = "Internet" });
_model.plans.Add(new Plans { PlanId = 2, PlanName = "TV & Streaming" });
_model.plans.Add(new Plans { PlanId = 3, PlanName = "Mobile" });
_model.plans.Add(new Plans { PlanId = 4, PlanName = "Home Security" });
_model.plans.Add(new Plans { PlanId = 5, PlanName = "Home Phone" });
var plansAvailable = JsonSerializer.Serialize(_model.plans);
_logger.Log(LogLevel.Information, "Response-Body: {@Response-Body}", plansAvailable);
return _model.plans;
}
@MarCo 问题是你没有通过你的模式
return View(result);
这是一个工作演示:
api方法:
[HttpGet]
[Route("AvailablePlans")]
public List<Plan.API.Models.Plans> GetPlan()
{
var _model = new ViewPhoneNumberInput();
_model.plans = new List<Plans>();
_model.plans.Add(new Plans { PlanId = 1, PlanName = "Internet" });
_model.plans.Add(new Plans { PlanId = 2, PlanName = "TV & Streaming" });
_model.plans.Add(new Plans { PlanId = 3, PlanName = "Mobile" });
_model.plans.Add(new Plans { PlanId = 4, PlanName = "Home Security" });
_model.plans.Add(new Plans { PlanId = 5, PlanName = "Home Phone" });
var plansAvailable = JsonSerializer.Serialize(_model.plans);
_logger.Log(LogLevel.Information, "Response-Body: {@Response-Body}", plansAvailable);
return _model.plans;
}
控制器动作:
public IActionResult SecIndex()
{
// call planapi
var result = _planServiceClient.RetrievePlans().Result;
_logger.Log(LogLevel.Information, "Reached the Second Page View....");
return View(new ViewPhoneNumberInput { plans=result});//So that you don't need to change the model in the view and the parameter type in the HttpPost Action.
}
查看:
@model Plan.API.Models.ViewPhoneNumberInput
<h2>Second page</h2>
@using (Html.BeginForm())
{
for (int i = 0; i < Model.plans.Count; i++)
{
<input type="checkbox" id="@Model.plans[i].PlanId" />
<input hidden value="@Model.plans[i].PlanId"/>
<input hidden value="@Model.plans[i].PlanName" />
<label for="Model.plans[i].PlanId"> @Model.plans[i].PlanName </label>
<br />
}
@Html.TextBoxFor(r => r.PhoneNumber)
<input id="Button" type="submit" value="Next" />
<p> @Html.ValidationMessageFor(r => r.PhoneNumber) </p>
}
<script>
$('form').submit(function () {
var count = 0;
$('input[type=checkbox]').each(function () {
if (this.checked) {
this.nextElementSibling.name = "plans["+count+"].PlanId";
this.nextElementSibling.nextElementSibling.name = "plans[" + count + "].PlanName";
count++;
}
});
});
</script>
结果:
我正在尝试将字符串对象列表显示为复选框。我有两个项目,ASP.NET Core MVC 应用程序项目和 ASP.NET Core Web API 都 运行 在 5.0 NET Core 上运行。在 MVC 项目中,我正在调用 Web API 项目,它将在其中创建一个新的对象列表。然后在我的 MVC 项目中我做了一个项目引用来调用视图中的控制器。当我 运行 应用程序时,MVC 将命中它调用 API 项目的行。在我的 API 控制器的 GetPlan()
方法中存储新创建的对象后,我尝试在我的 MVC 视图中将这些创建的对象显示为复选框。但是,当我这样做时,它说 Model.plans.Count
抛出了 System.NullReferenceException
类型的异常。然后进一步查看它,它只会告诉我:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Microsoft.AspNetCore.Mvc.Razor.RazorPage.Model.get returned null.
我不明白为什么我在已经创建了新对象的情况下返回 null。
MVC 项目:
Controller
我打电话给 API:
public IActionResult SecIndex()
{
// call planapi
var result = _planServiceClient.RetrievePlans().Result;
_logger.Log(LogLevel.Information, "Reached the Second Page View....");
return View();
}
然后是我的 API 项目:
Model class for ViewPhoneNumberInput
:
public class ViewPhoneNumberInput
{
[Required(ErrorMessage = "You did not enter your phone number! Please enter your phone number!")]
public String PhoneNumber { get; set; }
public List<Plans> plans { get; set; }
}
我的计划模型class:
public class Plans
{
public int PlanId { get; set; }
public string PlanName { get; set; }
}
Controller
对于 api:
[HttpGet]
[Route("AvailablePlans")]
public ActionResult GetPlan()
{
var _model = new ViewPhoneNumberInput();
_model.plans = new List<Plans>();
_model.plans.Add(new Plans { PlanId = 1, PlanName = "Internet" });
_model.plans.Add(new Plans { PlanId = 2, PlanName = "TV & Streaming" });
_model.plans.Add(new Plans { PlanId = 3, PlanName = "Mobile" });
_model.plans.Add(new Plans { PlanId = 4, PlanName = "Home Security" });
_model.plans.Add(new Plans { PlanId = 5, PlanName = "Home Phone" });
var plansAvailable = JsonSerializer.Serialize(_model.plans);
_logger.Log(LogLevel.Information, "Response-Body: {@Response-Body}", plansAvailable);
return Ok(_model.plans);
}
上面 _model.plans
将保存创建的新对象的值,所以我去我的 MVC 视图项目调用它,这样我就可以显示它,但这就是它说 Model.plans.Count
引发了类型为“System.NullReferenceException”的异常。
View
对于 MVC 项目:
@model Plan.API.Models.ViewPhoneNumberInput
<h2>Second page</h2>
@using (Html.BeginForm())
{
for (int i = 0; i < Model.plans.Count; i++)
{
<input type="checkbox" id="@Model.plans[i].PlanId" name="Model.plans[i].PlanId" />
<label for="Model.plans[i].PlanId"> @Model.plans[i].PlanName </label> <br />
}
@Html.TextBoxFor(r => r.PhoneNumber)
<input id="Button" type="submit" value="Next" />
<p> @Html.ValidationMessageFor(r => r.PhoneNumber) </p>
}
为什么它告诉我这个而不是实际保存来自 API 控制器的新创建的值?
在实施下面的建议时,我能够看到 PhoneNumber 的值,但对于 Plans,它显示为空(当鼠标悬停在 post SecIndex 中的 phoneNumberInput
上时)。
我的检索计划():
public async Task<List<Plan.API.Models.Plans>> RetrievePlans()
{
var response = await _httpClient.GetAsync("api/plans/AvailablePlans");
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<List<Plan.API.Models.Plans>>(result);
return json;
}
我的更新 SecIndex() with Post SecIndex()
:
public IActionResult SecIndex()
{
// call planapi
var result = _planServiceClient.RetrievePlans().Result;
_logger.Log(LogLevel.Information, "Reached the Second Page View....");
return View(new Plan.API.Models.ViewPhoneNumberInput { plans = result });//So that you don't need to change the model in the view and the parameter type in the HttpPost Action.
}
[HttpPost]
public IActionResult SecIndex(Plan.API.Models.ViewPhoneNumberInput phoneNumberInput)
{
try
{
if (ModelState.IsValid)
{
_logger.Log(LogLevel.Information, "User successfully entered their phone number.");
return RedirectToAction("FinalIndex", "Final");
}
else
{
_logger.Log(LogLevel.Error, "User missed to enter their phone number");
throw new Exception("User did not enter a phone number in the textfield!");
}
}
catch(Exception ex)
{
_logger.LogError(ex, "Empty textfield!");
return View(phoneNumberInput);
}
}
SecIndex.cshtml
@model Plan.API.Models.ViewPhoneNumberInput
<h2>Second page</h2>
@using (Html.BeginForm())
{
for (int i = 0; i < Model.plans.Count; i++)
{
<input type="checkbox" id="@Model.plans[i].PlanId" />
<input hidden value="@Model.plans[i].PlanId" />
<input hidden value="@Model.plans[i].PlanName" />
<label for="Model.plans[i].PlanId"> @Model.plans[i].PlanName </label>
<br />
}
@Html.TextBoxFor(r => r.PhoneNumber)
<input id="Button" type="submit" value="Next" />
<p> @Html.ValidationMessageFor(r => r.PhoneNumber) </p>
}
<script>
$('form').submit(function () {
var count = 0;
$('input[type=checkbox]').each(function () {
if (this.checked) {
this.nextElementSibling.name = "plans["+count+"].PlanId";
this.nextElementSibling.nextElementSibling.name = "plans[" + count + "].PlanName";
count++;
}
});
});
</script>
我的 API GetPlan 控制器:
[HttpGet]
[Route("AvailablePlans")]
public List<Plans> GetPlan()
{
var _model = new ViewPhoneNumberInput();
_model.plans = new List<Plans>();
_model.plans.Add(new Plans { PlanId = 1, PlanName = "Internet" });
_model.plans.Add(new Plans { PlanId = 2, PlanName = "TV & Streaming" });
_model.plans.Add(new Plans { PlanId = 3, PlanName = "Mobile" });
_model.plans.Add(new Plans { PlanId = 4, PlanName = "Home Security" });
_model.plans.Add(new Plans { PlanId = 5, PlanName = "Home Phone" });
var plansAvailable = JsonSerializer.Serialize(_model.plans);
_logger.Log(LogLevel.Information, "Response-Body: {@Response-Body}", plansAvailable);
return _model.plans;
}
@MarCo 问题是你没有通过你的模式
return View(result);
这是一个工作演示:
api方法:
[HttpGet]
[Route("AvailablePlans")]
public List<Plan.API.Models.Plans> GetPlan()
{
var _model = new ViewPhoneNumberInput();
_model.plans = new List<Plans>();
_model.plans.Add(new Plans { PlanId = 1, PlanName = "Internet" });
_model.plans.Add(new Plans { PlanId = 2, PlanName = "TV & Streaming" });
_model.plans.Add(new Plans { PlanId = 3, PlanName = "Mobile" });
_model.plans.Add(new Plans { PlanId = 4, PlanName = "Home Security" });
_model.plans.Add(new Plans { PlanId = 5, PlanName = "Home Phone" });
var plansAvailable = JsonSerializer.Serialize(_model.plans);
_logger.Log(LogLevel.Information, "Response-Body: {@Response-Body}", plansAvailable);
return _model.plans;
}
控制器动作:
public IActionResult SecIndex()
{
// call planapi
var result = _planServiceClient.RetrievePlans().Result;
_logger.Log(LogLevel.Information, "Reached the Second Page View....");
return View(new ViewPhoneNumberInput { plans=result});//So that you don't need to change the model in the view and the parameter type in the HttpPost Action.
}
查看:
@model Plan.API.Models.ViewPhoneNumberInput
<h2>Second page</h2>
@using (Html.BeginForm())
{
for (int i = 0; i < Model.plans.Count; i++)
{
<input type="checkbox" id="@Model.plans[i].PlanId" />
<input hidden value="@Model.plans[i].PlanId"/>
<input hidden value="@Model.plans[i].PlanName" />
<label for="Model.plans[i].PlanId"> @Model.plans[i].PlanName </label>
<br />
}
@Html.TextBoxFor(r => r.PhoneNumber)
<input id="Button" type="submit" value="Next" />
<p> @Html.ValidationMessageFor(r => r.PhoneNumber) </p>
}
<script>
$('form').submit(function () {
var count = 0;
$('input[type=checkbox]').each(function () {
if (this.checked) {
this.nextElementSibling.name = "plans["+count+"].PlanId";
this.nextElementSibling.nextElementSibling.name = "plans[" + count + "].PlanName";
count++;
}
});
});
</script>
结果: