You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Razor C#中将读取的CSV列表设置为全局变量在Post请求中复用

问题根本原因

Razor Pages的PageModel实例是每请求创建一次的,你在OnGetAsync里给doc1赋值,POST请求触发时会新建IndexModel实例,之前的doc1值自然就丢失了,所以每次POST都要重读数据。


解决方案1:应用级内存缓存(所有用户共用同一份数据,推荐)

如果这份CSV数据是所有用户共享的无差异数据,用ASP.NET Core自带的内存缓存即可,只在首次访问时加载,后续所有请求直接读取缓存,性能最优。

步骤1:注册缓存服务

在Program.cs中添加配置:

// 服务注册区添加
builder.Services.AddMemoryCache();

步骤2:改造IndexModel代码

将重复的Blob读取逻辑抽为公共方法,优先从缓存取数据,缓存不存在时再从Blob加载:

using Microsoft.Extensions.Caching.Memory; // 新增引用

public class IndexModel : PageModel
{
    private readonly ILogger<IndexModel> _logger;
    private readonly IMemoryCache _cache;
    // 缓存Key固定值,避免拼写错误
    private const string DocCacheKey = "Global_Document_List_Cache";

    public List<Documents> doc1 = new List<Documents>();
    // 其余原有属性保持不变

    // 构造函数注入缓存服务
    public IndexModel(ILogger<IndexModel> logger, IMemoryCache cache)
    {
        _logger = logger;
        _cache = cache;
    }

    // 抽离公共的文档加载方法
    private async Task<List<Documents>> LoadDocumentsAsync()
    {
        // 缓存存在直接返回
        if (_cache.TryGetValue(DocCacheKey, out List<Documents> cachedDocs))
        {
            return cachedDocs;
        }

        // 缓存不存在,走原有Blob加载逻辑
        var accountName = "";
        var accessKey = "";
        var credential = new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(accountName, accessKey);
        var storageAccount = new CloudStorageAccount(credential, true);
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("");
        CloudBlockBlob blockBlob2 = container.GetBlockBlobReference("FILES-1000000.xml");

        string files2;
        using (var memoryStream2 = new MemoryStream())
        {
            await blockBlob2.DownloadToStreamAsync(memoryStream2);
            files2 = System.Text.Encoding.UTF8.GetString(memoryStream2.ToArray());
        }

        byte[] byteArray2 = Encoding.UTF8.GetBytes(files2);
        MemoryStream stream2 = new MemoryStream(byteArray2);
        StreamReader reader2 = new StreamReader(stream2);
        XmlSerializer serializer = new XmlSerializer(typeof(filelists));
        filelists result = (filelists)serializer.Deserialize(reader2);
        reader2.Close();

        var docList = new List<Documents>();
        CloudBlockBlob blockBlob3 = container.GetBlockBlobReference(result.list[0].file);
        using (var memoryStream3 = new MemoryStream())
        {
            await blockBlob3.DownloadToStreamAsync(memoryStream3);
            var data = System.Text.Encoding.UTF8.GetString(memoryStream3.ToArray());
            var doc = data.Split("<seprt>");
            var counter = 0;
            string id = "", tytle = "", body = "", htmlbody = "";
            foreach (string value in doc)
            {
                if (counter % 4 == 0) id = doc[counter];
                else if (counter % 4 == 1) tytle = doc[counter];
                else if (counter % 4 == 2) body = doc[counter];
                else if (counter % 4 == 3)
                {
                    htmlbody = doc[counter];
                    docList.Add(new Documents()
                    {
                        id = id, tytle = tytle, body = body, htmlbody = htmlbody
                    });
                }
                counter++;
            }
        }

        // 写入缓存,设置1小时过期,可根据数据更新频率调整
        _cache.Set(DocCacheKey, docList, TimeSpan.FromHours(1));
        return docList;
    }

    public async Task OnGetAsync()
    {
        doc1 = await LoadDocumentsAsync();
        error = "open";
    }

    public async Task<JsonResult> OnPost()
    {
        indx = Request.Form["indx"];
        evnt = Request.Form["evnt"];
        textdata = Request.Form["textbody"];
        htmldata = Request.Form["htmlbody"];

        // 直接调用公共方法拿数据,不用重复写加载逻辑
        var docList = await LoadDocumentsAsync();
        int index = Int32.Parse(indx);

        if (evnt == "listclick")
        {
            bodyelement = docList[index].htmlbody;
        }
        else if (evnt == "save")
        {
            // 更新本地对象,再组装保存到Blob
            docList[index].body = textdata;
            docList[index].htmlbody = htmldata;
            await saveDoc(docList);
            // 保存成功后清除缓存,下次加载就会拿到最新数据
            _cache.Remove(DocCacheKey);
            bodyelement = "saved";
        }

        await Task.Delay(100);
        if (!ModelState.IsValid)
        {
            return new JsonResult("JSONResponse: Error occurred. Please retry.");
        }
        return new JsonResult(bodyelement);
    }

    // 改造saveDoc方法参数,直接传处理好的文档列表
    public async Task saveDoc(List<Documents> docList)
    {
        // 组装CSV逻辑保持不变,Blob上传逻辑也保持不变
        // ......原有保存逻辑......
    }
    // 其余原有类定义保持不变
}

解决方案2:用户会话级存储(每个用户独立数据)

如果数据是用户私有差异化数据,可使用Session存储:

  1. 在Program.cs中注册Session服务并启用Session中间件
  2. 将List<Documents>序列化后存入Session,请求时读取反序列化即可
    注意:Session适合存储小体积数据,大体积数据仍建议走缓存+用户标识区分的方案

内容的提问来源于stack exchange,提问作者西浦直志

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 09:24:01