【问题标题】:How to pass a list from method to another method如何将列表从方法传递到另一个方法
【发布时间】:2019-11-05 11:08:22
【问题描述】:

如何将下面的动作传递给另一个动作,以便将其导出到 Excel 工作表中 ,我需要将 VL 列表传递给另一个动作

public ActionResult Details(int S)
{
    SLMEntitiesDB dbContext = new SLMEntitiesDB();
                var VL = (from U in dbContext.Users
                  join P in dbContext.Products
                  on U.PID equals P.PID
                  where P.PID == U.PID
                  select new UP()
                  {
                      UserO = U,
                      ProductO = P
                  }).Where(U => U.UserO.LID == S).ToList();
TempData["Exc"] = VL; 
    return View(VL);
}

和同一控制器中的其他操作,但它不起作用

public void ExportToExcel()
        {

            var V = TempData["Exc"] as List;
            ExcelPackage pck = new ExcelPackage();
            ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Report");
            ws.Cells["A1"].Value = "UserName";
            int rowStart = 1;
            foreach (var item in V)// here is the error 
            {
                ws.Cells[string.Format("A{0}", rowStart)].Value = item.UserO.CN;

【问题讨论】:

  • 可以使用RedirectToAction方法,将VL作为参数传递,在目标动作方法return RedirectToAction(VL)中处理请求;
  • 上述方法只是在视图中查看此列表,现在我想在该视图中创建一个按钮以将列表导出到excel表中。
  • 或者说,我如何从同一个类中的另一个操作访问上面的列表
  • 来自您的其他so question\answer 我将更新我的答案以使用您在那里定义的模型命名空间。另外,请确保您在该问题中接受自己的答案 - 不要让问题在解决后仍然未被接受。

标签: c# entity-framework model-view-controller


【解决方案1】:

您将在您的控制器上创建另一个 Function\Action 并将数据从您的视图传递给它。根据数据的大小,您可以将其作为 QueryString 执行(注意:输入 .ToString() 注意事项,采用该方法的 html 编码),但您更有可能使用 TempData[key] 或类似的东西。

您尝试做的其他方面(导出 Excel 文件)将由添加的操作处理;但是,我建议您定义一个继承 FileResult 类型的类型,而不是您在操作范围内处理整个响应写入 - 您在重载的 WriteFile 函数中处理 HttpResponseBase (下面的示例)。

XLSFileResult

此示例类型实际上将写入逗号分隔值 (CSV) 内容,但 Content-Type(加上 Content-Disposition)将向客户端“指示”它是一个 excel 文件 - Response 将响应带有“.xls”文件。

注意:此示例中的文件名和扩展名实际上是在其初始化时定义的 - 在控制器的操作中。

public class XLSFileResult : FileResult
{
    public XLSFileResult() : base(@"application/vnd.ms-excel")
    {
        Data = new List<UP>();
    }

    public IEnumerable<UP> Data { get; set; }

    protected override void WriteFile(HttpResponseBase response)
    {
        // note: you'll want to handle this better; I'm just choosing a property of each complex type.
        string[] lines = Data.Select(d => string.Join(", ", d.UserO.UserName , d.ProductO.PName)).ToArray();
        byte[] buffer = response.ContentEncoding.GetBytes(string.Join(Environment.NewLine, lines));
        response.BinaryWrite(buffer);                       
    }
}

控制器上的示例动作\函数

public ActionResult Details(int S)
{
    SLMEntitiesDB dbContext = new SLMEntitiesDB();
    var VL = (from U in dbContext.Users
              join P in dbContext.Products
              on U.PID equals P.PID
              where P.PID == U.PID
              select new UP()
              {
                  UserO = U,
                  ProductO = P
              }).Where(U => U.UserO.LID == S).ToList();
    return View(VL);
}

protected FileResult HandleDataToFileResult(IEnumerable<UP> data)
{
    return new XLSFileResult()
    {
        Data = data,
        FileDownloadName = "MyFile.xls" //by virtue of this assignment, a 'Content-Disposition' Response.Header is added to HttpResponseBase
    };
}

public FileResult GenerateFile()
{
    var data = (IEnumerable<UP>)TempData["GenerateFile"];
    return HandleDataToFileResult(data);
}

剃刀页面

在这个剃须刀页面示例中,我们将使用ActionLink...

@using SLMDemo0.Models
@model IEnumerable<UP>

@{
  ViewBag.Title = "Details";
  //Review TempData, it's session data that clears at the end of the next request
  TempData["GenerateFile"] = Model.ToArray();
}
...

@Html.ActionLink("GenerateFile", "GenerateFile");

【讨论】:

  • 非常感谢 brett 的回答,很抱歉,我对 mvc 完全陌生,我不太了解您的回答(尤其是 XLSFileResult 的第一部分)
  • 关于第一部分是公共类 XLSFileResult : FileResult,这应该在我的控制器中吧?
  • 不是类型(public class)本身的定义..但它的用法应该是(new实例)。
猜你喜欢
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多