Asp.net 使用 TemData.Keep() 时出现核心 HTTP 500 错误
Asp.net core HTTP 500 ERROR When TemData.Keep() is Used
城市控制器
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MVC.Models;
namespace MVC.Controllers
{
public class CityController : Controller
{
private readonly ILogger<CityController> _logger;
public CityController(ILogger<CityController> logger)
{
_logger = logger;
}
public IActionResult CitiesOnMap()
{
List<City> cities = new List<City>();
cities.Add(new City { CityName = "Hatay", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Konya", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Istanbul", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Izmir", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Samsun", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Antalya", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Bursa", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Manisa", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Mersin", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Ankara", Latitude = 123, Longtitude = 435 });
TempData["cities"] = cities;
return View();
}
[HttpPost]
public IActionResult CitiesOnMap(string SelectedCity)
{
if (TempData["cities"] != null)
{
foreach (var redirectedCity in TempData["cities"] as List<City>)
{
if (String.Equals(redirectedCity.CityName, SelectedCity))
{
TempData["selectedCity"] = redirectedCity;
return RedirectToAction(redirectedCity.CityName, "City");
}
}
}
return RedirectToAction(SelectedCity, "City"); ;
}
public IActionResult Hatay()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
在我的索引页中,有一个用于选择地图的下拉菜单。用户选择一个地图并单击按钮,然后我使用 RedirectToAction 使用此 CityController 重定向 CitiesOnMap.cshtml。
CitiesOnMap.cshtml
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
ViewData["Title"] = "CitiesOnMap";
}
<div class="text-center pt-5">
<h1 class="display-4 pb-2 ">LET'S SEE THE CITIES!</h1>
<p class="pb-3">Now, Please Choose A City You Want to See on Map.</p>
<h3> @TempData["SelectedMap"] </h3>
<div class="text-center mx-auto pt-5">
<form asp-action="CitiesOnMap" asp-controller="City" method="post">
<div class="row">
<div class="col-9 mx-auto">
<select id="drpEmpList" name="SelectedCity" class="form-control">
<option disabled selected hidden>Choose a City </option>
@foreach (var name in TempData["cities"] as List<MVC.Models.City>)
{
<option>@name.CityName </option>
}
</select>
<input type="hidden" />
</div>
</div>
<div class="row">
<div class="col-md-12 pt-4">
<input type="submit" name="btnSubmit" value="Let's See" class="btn btn-success btn-lg" />
</div>
</div>
</form>
</div>
</div>
我发送的城市列表是我的城市模型的 类。在此页面上,用户从 CitiesOnMap.cshtml 文件的下拉列表中选择一个城市。选择后,我想将用户重定向到正确的城市页面。但是当用户 select 提交按钮时,如果我不使用 TempData["cities"].Keep() 方法,.net 会抛出一个 NullReferenceError 因为我无法在使用它之后再次保留我的数据我知道。如果我使用 TempData["cities"].Keep() 方法,我会收到 HTTP 500 错误。而且我想我必须序列化我的 TempData["cities"] 但我很困惑我有很多问题:( 请帮助我
首先,您的代码犯了一个错误,您无法通过 TempData["KeyName"]
重定向到另一个控制器操作。否则会return 500错误,下面的错误message.That是因为TempData
使用了Session
,它本身使用了IDistributedCache
。 IDistributedCache
没有接受对象或序列化对象的能力:
InvalidOperationException: The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer' cannot serialize an object of type ....
这是一个使用 JSON.Net 的工作演示(您也可以使用 System.Text.Json):
public IActionResult CitiesOnMap()
{
List<City> cities = new List<City>();
//....
cities.Add(new City { CityName = "Ankara", Latitude = 123, Longtitude = 435 });
//Serialize manually by JSON.Net....
TempData["cities"] = Newtonsoft.Json.JsonConvert.SerializeObject(cities);
TempData.Keep("cities");
return View();
}
[HttpPost]
public IActionResult CitiesOnMap(string SelectedCity)
{
if (TempData["cities"] != null)
{
foreach (var redirectedCity in JsonConvert.DeserializeObject<List<City>>(TempData["cities"] as string))
{
if (String.Equals(redirectedCity.CityName, SelectedCity))
{
//not sure what is your selected city page
//but if you redirect to another action
//you also need to serialize the model data manually
TempData["selectedCity"] = JsonConvert.SerializeObject(redirectedCity);
return RedirectToAction(redirectedCity.CityName, "City");
}
}
}
return RedirectToAction(SelectedCity, "City"); ;
}
CitiesOnMap.cshtml:
<form asp-action="CitiesOnMap" asp-controller="City" method="post">
<div class="row">
<div class="col-9 mx-auto">
<select id="drpEmpList" name="SelectedCity" class="form-control">
<option disabled selected hidden>Choose a City </option>
@foreach (var name in
Newtonsoft.Json.JsonConvert.DeserializeObject<List<MVC.Models.City>>(TempData["cities"] as string))
{
<option>@name.CityName </option>
}
</select>
</div>
</div>
</form>
城市控制器
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MVC.Models;
namespace MVC.Controllers
{
public class CityController : Controller
{
private readonly ILogger<CityController> _logger;
public CityController(ILogger<CityController> logger)
{
_logger = logger;
}
public IActionResult CitiesOnMap()
{
List<City> cities = new List<City>();
cities.Add(new City { CityName = "Hatay", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Konya", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Istanbul", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Izmir", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Samsun", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Antalya", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Bursa", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Manisa", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Mersin", Latitude = 123, Longtitude = 435 });
cities.Add(new City { CityName = "Ankara", Latitude = 123, Longtitude = 435 });
TempData["cities"] = cities;
return View();
}
[HttpPost]
public IActionResult CitiesOnMap(string SelectedCity)
{
if (TempData["cities"] != null)
{
foreach (var redirectedCity in TempData["cities"] as List<City>)
{
if (String.Equals(redirectedCity.CityName, SelectedCity))
{
TempData["selectedCity"] = redirectedCity;
return RedirectToAction(redirectedCity.CityName, "City");
}
}
}
return RedirectToAction(SelectedCity, "City"); ;
}
public IActionResult Hatay()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
在我的索引页中,有一个用于选择地图的下拉菜单。用户选择一个地图并单击按钮,然后我使用 RedirectToAction 使用此 CityController 重定向 CitiesOnMap.cshtml。
CitiesOnMap.cshtml
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
ViewData["Title"] = "CitiesOnMap";
}
<div class="text-center pt-5">
<h1 class="display-4 pb-2 ">LET'S SEE THE CITIES!</h1>
<p class="pb-3">Now, Please Choose A City You Want to See on Map.</p>
<h3> @TempData["SelectedMap"] </h3>
<div class="text-center mx-auto pt-5">
<form asp-action="CitiesOnMap" asp-controller="City" method="post">
<div class="row">
<div class="col-9 mx-auto">
<select id="drpEmpList" name="SelectedCity" class="form-control">
<option disabled selected hidden>Choose a City </option>
@foreach (var name in TempData["cities"] as List<MVC.Models.City>)
{
<option>@name.CityName </option>
}
</select>
<input type="hidden" />
</div>
</div>
<div class="row">
<div class="col-md-12 pt-4">
<input type="submit" name="btnSubmit" value="Let's See" class="btn btn-success btn-lg" />
</div>
</div>
</form>
</div>
</div>
我发送的城市列表是我的城市模型的 类。在此页面上,用户从 CitiesOnMap.cshtml 文件的下拉列表中选择一个城市。选择后,我想将用户重定向到正确的城市页面。但是当用户 select 提交按钮时,如果我不使用 TempData["cities"].Keep() 方法,.net 会抛出一个 NullReferenceError 因为我无法在使用它之后再次保留我的数据我知道。如果我使用 TempData["cities"].Keep() 方法,我会收到 HTTP 500 错误。而且我想我必须序列化我的 TempData["cities"] 但我很困惑我有很多问题:( 请帮助我
首先,您的代码犯了一个错误,您无法通过 TempData["KeyName"]
重定向到另一个控制器操作。否则会return 500错误,下面的错误message.That是因为TempData
使用了Session
,它本身使用了IDistributedCache
。 IDistributedCache
没有接受对象或序列化对象的能力:
InvalidOperationException: The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer' cannot serialize an object of type ....
这是一个使用 JSON.Net 的工作演示(您也可以使用 System.Text.Json):
public IActionResult CitiesOnMap()
{
List<City> cities = new List<City>();
//....
cities.Add(new City { CityName = "Ankara", Latitude = 123, Longtitude = 435 });
//Serialize manually by JSON.Net....
TempData["cities"] = Newtonsoft.Json.JsonConvert.SerializeObject(cities);
TempData.Keep("cities");
return View();
}
[HttpPost]
public IActionResult CitiesOnMap(string SelectedCity)
{
if (TempData["cities"] != null)
{
foreach (var redirectedCity in JsonConvert.DeserializeObject<List<City>>(TempData["cities"] as string))
{
if (String.Equals(redirectedCity.CityName, SelectedCity))
{
//not sure what is your selected city page
//but if you redirect to another action
//you also need to serialize the model data manually
TempData["selectedCity"] = JsonConvert.SerializeObject(redirectedCity);
return RedirectToAction(redirectedCity.CityName, "City");
}
}
}
return RedirectToAction(SelectedCity, "City"); ;
}
CitiesOnMap.cshtml:
<form asp-action="CitiesOnMap" asp-controller="City" method="post">
<div class="row">
<div class="col-9 mx-auto">
<select id="drpEmpList" name="SelectedCity" class="form-control">
<option disabled selected hidden>Choose a City </option>
@foreach (var name in
Newtonsoft.Json.JsonConvert.DeserializeObject<List<MVC.Models.City>>(TempData["cities"] as string))
{
<option>@name.CityName </option>
}
</select>
</div>
</div>
</form>