c# - 使用 TemData.Keep() 时的 Asp.net 核心 HTTP 500 错误
问题描述
城市控制器
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 文件的下拉列表中选择一个城市。选择后,我想将用户重定向到正确的城市页面。但是当用户选择提交按钮时,如果我不使用 TempData["cities"].Keep() 方法,.net 会抛出 NullReferenceError,因为据我所知,在使用它后我无法再次保留我的数据。如果我使用 TempData["cities"].Keep() 方法,我会收到 HTTP 500 错误。而且我认为我必须序列化我的 TempData["cities"] 但我很困惑我有很多问题:(请帮助我
解决方案
首先,您的代码犯了一个错误,即您无法将 TempData["KeyName"]
重定向传递给另一个控制器操作。否则它将返回 500 错误并显示以下错误消息。那是因为TempData
uses 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>
推荐阅读
- excel - 如何创建 VBA 函数来打开文件
- powershell - 为什么“退出”函数在我的 PowerShell 代码中不起作用?
- symfony - 在 symfony 中更新一对多关系
- python - 将一个字母更改为另一种语言的另一个字母 - python
- angular - 如何将角度 url 路由到默认组件?
- bash - 在 BASH 中连接多组 2 个 fastq 文件
- r - 嵌套循环和 if 在 R 中的组合替换
- node.js - 如何从标题中获取 Electron 中的响应正文/响应文本
- firebase - 使用 LinkedIn 提供程序时在 firebase 身份验证中遇到身份验证/操作不允许
- angular - 如何在 Vercel 中使用 json-server mocha 上传前端项目?