如何强制填充控制器的TempData?

时间:2018-10-17 13:27:50

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

背景

我正在修复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"]抛出异常

问题

每当调用TempData时如何填充Foos()或增加控制器的寿命?

1 个答案:

答案 0 :(得分:0)

会话变量应该起作用。

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();
    }
}