代码之家  ›  专栏  ›  技术社区  ›  Liam Kernighan

ASP。NET MVC 5在请求之间保留旧输入

  •  2
  • Liam Kernighan  · 技术社区  · 6 年前

    我需要的功能类似于Laravel的旧输入助手,但在MVC 5中。 https://laravel.com/docs/5.6/requests#old-input

    如果验证失败,我需要像在前一个请求中一样重新加载所有模型数据,但用户输入错误的输入除外。

    问题是,我的表单有许多被禁用的输入和字段,程序在[HttpGet]方法中获取这些输入和字段,它们在提交过程中丢失了。所以我需要在会话中存储它们。

    下面的代码似乎可以工作,但有没有更有效、更漂亮的方法,可以在每个控制器中使用更少的代码?

    [HttpGet]
    [Route(@"TaskManagement/Edit/{guid}")]
    public async Task<ActionResult> Edit(Guid guid)
    {
        var model = new EditTaskViewModel(); 
        model.Guid = guid;
    
        await model.GetTaskFromRemoteService(new UserInfo(User));
    
        ControllerHelpers.DisplayAlerts(model, this);
    
        TempData["OldModel"] = model;
    
        return View(model);                
    }
    
    
    [HttpPost]
    [ValidateAntiForgeryToken]
    [Route(@"TaskManagement/Edit/{guid}")]
    public async Task<ActionResult> Edit(EditTaskViewModel model, Guid guid, string submit)
    {
        model.Guid = guid;
    
        if (ModelState.IsValid) {
            await model.UpdateTaskInRemoteService(new UserInfo(User), submit);
            ControllerHelpers.DisplayAlerts(model, this, "Task successfully updated");
    
            if (model.ErrorCode == null)
                return RedirectToAction("Edit", new { guid = model.Guid });
    
            return RedirectToAction("Index");
        }
    
    
        if (TempData["OldModel"] != null) {
            model = (EditTaskViewModel)TempData["OldModel"];
        }
        return View(model);
    
    }
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Tim M.    6 年前

    使用会话状态(包括 TempData )这样,当您打开页面的多个副本时,可能会中断。你可以通过 generating a unique ID for the session key and storing it in a hidden field

    然而,我会尽量避免完全使用会话。

    一种简单的方法是使用隐藏字段存储未发送到服务器的值,因为这些值位于禁用字段中。

    一种更健壮的方法是一个单独的类(或至少是一个私有方法),它知道如何在第一次和转换过程中设置模型(例如,服务器验证失败)。我将这些类称为“composers”,并描述了该方法 here

    有关具有编写器的操作方法的外观的伪代码:

    if( ModelState.IsValid ){
        return Redirect();
    }
    
    var rebuiltModel = _composer.ComposeEdit( incomingModel );
    return View( rebuiltModel );
    
        2
  •  0
  •   Liam Kernighan    6 年前

    我认为答案很简单。最短、最简单的方法是再次从数据库\远程服务填充对象。

    用户输入的字段是否有效将保持原样。其余的将再次加载。