【问题标题】:How can I force a controller's TempData to be populated?如何强制填充控制器的 TempData?
【发布时间】:2019-03-22 04:54:27
【问题描述】:

背景

我正在修复 MVC 环境中窗口上的一个问题,在该问题中按下切换按钮不会导致数据更新,而是需要刷新。

文件

Foos\Index.cshtml

<environment>
    <script src="~/js/services/fooController.js"/>
</environment>
<div ng-controller="FooController" ng-init="loadFoos()" ng-cloak>
    <md-list-item ng-repeat="foo in foos" ng-click="null">
        <div layout="row">
            <div>{{foo.name}}</div>
            <div>{{foo.flag}}</div>
            <div>
                <md-button ng-click="toggleFlag(foo)">
                    <md-icon>myIcon</md_icon>
                </md-button>
            </div>
        </div>
    </md-list-item>
</div>

fooController.js

app.controller('FooController', ['$scope', 'fooService', function($scope, fooService) {
    $scope.loadFoos = function() {
        fooService.Load().then(function (response) {
            $scope.foos = response.foos;
        });
    };

    $scope.toggleFlag = function(foo) {
        fooService.toggleFlag(foo).then(function () {
            $scope.loadFoos();
        });
    }
}]);

fooService.js

(function () {
    'use strict';

    angular.module('MyModule').factory('fooService', ['$http', fooService]);

    function fooService($http) {
        return {
            loadFoos: loadFoos,
            toggleFlag: toggleFlag
        };

        function loadFoos() {
            return $http.get("/Foos/Foos").then(successCallBack);
        }

        function toggleFlag(foo) {
            return $http.post("/Foos/ToggleFlag", foo);
        }

        function successCallBack(response) {
            return response.data;
        }
    };
})();

FooController.cs

最后,这一切都回到了一个 C# 控制器,它看起来像这样:

public class FooController : Controller
{
    [Route("/Users/{userId}/Foos")]
    public IActionResult Index(int userId)
    {
        this.TempData["userId"] = userId;
        return View();
    }

    [HttpGet]
    public JsonResult Foos()
    {
        var userId = int.Parse(this.TempData["userId"].ToString());
        IEnumerable<Foo> foos = new Foo[0];
        //to keep this as small as possible for reproducing
        return this.Json(new { foos = foos });
    }

    [HttpPost]
    [Route("/Foos/ToggleFlag")]
    public ActionResult ToggleFlag([FromBody] Foo foo)
    {
        //delegate updating to writer; omitted for reproducibility
        return this.Ok();
    }
}

根本问题

当窗口加载时,Index() 被调用并自动使用 URL 中的适当用户 ID 填充 TempData。然后它可以调用Foos() 并返回适当的列表。但是,当通过$scope.toggleFlag 调用时,它调用Index(),使得Foos() 在尝试访问不存在的TempData["userId"] 时抛出异常。

问题

如何在调用Foos() 时填充TempData,或延长控制器的使用寿命?

【问题讨论】:

  • TempData 专为一次性使用而设计。请改用Session 变量。

标签: c# asp.net angularjs model-view-controller


【解决方案1】:

会话变量应该可以工作。

TempData 仅允许我们在单个请求的持续时间内访问,而会话变量“保持”其值的时间要长得多。

public class FooController : Controller
{
    [Route("/Users/{userId}/Foos")]
    public IActionResult Index(int userId)
    {
        System.Web.HttpContext.Current.Session["userId"] = userId; 
        //this.TempData["userId"] = userId;
        return View();
    }

    [HttpGet]
    public JsonResult Foos()
    {
        var userId = (int)System.Web.HttpContext.Current.Session["userId"]; 
        //var userId = int.Parse(this.TempData["userId"].ToString());
        IEnumerable<Foo> foos = new Foo[0];
        //to keep this as small as possible for reproducing
        return this.Json(new { foos = foos });
    }

    [HttpPost]
    [Route("/Foos/ToggleFlag")]
    public ActionResult ToggleFlag([FromBody] Foo foo)
    {
        //delegate updating to writer; omitted for reproducibility
        return this.Ok();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 2014-10-14
    • 2015-01-21
    • 2012-06-25
    相关资源
    最近更新 更多