1

I have a mvc web application which contains chart and table data.

Scenario:

I am populating data in the Index method and return the model to view for binding. In view, table bind with the data. I also want to bind the chart with same data. Chart bind with child action. I set TempData[] object in the Index method and retrieve the same in Chart action.

Code:

Controller

        public ActionResult Index()
    {
        var data = new List<MyModel>()
        {
            new MyModel { Text = "Name1", Value = 123 },
            new MyModel { Text = "Name2", Value = 24 },
        };
        TempData["data"] = data;
        return View(data);
    }

    public FileContentResult Chart()
    {
        List<MyModel> data = TempData["data"] as List<MyModel>;
        var chart = new Chart
        {
            Width = 300,
            Height = 450,
       };
        if (data != null)
        {
            chart.ChartAreas.Add("");
            chart.Series.Add("");
            chart.Series[0].ChartType = SeriesChartType.Column;
            foreach (var q in data)
            {
                chart.Series[0].Points.AddXY(q.Text, Convert.ToDouble(q.Value));
            }
        }
        using (var chartimage = new MemoryStream())
        {
            chart.SaveImage(chartimage, ChartImageFormat.Png);
            return File(chartimage.GetBuffer(), @"image/png");
        }
    }

    public async Task<ActionResult> Export()
    {
        var converter = new HtmlToPdf();
        var baseAddress = new Uri("http://localhost:4545/");
        var cookieContainer = new System.Net.CookieContainer();

        using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
        using (HttpClient client = new HttpClient(handler) { BaseAddress = baseAddress })
        {
            var result = await client.GetAsync("/Home/Index");
            var htmlString = await result.Content.ReadAsStringAsync();

            var doc = converter.ConvertHtmlString(htmlString, baseAddress.ToString());
            doc.Save(System.Web.HttpContext.Current.Response, true, "test.pdf");
            doc.Close();
        }
        return null;
    }

View:

<div class="row">
@using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
<div class="col-md-12">
    <table>
        @{
            foreach (var item in Model)
            {
                <tr>
                    <td>
                        @item.Text
                    </td>
                    <td>
                        @item.Value
                    </td>
                </tr>
                }
        }
    </table>
</div>
<div class="col-md-12">
    <img src="@Url.Action("Chart")" />
    <input type="submit" value="Filter" />
</div>
}
<div class="col-md-12">
    @using (Html.BeginForm("Export", "Home", FormMethod.Post))
    {
        <input type="submit" value="Export" />
    }
</div>

Problem:

Here i am using SelectPdf to export the web page to pdf. When i click Export button, it takes the content of web page so that again Index and Chart rendered. But here i didn't get tempdata[] values. It shows as null. So chart data not getting in pdf

Please help me to solve this issue

Akhil
  • 1,918
  • 5
  • 30
  • 74
  • Have you tried using ViewData? – Anthony McGrath Feb 13 '18 at 04:29
  • Please have a look at this link https://hassantariqblog.wordpress.com/2016/09/02/mvc-when-to-use-keep-vs-peek-in-asp-net-mvc/ – Nishant Shrivastava Feb 13 '18 at 05:04
  • nice article. I got that. I think the issues in export button. In that method i get the contents of view using httpClient. Any wrong there? – Akhil Feb 13 '18 at 09:57
  • 1
    I solved the issue by change the export method. Instead of using hppclient to get the html string, I directly give url to convert into pdf and solved the issue – Akhil Feb 14 '18 at 12:45

2 Answers2

3

Please Note :

TempData in ASP.NET MVC can be used to store temporary data which can be used in the subsequent request. TempData will be cleared out after the completion of a subsequent request.

So to retain the values of TempData in subsequent request you need to call either TempData.Keep() or Peek("tempdata name").

Keep Syntax:

String data = TempData["myData"] as string;
TempData.Keep();

Peek Syntax:

String data = TempData.Peek("myData");
Dotnetpickles
  • 1,016
  • 8
  • 13
  • i tried this. but still i didn't get the data. When i click Export button and debug, still i am getting null even if i used Peek. Any impact due to that export action implementation? – Akhil Feb 13 '18 at 07:31
0

Try this

List<MyModel> data = (List<MyModel>)TempData.Peek("data");