Reading and Displaying Uploaded text Files in MVC

b0w3rb0w3r picture b0w3rb0w3r · May 8, 2013 · Viewed 18k times · Source

Is it possible to read uploaded text files e.g .txt and display the content in a textbox ? I want to do a file conversion of the uploaded files. I've managed to upload and validate the files I would like at the click of a button to read the contents and display them in a textbox ready for conversion. How would I go about doing this? Upload class

public class UploadedFile
{
    public long Size { get; set; }
    public string Path { get; set; }
    public string Name { get; set; }
   // public int Length { get; set; }
    public string extension { get; set; }
}

public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

        return View();
    }
    [HttpPost]
    public ActionResult Index(HttpPostedFileBase file)
    {
        var supportedTypes = new[] { "txt", "rtf", "html", "xaml", "xslx" ,"pdf", "doc", "docx", "csv" };

        var fileExt = System.IO.Path.GetExtension(file.FileName).Substring(1);

        if (!supportedTypes.Contains(fileExt))
        {
            ModelState.AddModelError("file", "Invalid type. Only the following types (txt, rtf, html, xslx, pdf, xaml, doc, docx, csv) are supported.");
            return View();
        }
        if (file.ContentLength > 200000)
        {
            ModelState.AddModelError("file", "The size of the file should not exceed 200 KB");
            return View();
        }
        if (file.ContentLength > 0)
        {


            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(Server.MapPath("~/uploads"), fileName);
            file.SaveAs(path);
        }

        return RedirectToAction("Index");
    }

    public ActionResult About()
    {
       var uploadedFiles = new List<UploadedFile>();
        var files = Directory.GetFiles(Server.MapPath("~/uploads"));
        foreach(var file in files)
        {
            var fileInfo = new FileInfo(file);
            var uploadedFile = new UploadedFile() {Name = Path.GetFileName(file)};
            uploadedFile.Size = fileInfo.Length;
            uploadedFile.extension = Path.GetExtension(file);

            uploadedFile.Path = ("~/uploads/") + Path.GetFileName(file);

            uploadedFiles.Add(uploadedFile);
        }
        return View(uploadedFiles);
    }
}

So far the files uploaded are listed in a table.I would like to read and display the contents if the button is Clicked and the contents placed inside the text area below the table. So I can perform conversion.

enter image description here How would I achieve this? Thanks

`<script>$('btnreadfile').click(function () {
    document.location = '@Url.Action("ReadTextFile","Home")'; });</script>
      <input id="btnreadfile" name="btnReadFile" type="submit" value="Read File"/>

    `My button Code

Answer

HaBo picture HaBo · May 8, 2013

Working code. Fully tested

in you _Layout.cshtml

<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</head>

in your About.cshtml

Table mark up

<table style="background-color: lightgreen; border: solid 2px black;">
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            <b>Size</b>
        </td>
        <td>
            <b>Preview</b>
        </td>
        <td>
            <b>Read File</b>
        </td>
    </tr>
    @foreach (var file in Model)
    {    
        <tr>
            <td>
                @file.Name
            </td>
            <td>
                @(file.Size / 1000) KB
            </td>
            <td>
                @(file.extension)
            </td>
            <td>
                <input id="btnreadfile" name="@file.Name" class='btnClick' type="button" value="Read File"/>
                <textarea rows="4" cols="50">
</textarea>
            </td>
        </tr>   
    }
</table>

in your About.cshtml all the way bottom add this script

<script>
    $.ajax({
        url: "/Home/ReadTextFile", 
        type: "GET",
        data: { fileName: $(this).attr("name") },
        DataType: "text",
        success: function (str) {
            alert(str);
            $("textarea").val(str); // this line has to be replaced with more dynamic jQuery selector that can select this button next textarea
            //$(this).next("textarea").val(str);
        },
        error: function (err) {
            alert(err);
        }
    });
});
</script>

in Your Controller

  • Add reference using System.Runtime.InteropServices.ComTypes;
  • add a JsonResult Method

public JsonResult ReadTextFile(string fileName)
        {
            string retString = string.Empty;
            string path = Path.Combine(Server.MapPath("~/uploads") , fileName );
            if (System.IO.File.Exists(path))
            {
                if (Path.GetExtension(path) == "doc" || Path.GetExtension(path) == ".docx")
                {
                    Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
                    object miss = System.Reflection.Missing.Value;
                    object readOnly = true;
                    object wordPath = path;
                    Microsoft.Office.Interop.Word.Document docs = word.Documents.Open(
                        ref wordPath, 
                        ref miss, 
                        ref readOnly, 
                        ref miss, ref miss, ref miss, 
                        ref miss, ref miss, ref miss, 
                        ref miss, ref miss, ref miss, 
                        ref miss, ref miss, ref miss, ref miss);
                    for (int i = 0; i < docs.Paragraphs.Count; i++)
                    {
                        retString += " \r\n " + docs.Paragraphs[i + 1].Range.Text.ToString();
                    }
                }
                else if (Path.GetExtension(path) == "txt")
                {
                    using (StreamReader sr = new StreamReader(path))
                    {
                        retString = sr.ReadToEnd();
                    }
                }
            }
            return Json(retString, JsonRequestBehavior.AllowGet);
        }

Note: I have considered to read only files with extension .doc, .docx and .txt any other extensions should be handled further