I have a method to remove the object. Removal does not own view, and is a "Delete" button in the "EditReport". Upon successful removal of a redirect on "Report".
我有一个删除对象的方法。删除不属于视图,并且是“EditReport”中的“删除”按钮。成功删除“报告”上的重定向后。
[HttpPost]
[Route("{reportId:int}")]
[ValidateAntiForgeryToken]
public IActionResult DeleteReport(int reportId)
{
var success = _reportService.DeleteReportControl(reportId);
if (success == false)
{
ModelState.AddModelError("Error", "Messages");
return RedirectToAction("EditReport");
}
ModelState.AddModelError("OK", "Messages");
return RedirectToAction("Report");
}
In ASP.NET MVC 5 I use the following attributes to save ModelState between methods. I took from here: https://*.com/a/12024227/3878213
在ASP.NET MVC 5中,我使用以下属性在方法之间保存ModelState。我从这里开始:https://*.com/a/12024227/3878213
public class SetTempDataModelStateAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
filterContext.Controller.TempData["ModelState"] =
filterContext.Controller.ViewData.ModelState;
}
}
public class RestoreModelStateFromTempDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (filterContext.Controller.TempData.ContainsKey("ModelState"))
{
filterContext.Controller.ViewData.ModelState.Merge(
(ModelStateDictionary)filterContext.Controller.TempData["ModelState"]);
}
}
}
But in ASP.NET MVC 6 RC 1 (ASP.NET Core 1.0), this code does not work.
但是在ASP.NET MVC 6 RC 1(ASP.NET Core 1.0)中,此代码不起作用。
Error in filterContext.Controller does not contain definitions for TempData and ViewData.
filterContext.Controller中的错误不包含TempData和ViewData的定义。
2 个解决方案
#1
4
Thanks to answer, I realized that the need to create your own code ASP.NET Core 1.0 (Full .NET Framework 4.6.2)
感谢回答,我意识到需要创建自己的代码ASP.NET Core 1.0(完整的.NET Framework 4.6.2)
public class SetTempDataModelStateAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var controller = filterContext.Controller as Controller;
var modelState = controller?.ViewData.ModelState;
if (modelState != null)
{
var listError = modelState.Where(x => x.Value.Errors.Any())
.ToDictionary(m => m.Key, m => m.Value.Errors
.Select(s => s.ErrorMessage)
.FirstOrDefault(s => s != null));
controller.TempData["ModelState"] = JsonConvert.SerializeObject(listError);
}
}
}
public class RestoreModelStateFromTempDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
var controller = filterContext.Controller as Controller;
var tempData = controller?.TempData?.Keys;
if (controller != null && tempData != null)
{
if (tempData.Contains("ModelState"))
{
var modelStateString = controller.TempData["ModelState"].ToString();
var listError = JsonConvert.DeserializeObject<Dictionary<string, string>>(modelStateString);
var modelState = new ModelStateDictionary();
foreach (var item in listError)
{
modelState.AddModelError(item.Key, item.Value ?? "");
}
controller.ViewData.ModelState.Merge(modelState);
}
}
}
}
Asynchronous version of the code ASP.NET Core 1.0 (Full .NET Framework 4.6.2)
代码的非同步版本ASP.NET Core 1.0(完整的.NET Framework 4.6.2)
public class SetTempDataModelStateAttribute : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext filterContext, ActionExecutionDelegate next)
{
await base.OnActionExecutionAsync(filterContext, next);
var controller = filterContext.Controller as Controller;
var modelState = controller?.ViewData.ModelState;
if (modelState != null)
{
var listError = modelState.Where(x => x.Value.Errors.Any())
.ToDictionary(m => m.Key, m => m.Value.Errors
.Select(s => s.ErrorMessage)
.FirstOrDefault(s => s != null));
var listErrorJson = await Task.Run(() => JsonConvert.SerializeObject(listError));
controller.TempData["ModelState"] = listErrorJson;
}
await next();
}
}
public class RestoreModelStateFromTempDataAttribute : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext filterContext, ActionExecutionDelegate next)
{
await base.OnActionExecutionAsync(filterContext, next);
var controller = filterContext.Controller as Controller;
var tempData = controller?.TempData?.Keys;
if (controller != null && tempData != null)
{
if (tempData.Contains("ModelState"))
{
var modelStateString = controller.TempData["ModelState"].ToString();
var listError = await Task.Run(() =>
JsonConvert.DeserializeObject<Dictionary<string, string>>(modelStateString));
var modelState = new ModelStateDictionary();
foreach (var item in listError)
{
modelState.AddModelError(item.Key, item.Value ?? "");
}
controller.ViewData.ModelState.Merge(modelState);
}
}
await next();
}
}
#2
3
The fix to make the code compile is below, but it appears that ASP.NET Core does not support serializing the model state (due to ModelStateEntry
containing exceptions which are never serializable).
编译代码的修复程序如下所示,但似乎ASP.NET Core不支持序列化模型状态(由于ModelStateEntry包含永远不可序列化的异常)。
As such, you cannot serialize the model state in TempData
. And as explained in this GitHub issue, there appear to be no plans to change this behavior.
因此,您无法在TempData中序列化模型状态。正如本GitHub问题所解释的那样,似乎没有计划改变这种行为。
The Controller
property in ActionExecutingContext
is of type object
. This is because controllers in ASP.NET Core are not required to inherit from Controller
, so there is no common base type for them.
ActionExecutingContext中的Controller属性是object类型。这是因为ASP.NET Core中的控制器不需要从Controller继承,因此它们没有共同的基类型。
In order to access the TempData
property, you have to cast it to Controller
first. Your attributes could look like this then:
要访问TempData属性,必须先将其强制转换为Controller。您的属性可能如下所示:
public class SetTempDataModelStateAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
Controller controller = filterContext.Controller as Controller;
if (controller != null)
{
controller.TempData["ModelState"] = controller.ViewData.ModelState;
}
}
}
public class RestoreModelStateFromTempDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
Controller controller = filterContext.Controller as Controller;
if (controller != null & controller.TempData.ContainsKey("ModelState"))
{
controller.ViewData.ModelState.Merge(
(ModelStateDictionary)controller.TempData["ModelState"]);
}
}
}
#1
4
Thanks to answer, I realized that the need to create your own code ASP.NET Core 1.0 (Full .NET Framework 4.6.2)
感谢回答,我意识到需要创建自己的代码ASP.NET Core 1.0(完整的.NET Framework 4.6.2)
public class SetTempDataModelStateAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var controller = filterContext.Controller as Controller;
var modelState = controller?.ViewData.ModelState;
if (modelState != null)
{
var listError = modelState.Where(x => x.Value.Errors.Any())
.ToDictionary(m => m.Key, m => m.Value.Errors
.Select(s => s.ErrorMessage)
.FirstOrDefault(s => s != null));
controller.TempData["ModelState"] = JsonConvert.SerializeObject(listError);
}
}
}
public class RestoreModelStateFromTempDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
var controller = filterContext.Controller as Controller;
var tempData = controller?.TempData?.Keys;
if (controller != null && tempData != null)
{
if (tempData.Contains("ModelState"))
{
var modelStateString = controller.TempData["ModelState"].ToString();
var listError = JsonConvert.DeserializeObject<Dictionary<string, string>>(modelStateString);
var modelState = new ModelStateDictionary();
foreach (var item in listError)
{
modelState.AddModelError(item.Key, item.Value ?? "");
}
controller.ViewData.ModelState.Merge(modelState);
}
}
}
}
Asynchronous version of the code ASP.NET Core 1.0 (Full .NET Framework 4.6.2)
代码的非同步版本ASP.NET Core 1.0(完整的.NET Framework 4.6.2)
public class SetTempDataModelStateAttribute : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext filterContext, ActionExecutionDelegate next)
{
await base.OnActionExecutionAsync(filterContext, next);
var controller = filterContext.Controller as Controller;
var modelState = controller?.ViewData.ModelState;
if (modelState != null)
{
var listError = modelState.Where(x => x.Value.Errors.Any())
.ToDictionary(m => m.Key, m => m.Value.Errors
.Select(s => s.ErrorMessage)
.FirstOrDefault(s => s != null));
var listErrorJson = await Task.Run(() => JsonConvert.SerializeObject(listError));
controller.TempData["ModelState"] = listErrorJson;
}
await next();
}
}
public class RestoreModelStateFromTempDataAttribute : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext filterContext, ActionExecutionDelegate next)
{
await base.OnActionExecutionAsync(filterContext, next);
var controller = filterContext.Controller as Controller;
var tempData = controller?.TempData?.Keys;
if (controller != null && tempData != null)
{
if (tempData.Contains("ModelState"))
{
var modelStateString = controller.TempData["ModelState"].ToString();
var listError = await Task.Run(() =>
JsonConvert.DeserializeObject<Dictionary<string, string>>(modelStateString));
var modelState = new ModelStateDictionary();
foreach (var item in listError)
{
modelState.AddModelError(item.Key, item.Value ?? "");
}
controller.ViewData.ModelState.Merge(modelState);
}
}
await next();
}
}
#2
3
The fix to make the code compile is below, but it appears that ASP.NET Core does not support serializing the model state (due to ModelStateEntry
containing exceptions which are never serializable).
编译代码的修复程序如下所示,但似乎ASP.NET Core不支持序列化模型状态(由于ModelStateEntry包含永远不可序列化的异常)。
As such, you cannot serialize the model state in TempData
. And as explained in this GitHub issue, there appear to be no plans to change this behavior.
因此,您无法在TempData中序列化模型状态。正如本GitHub问题所解释的那样,似乎没有计划改变这种行为。
The Controller
property in ActionExecutingContext
is of type object
. This is because controllers in ASP.NET Core are not required to inherit from Controller
, so there is no common base type for them.
ActionExecutingContext中的Controller属性是object类型。这是因为ASP.NET Core中的控制器不需要从Controller继承,因此它们没有共同的基类型。
In order to access the TempData
property, you have to cast it to Controller
first. Your attributes could look like this then:
要访问TempData属性,必须先将其强制转换为Controller。您的属性可能如下所示:
public class SetTempDataModelStateAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
Controller controller = filterContext.Controller as Controller;
if (controller != null)
{
controller.TempData["ModelState"] = controller.ViewData.ModelState;
}
}
}
public class RestoreModelStateFromTempDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
Controller controller = filterContext.Controller as Controller;
if (controller != null & controller.TempData.ContainsKey("ModelState"))
{
controller.ViewData.ModelState.Merge(
(ModelStateDictionary)controller.TempData["ModelState"]);
}
}
}