DEV Community

Cover image for Upload and Download Pdf files to/from MS SQL Database using Razor Pages
Zoltan Halasz
Zoltan Halasz

Posted on

Upload and Download Pdf files to/from MS SQL Database using Razor Pages

As most of my project applications are business related, and I still plan to create such applications, thought about the idea to store attached pdf invoices in a database.

Below is a simple sample application, using Asp.Net Core 3.1 and Razor Pages, for an invoice management system with pdf file upload/download.

The Github repo for the application is here. https://github.com/zoltanhalasz/UploadFile

The application is also online, can be tested out: https://uploadfile.zoltanhalasz.net/

Prerequisites:

My sources for learning were:

CREATE TABLE [dbo].[Invoices](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Number] [int] NOT NULL,
    [Date] [datetime] NOT NULL,
    [Value] [decimal](18, 2) NOT NULL,
    [Attachment] [varbinary](max) NULL,
 CONSTRAINT [PK_Invoices] PRIMARY KEY CLUSTERED ([Id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Enter fullscreen mode Exit fullscreen mode

Steps for creating the application:
Create an Asp.Net Razor Pages project
.Net Core version 3.1

Scaffold the database into the models using
https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools or simply copy my Data folder that is adding the necessary data structures
Alternatively, you can use the more traditional caffolding method: https://www.entityframeworktutorial.net/efcore/create-model-for-existing-database-in-ef-core.aspx

Make sure that the model and dbContext (called UploadFileContext) will be stored in Data folder.

Add to Startup.cs, ConfigureServices method:

 services.AddDbContext<UploadfileContext>(options =>
                  options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),           
                    sqlServerOptions => sqlServerOptions.CommandTimeout(100))
                    );
Enter fullscreen mode Exit fullscreen mode

Create Index page, that will show the list of invoices

  • the page cshtml file will contain the listing of the invoices, together with the download, upload, and delete functionalities

https://github.com/zoltanhalasz/UploadFile/blob/master/UploadFile/Pages/Index.cshtml

  • the PageModel class will contain the methods to deal with:

a. download the pdf file from the database:

public async Task<IActionResult> OnPostDownloadAsync(int? id)
{
            var myInv = await _context.Invoices.FirstOrDefaultAsync(m => m.Id == id);
            if (myInv == null)
            {
                return NotFound();
            }

            if (myInv.Attachment== null)
            {
                return Page();
            }
            else
            {
                byte[] byteArr = myInv.Attachment;
                string mimeType = "application/pdf";
                return new FileContentResult(byteArr, mimeType)
                {
                    FileDownloadName = $"Invoice {myInv.Number}.pdf"
                };
            }
}
Enter fullscreen mode Exit fullscreen mode

b. delete attached file from database:

public async Task<IActionResult> OnPostDeleteAsync(int? id)
{
            var myInv = await _context.Invoices.FirstOrDefaultAsync(m => m.Id == id);
            if (myInv == null)
            {
                return NotFound();
            }

            if (myInv.Attachment == null)
            {
                return Page();
            }
            else
            {
                myInv.Attachment = null;
                _context.Update(myInv);
                await _context.SaveChangesAsync();
            }

            Invoices = await _context.Invoices.ToListAsync();
            return Page();
}
Enter fullscreen mode Exit fullscreen mode

Add a page to create Invoice Data (this can be done via Razor Pages scaffolding)

see https://github.com/zoltanhalasz/UploadFile/blob/master/UploadFile/Pages/Create.cshtml
and
https://github.com/zoltanhalasz/UploadFile/blob/master/UploadFile/Pages/Create.cshtml.cs

Create an Upload Page that will help with pdf file upload

This will have the file with markup, cshtml, containing the html tags for the form:

page
@model UploadFile.Pages.UploadModel
@{
}

<h1>Upload Invoice</h1>


<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post" enctype="multipart/form-data">
            <div class="form-group">
                <div class="col-md-10">
                    <p>Upload file</p>
                    <input type="hidden" asp-for="@Model.ID" value="@Model.myID" />
                    <input asp-for="file" class="form-control" accept=".pdf" type="file" />
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-10">
                    <input class="btn btn-success" type="submit" value="Upload" />
                </div>
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>
Enter fullscreen mode Exit fullscreen mode

And for the PageModel class, we will have the handler to deal with the file uploaded:

public class UploadModel : PageModel
{                  

        private readonly UploadfileContext _context;

        public UploadModel(UploadfileContext context)
        {

            _context = context;
        }
        public int ? myID { get; set; }

        [BindProperty]
        public IFormFile file { get; set; }

        [BindProperty]
        public int ? ID { get; set; }
        public void OnGet(int? id)
        {
            myID = id;
        }

        public async Task<IActionResult> OnPostAsync()
        {
            if (file != null)
            {
                if (file.Length > 0 && file.Length < 300000)
                {
                    var myInv = _context.Invoices.FirstOrDefault(x => x.Id == ID);

                    using (var target = new MemoryStream())
                    {
                        file.CopyTo(target);
                        myInv.Attachment = target.ToArray();
                    }

                    _context.Invoices.Update(myInv);
                    await _context.SaveChangesAsync();
                }

            }

            return RedirectToPage("./Index");
        }

}
Enter fullscreen mode Exit fullscreen mode

The end result will be like this:
Alt Text

Top comments (0)