C# 控制器中的字典会突然重置,并在NPE中恢复

C# 控制器中的字典会突然重置,并在NPE中恢复,c#,asp.net-mvc,dictionary,C#,Asp.net Mvc,Dictionary,由于某种原因,每当我尝试使用ActionResult Details()方法访问字典时,字典似乎会重置为0(无元素)。我真的不知道为什么会发生这种情况,我能做些什么来防止这种情况发生。我尝试过更改访问修饰符,但没有成功,我也搜索了几个论坛,但很难找到类似的问题。我相信这是一件很容易的事情,我只是监督,如果有人能够帮助,我将不胜感激。 我对它进行了调试,看看数据是否真的被添加到了字典中。看起来添加的很好 using TransactionImporter.Factory; using Transa

由于某种原因,每当我尝试使用
ActionResult Details()
方法访问字典时,字典似乎会重置为
0
(无元素)。我真的不知道为什么会发生这种情况,我能做些什么来防止这种情况发生。我尝试过更改访问修饰符,但没有成功,我也搜索了几个论坛,但很难找到类似的问题。我相信这是一件很容易的事情,我只是监督,如果有人能够帮助,我将不胜感激。 我对它进行了调试,看看数据是否真的被添加到了字典中。看起来添加的很好

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]);
        }
以下是每次用户鼠标越过Details href时调用控制器中的
ActionResult Details()
方法的索引。由于字典决定将自身重置为
0
,每次我将鼠标悬停在细节上时,都会得到一个NPE,因为它找不到我要查找的键,因为字典中没有数据

@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>
}
@model IEnumerable
@{
ViewBag.Title=“Index”;
}
上传
@DisplayNameFor(model=>model.Username)
@Html.DisplayNameFor(model=>model.FileName)
@DisplayNameFor(model=>model.UploadId)
@DisplayNameFor(model=>model.UploadedOn)
@foreach(模型中的var项目){
@DisplayFor(modelItem=>item.Username)
@DisplayFor(modelItem=>item.FileName)
@DisplayFor(modelItem=>item.UploadId)
@DisplayFor(modelItem=>item.UploadeOn)
|
@ActionLink(“Download EU”,“DownloadEu”,new{id=item.UploadId,controller=“Download”})|
@ActionLink(“Delete”,“Delete”,new{id=item.UploadId,controller=“Download”})
}
@节脚本
{
var ShowDetails=函数(id){
var detailsDiv=$(“#MyDetails”);
$.get('/Download/Details/',{id:id},函数(数据){
html(数据);
});
};
}

您只需在
Index()操作中添加到
IdModelDictionary
对象。但是你什么都不做

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

您缺少的一点是,这些操作完全无关且无状态。对该控制器的每个HTTP请求都会导致创建一个新的控制器实例。因此,执行
Index()
(并填充其
IdModelDictionary
对象)的控制器实例和执行
Details()
的控制器实例是控制器对象的不同实例。当创建第二个实例时,第一个实例早已消失

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

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

每种方法都有其优点和缺点,你可以权衡选择并做出决定。最常见和最不危险的方法可能是将数据存储在数据库中。在
Index()
操作中,通常会显示数据的摘要列表,而在
Details()
操作中,通常会显示数据中特定记录的详细信息。每个操作将分别查询数据库。

谢谢,这很有意义。我不知道为什么我自己没有想到这一点。对于ASP.NET和一般编程来说仍然非常陌生。谢谢。
@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>
}