Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用临时数据实现post get重定向模式时出现模型绑定错误_C#_Asp.net Core - Fatal编程技术网

C# 使用临时数据实现post get重定向模式时出现模型绑定错误

C# 使用临时数据实现post get重定向模式时出现模型绑定错误,c#,asp.net-core,C#,Asp.net Core,我正在使用asp.net core 2.2并尝试实现中概述的模式。我有两项行动如下: [ImportModelState] public async Task<IActionResult> Upload(int id, CancellationToken ct) { var model = new MyModel(); // ... return this.View(model); } [HttpPost] [ExportModelState] public

我正在使用asp.net core 2.2并尝试实现中概述的模式。我有两项行动如下:

[ImportModelState]
public async Task<IActionResult> Upload(int id, CancellationToken ct)
{
    var model = new MyModel();
    // ...
    return this.View(model);
}

[HttpPost]
[ExportModelState]
public async Task<IActionResult> Upload(int id, MyModel model, CancellationToken ct)
{
    // ...
}
反序列化和合并使用以下逻辑:

var errorList = modelState
    .Select(kvp => new ModelStateTransferValue
    {
        Key = kvp.Key,
        AttemptedValue = kvp.Value.AttemptedValue,
        RawValue = kvp.Value.RawValue,
        ErrorMessages = kvp.Value.Errors
            .Select(p => p.ErrorMessage)
            .ToList(),
    });
var errorList = JsonConvert.DeserializeObject<List<ModelStateTransferValue>>(serialized);
var modelState = new ModelStateDictionary();

foreach (var item in errorList)
{
    modelState.SetModelValue(item.Key, item.RawValue, item.AttemptedValue);
    foreach (var error in item.ErrorMessages)
    {
        modelState.AddModelError(item.Key, error);
    }
}

filterContext.ModelState.Merge(modelState);
var errorList=JsonConvert.DeserializeObject(序列化);
var modelState=new ModelStateDictionary();
foreach(错误列表中的变量项)
{
SetModelValue(item.Key、item.RawValue、item.AttemptedValue);
foreach(item.ErrorMessages中的变量错误)
{
AddModelError(item.Key,error);
}
}
filterContext.ModelState.Merge(ModelState);

问题在于您实际上没有遵循post重定向get。重定向在成功时发生。如果存在验证错误,只需再次返回视图。无需在
TempData
中保存任何内容。就连这篇链接文章的作者也指出:

由于PRG主要用于防止双重表单提交,因此如果表单无效,则不一定要重定向用户。在这种情况下,请求不应该是修改状态,因此再次提交表单是有效的

他误入歧途的地方是在整个过程中使用
TempData
来处理无效的提交,并且仍然重定向内容。这显然是错误的,我发现安德鲁·洛克的建议有点令人惊讶。我经常引用他的文章,但显然从未注意到这篇

在软件开发中,有一条潜规则:不要做独角兽。与地球上几乎所有其他开发者做不同的事情并不会让你与众不同;这让你成为一个白痴

更新

哇。在阅读这些评论时,遇到了安德鲁的评论,他说:

话虽如此,我个人并没有使用这种方法——正如你所说,它增加了很多复杂性

这是一个已经完成的交易。我的意思是这是一个有趣的思想实验,但是如果它对写它的人来说不够好,那么对其他人来说也不够好


当用户刷新使用无效数据提交的页面时,所有这一切都会消除“确认表单重新提交”对话框。一般而言,PRG已涵盖职位成功的案例。考虑到复杂性和所有额外的请求,对于一些可能永远不会发生的事情来说,这根本不值得。就我个人而言,我发现用户害怕刷新页面,担心他们必须重新输入所有字段(具有讽刺意味的是,这种解决方案实际上会导致刷新,而如果不是这样的话,他们只会很好地刷新页面).

您能告诉我们您是如何将
ModelState
的序列化编码为
TempData
的吗?没问题,我已经更新了这个问题。我不确定我是否同意,如果您不在post操作的每个响应上重定向,您就不能在不重新发布的情况下刷新页面。通过始终重定向,当您遇到表单错误并被重定向到包含数据和模型错误的视图时,您可以刷新并从头开始。同样,大多数用户不仅不会刷新,即使他们刷新了,他们的期望是数据保留,而不是清除。这是一种非典型的,我甚至可以说是反模式的方法,你提到的文章的作者甚至没有使用他自己。这是一个亲吻的时刻。明智地选择。