控制器中的字典在NPE中重置为蓝色

时间:2018-06-03 13:42:57

标签: c# asp.net-mvc dictionary

出于某种原因,每次我尝试使用0方法访问时,我的词典似乎都会重置为ActionResult Details()(无元素)。我不确定为什么会发生这种情况以及我能做些什么来防止这种情况发生。我已经尝试更改访问修饰符,但这导致没有成功,我也搜索了几个论坛,但很难找到类似的问题。我确信这只是一件容易的事情,我只是在监督,如果有人能够提供帮助,我将非常感激。 我调试它以查看数据是否实际添加到字典中。好像它被添加得很好。

using TransactionImporter.Factory;
using TransactionImporter.WebUI.Models;
using TransactionImpoter.Domain;

namespace TransactionImporter.WebUI.Controllers
{
    public class DownloadController : Controller
    {
        private IUploadDetailLogic uploadDetailLogic = UploadDetailFactory.CreateLogic();
        private IExporterLogic exporterLogic = ExporterFactory.CreateLogic();
        private IUserLogic userLogic = UserFactory.CreateLogic();
        public IDictionary<int, DownloadModels> IdModelDictionary = new Dictionary<int, DownloadModels>();

        // GET: Download
        public ActionResult Index()
        {
            List<UploadDetail> uploadDetailList = uploadDetailLogic.UploadDetailList();
            List<DownloadModels> downloadableList = new List<DownloadModels>();
            foreach (UploadDetail upload in uploadDetailList)
            {
                User user = userLogic.GetUserById(upload.UserId);
                DownloadModels model = new DownloadModels(upload.UploadId, upload.UserId, user.Username,
                    upload.StartTimeUpload.ToString(), upload.FileName, Convert.ToInt32(upload.FileSize));

                downloadableList.Add(model);
                IdModelDictionary.Add(upload.UploadId, model);
            }
            return View(downloadableList);
           }

        // GET: Download/Details/5
        public ActionResult Details(int id)
        {
            return View(IdModelDictionary[id]);
        }

DownloadModels:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TransactionImporter.WebUI.Models
{
    public class DownloadModels
    {
        public DownloadModels(int uploadId, int userId, string uploadedOn, string fileName, int fileSize)
        {
            UploadId = uploadId;
            UserId = userId;
            UploadedOn = uploadedOn;
            FileName = fileName;
            FileSize = fileSize;
        }
        public DownloadModels(int uploadId, int userId, string username, string uploadedOn, string fileName, int fileSize)
        {
            UploadId = uploadId;
            UserId = userId;
            Username = username;
            UploadedOn = uploadedOn;
            FileName = fileName;
            FileSize = fileSize;
        }
        public DownloadModels() { }

        public int UploadId { get; private set; }
        public string UploadedOn { get; private set; }
        public string FileName { get; private set; }
        public int FileSize { get; private set; }
        public int UserId { get; private set; }
        public string Username { get; private set; }
        public IEnumerator GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }
}

这是每次用户将鼠标悬停在详细信息href时在控制器中调用ActionResult Details()方法的索引。看到字典决定将自身重置为0,每次我将鼠标悬停在细节上时,我都会得到一个NPE,因为它无法找到我正在寻找的密钥,因为字典中没有数据。 / p>

@model IEnumerable<TransactionImporter.WebUI.Models.DownloadModels>

@{
    ViewBag.Title = "Index";
}

<h2>Uploads</h2>

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Username)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.FileName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.UploadId)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.UploadedOn)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Username)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FileName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.UploadId)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.UploadedOn)
            </td>
            <td>
                <a href="#" onmouseover="ShowDetails(@item.UploadId)">Details</a> |
                @Html.ActionLink("Download-EU", "DownloadEu", new { id = item.UploadId, controller = "Download" }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.UploadId, controller = "Download" })
            </td>
        </tr>
    }

</table>
<div class="col-md-6" id="MyDetails">

</div>

@section Scripts
{
    <script>

        var ShowDetails = function (id) {

            var detailsDiv = $('#MyDetails');
            $.get('/Download/Details/', { id: id }, function (data) {
                detailsDiv.html(data);
            });
        };
    </script>
}

1 个答案:

答案 0 :(得分:1)

您只能在IdModelDictionary操作中添加到Index()对象。但是你不能用它做任何事情。

稍后,您尝试在Details()操作中引用它,但不首先添加任何内容。

您缺少的一点是,这些行为完全不相关且无国籍。对此控制器的每个HTTP请求都会导致创建一个新的控制器实例。因此,执行Index()(并填充其IdModelDictionary对象)的控制器实例和执行Details()的控制器实例是控制器对象的不同实例。到第二个实例创建时,第一个实例早已不复存在。

为了在多个HTTP请求之间保留数据,需要在某处保留该数据。数据库是保存数据的常用位置。其他选项包括但不限于:

  • 页面(因此数据在客户端可用)
  • 会话状态
  • 应用程序缓存
  • static属性
  • 文件系统
  • 其他缓存系统(可能在内部使用某种数据库)

每个人都有自己的专业人士和成员,你可以权衡选项并做出决定。可能最常见且最不危险的方法是将数据存储在数据库中。在Index()操作中,通常会显示数据的摘要列表,在Details()操作中,通常会显示数据中特定记录的详细信息。每个操作都会单独查询数据库。