2

I am using FileStream.Create to upload a .csv file onto a server and then read it into a SQL database. Once it is read in, I just delete the file from the folder that it was written to. The goal is to just get the file into the database. This would run fine locally, but I cannot get write access on the new server so I get an UnauthorizedAccessException. I don't think that it is necessary to upload the file to the server to read it into the SQL table, but I am having trouble adjusting the code.

[HttpPost]
    public ActionResult UploadValidationTable(HttpPostedFileBase csvFile)
    {
        var inputFileDescription = new CsvFileDescription
        {
            SeparatorChar = ',',
            FirstLineHasColumnNames = true
        };
        var cc = new CsvContext();
        var filePath = uploadFile(csvFile.InputStream);
        var model = cc.Read<Credit>(filePath, inputFileDescription);

        try
        {
            var entity = new Entities();
            foreach (var item in model)
            {
                var tc = new TemporaryCsvUpload
                {
                    Id = item.Id,
                    Amount = item.Amount,
                    Date = item.Date,
                    Number = item.Number,
                    ReasonId = item.ReasonId,
                    Notes = item.Notes
                };
                entity.TemporaryCsvUploads.Add(tc);
            }
            entity.SaveChanges();

            System.IO.File.Delete(filePath);

Here is the uploadFile method:

        private string uploadFile(Stream serverFileStream)
    {
        const string directory = "~/Content/CSVUploads";

        var directoryExists = Directory.Exists(Server.MapPath(directory));

        if (!directoryExists)
        {
            Directory.CreateDirectory(Server.MapPath(directory));
        }

        var targetFolder = Server.MapPath(directory);
        var filename = Path.Combine(targetFolder, Guid.NewGuid() + ".csv");

        try
        {
            const int length = 256;
            var buffer = new byte[length];

            // write the required bytes
            using (var fs = new FileStream(filename, FileMode.Create))
            {
                int bytesRead;
                do
                {
                    bytesRead = serverFileStream.Read(buffer, 0, length);
                    fs.Write(buffer, 0, bytesRead);
                } while (bytesRead == length);
            }

            serverFileStream.Dispose();
            return filename;
        }
        catch (Exception)
        {
            return string.Empty;
        }
    }

To sum it up, I am uploading a .csv file to a temporary location, reading it into an object, reading it into a database, then deleting the .csv file out of the temporary location. I am using Linq2Csv to create the object. Can I do this without uploading the file to the server (because I can't get write access)?

cfly24
  • 1,882
  • 3
  • 22
  • 56
  • 1
    Why do you have to save the csv? Why create a csv in the first place? Why not just create a byte array and upload that into the database (bypassing the need to create that temporary csv)? – Lareau Aug 04 '15 at 12:59
  • I have never used a byte array before. Googling now. – cfly24 Aug 04 '15 at 13:00
  • You can probably build your csv using a stringbuilder as well? Not sure how the csvContext works though. – Lareau Aug 04 '15 at 13:01
  • csvContext is a LinqToCsv class. I should've included that. – cfly24 Aug 04 '15 at 13:03
  • Your error handling is appalling, I must say. In case of error you just do nothing. What does that accomplish? Worse than not handling. Maybe you are trying to delete the file "". Remove that error handling and test again. – usr Aug 04 '15 at 13:11
  • I was planning on adding error handling after I figured out what the best way to move forward without FileStream. But yeah, right now it doesn't do anything to help – cfly24 Aug 04 '15 at 13:17
  • Remove it to make sure that you are not trying to delete "" which would fail. – usr Aug 04 '15 at 13:21
  • Same issue, I know that it is happening because I can't get write access to the folder on the server, but it does run fine locally – cfly24 Aug 04 '15 at 13:24

1 Answers1

0

According to http://www.codeproject.com/Articles/25133/LINQ-to-CSV-library,

you can read from a StreamReader

Read<T>(StreamReader stream)
Read<T>(StreamReader stream, CsvFileDescription fileDescription)

You can probably use a streamreader (or a stringbuilder) to create your file instead of a csv - Write StringBuilder to Stream

How to take a stringbuilder and convert it to a streamReader?

and then send that to your CSVContext?

Community
  • 1
  • 1
Lareau
  • 1,982
  • 1
  • 26
  • 47
  • Thanks for your answer. I was able to get this working by changing only one line: `var csvReader = new StreamReader(csvFile.InputStream);` – cfly24 Aug 04 '15 at 13:49
  • And then inserting it as the first parameter instead: `var model = cc.Read(csvReader, inputFileDescription);` – cfly24 Aug 04 '15 at 13:54