【问题标题】:TempData does not work in my .NET Core projectTempData 在我的 .NET Core 项目中不起作用
【发布时间】:2019-07-20 16:02:06
【问题描述】:

我有一个非常简单的 ASP.NET Core 项目。这是我的控制器:

public class AdminController : Controller
{
    private readonly IProductRepository _repository;

    public AdminController(IProductRepository repository)
    {
        _repository = repository;
    }

    public ViewResult Index()
    {
        return View(_repository.Products.OrderBy(p => p.Id));
    }

    public ViewResult Edit(int id)
    {
        Product product = _repository.Products.FirstOrDefault(p => p.Id == id);

        return View(product);
    }

    [HttpPost]
    public ActionResult Edit(Product product)
    {
        if (ModelState.IsValid)
        {
            _repository.SaveProduct(product);
            TempData["message"] =  $"{product.Name} has been saved";

            return RedirectToAction("Index");
        }

        return View(product);
    }
}

我的看法_AdminLayout.cshtml

<main role="main" class="pb-3">
    <div>
        @if (TempData["message"] != null)
        {
            <div class="alert alert-success">
                @TempData["message"]
            </div>
        }
    </div>
    @RenderBody()
</main>

最后是Index.cshtml 视图

@model System.Collections.Generic.IEnumerable<Domains.Entities.Product>

@{
    ViewBag.Title = "Admin";
    Layout = "_AdminLayout";
}

<div>
// some cshtml code ...
</div>

如您所见,我正在等待以下业务逻辑:

  1. 保存产品;

  2. 重定向到Index.cs 管理员视图

  3. 我在屏幕顶部看到有关成功保存产品的消息。

但是什么也没发生。保存后看不到消息,重定向到IndexTempData 为空。

此外,我对这种方法的单元测试有疑问。

这是我的测试代码:

[Test]
public void Can_Save_Valid_Changes()
{
    Mock<IProductRepository> mock = new Mock<IProductRepository>();

    AdminController controller = new AdminController(mock.Object);

    Product product = new Product { Name = "Test"};

    IActionResult result = controller.Edit(product);

    // check if have saved product to repo 
    mock.Verify(m => m.SaveProduct(product));

    Assert.IsNotInstanceOf<ViewResult>(result);
}

我使用NUnit 库进行测试。运行测试后,我收到来自测试的以下消息:object reference not set to an instance of an object。似乎将价值赋予TempData 在测试期间会引发此异常。

请告诉我,这个TempData 发生了什么?错误在哪里?我看到了很多关于TempData 奇怪行为的问题,但我没有找到适合我的答案。我很感激任何帮助。

【问题讨论】:

    标签: c# asp.net-core nunit tempdata


    【解决方案1】:

    当对访问TempData 的控制器进行单元测试时,您需要为该控制器创建一个TempDataDictionary

    [Test]
    public void Can_Save_Valid_Changes() {
        //Arrange
        var httpContext = new DefaultHttpContext();
        var tempData = new TempDataDictionary(httpContext, Mock.Of<ITempDataProvider>());
        var mock = new Mock<IProductRepository>();
        AdminController controller = new AdminController(mock.Object);
        controller.TempData = tempData;
    
        Product product = new Product { Name = "Test"};
    
        //Act
        IActionResult result = controller.Edit(product);
    
        //Assert
        // check if have saved product to repo 
        mock.Verify(m => m.SaveProduct(product));
        Assert.IsNotInstanceOf<ViewResult>(result);
        Assert.IsTrue(tempData.ContainsKey("message"));
    }
    

    【讨论】:

    • 非常感谢!它解决了我一半的问题。你能给我一个如何在控制器中使用它的例子吗?我已经尝试过这个TempData = new TempDataDictionary(HttpContext, new SessionStateTempDataProvider()) ; TempData["message"] = $"{product.Name} has been saved"; 但它继续在视图中给我null。我找不到好的用法。
    • @Aleksej_Shherbak 您在最初的问题中所拥有的应该可以工作。我不确定为什么你所拥有的东西不起作用。我唯一能想到的就是你在布局中有它。只是为了解决问题。将 tempdata 代码从布局移动到索引,看看它是否有所作为。
    • 哈哈哈!我已经解决了问题的第二部分)你知道它是什么吗?我是 cookie 政策的设置!这些设置位于Sturtup.cs 文件中。如果您在Startup.cs 中有类似的内容:` services.Configure(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; });` 那么你必须设置options.CheckConsentNeeded = context =&gt; 为假。非常感谢!
    猜你喜欢
    • 2017-08-03
    • 2020-05-22
    • 2021-09-28
    • 2014-08-29
    • 1970-01-01
    • 2020-03-16
    • 2012-04-14
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多