0

Hello clever coding people, I am working on a MVC project for college, and I am trying to output an invoice, I do not need to view the invoice, just create a downloadable text file. I have been trying to use StringBuilder to get the details from ViewBag, but they are not being written into the file. I am using a @HtmlActionLink to create it from the view. I am sure I am doing something stupid, any advice would be greatly appreciated. Thanks a million.

Method in my Controller:

public FileStreamResult Invoice()
    {
        StringBuilder sb = new StringBuilder("Your Invoice");

        sb.AppendLine(" ");
        sb.AppendLine("Id:"+ @ViewBag.ClientId);
        sb.AppendLine("Name:" + @ViewBag.Name);
        sb.AppendLine("Total:" + @ViewBag.Total);

        var invoiceDetails = sb.ToString();

        var byteArray = Encoding.ASCII.GetBytes(invoiceDetails);
        var stream = new MemoryStream(byteArray);


        return File(stream, "text/plain", "Invoice.txt");

    }
  • Hi Esther, are you trying to post ClientId,Name and Total from your webpage? Or if not where are these coming from? – Glynn Hurrell May 02 '20 at 16:18
  • they're coming from an azure database – Esther Leonard May 02 '20 at 16:26
  • In which case ViewBag isn't the best way to be transporting data in the back end. You need to look at creating a models to represent data (classes) and then use these models in your actions. I will post an answer shortly – Glynn Hurrell May 02 '20 at 16:29
  • Eeeek! Sorry, I probably should have posted my model classes too. Should I post a link to my GitHub repository? – Esther Leonard May 02 '20 at 16:39
  • yes go for it. should be easier to see. – Glynn Hurrell May 02 '20 at 16:42
  • https://github.com/thewarpdrive84/EL_Dog_Grooming – Esther Leonard May 02 '20 at 16:46
  • the invoice method is in the CartServiceController, and the ActionResult is in the GoToCart View. Thanks so so much Glynn!!! – Esther Leonard May 02 '20 at 16:47
  • Having skimmed through your code, the biggest issue is that you are using ViewBag which only has a life cycle of the current request and therefore when you try and and retrieve the values in your action, they will, always be NULL. If the data is temporary then you could look at using Session (HttpContext.Current.Session from within your action) or if it needs to be stored in a database then you need to look into using data in ASP NET.... https://learn.microsoft.com/en-us/aspnet/web-pages/overview/data/5-working-with-data – Glynn Hurrell May 02 '20 at 16:57
  • Or this .... https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database. There are many approaches to take. Using something like Entity Framework should make it easy enough to use your data – Glynn Hurrell May 02 '20 at 17:00
  • Cool, thanks so much Glynn! I as you can probably see I need all the help I can get! Those links look really helpful. Thank you! – Esther Leonard May 02 '20 at 17:10
  • No problem... we've all got to start from somewhere. Good luck :) – Glynn Hurrell May 02 '20 at 17:12

1 Answers1

0

You could pass a parameter, an ID of the invoce into the action that downloads the invoce.

The action link for downloading the invoice with the ID parameter:

@Html.ActionLink("Download invoice", "Invoice", "MyController", new { id = @Model.InvoiceId }) 

@Model.InvoiceId comes from the model of the view displaying the invoice.

The controller action:

public FileStreamResult Invoice(int id)
{
    ...
}
Martin Staufcik
  • 8,295
  • 4
  • 44
  • 63