Solved

character encoding in javascript

Posted on 2016-08-27
12
25 Views
Last Modified: 2016-09-03
Hi,

I have a MVC site which includes a grid with some documents residing in an SQL database. In the grid I have an open button with which I would like to open the document in the client side. The javascript for the button click is like this:
    function openDoc(e) {
        var selected = $(e.currentTarget).closest('tr').find('td:first').text();
        var name = $(e.currentTarget).closest('tr').find('td:nth-child(2)').text();
        $.ajax({
            url: "@Url.Action("OpenFile", "Home")",
            data: { id: selected, fileName: name },
            success: function (data) {
                var blob = new Blob([data]);
                var link = document.createElement('a');
                link.href = window.URL.createObjectURL(blob);
                link.download = name;
                link.click();
            }
        });
    }

Open in new window

and in the controller it looks like this:
        public ActionResult OpenFile(string id, string fileName)
        {
            fileName = Regex.Replace(fileName, " ", "\u00A0");
            byte[] buffer = null;
            byte[] txContext = null;
            string pathName = String.Empty;
            string strExtenstion = fileName.Split('.')[fileName.Split('.').Length - 1];

            using (SqlConnection spConn = new SqlConnection())
            {
                spConn.ConnectionString = ConnectionString;
                SqlCommand cmd = new SqlCommand("SELECT documentContent.PathName() AS FilePath FROM Documents WHERE documentID = '" + id + "'", spConn);
                spConn.Open();
                pathName = cmd.ExecuteScalar() as string;

                //Obtain a Transaction Context
                SqlTransaction transaction = spConn.BeginTransaction("ItemTran");
                cmd.Transaction = transaction;
                cmd.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";
                txContext = cmd.ExecuteScalar() as byte[];

                //Open and read file using SqlFileStream Class
                SqlFileStream sqlFileStream = new SqlFileStream(pathName, txContext, FileAccess.Read);
                buffer = new byte[sqlFileStream.Length];
                sqlFileStream.Read(buffer, 0, buffer.Length);

                //Cleanup
                sqlFileStream.Close();
                cmd.Transaction.Commit();
            }

            string filetype = String.Empty;

            if (strExtenstion.ToLower() == "doc" || strExtenstion.ToLower() == "docx")
            {
                filetype = "application/vnd.ms-word";
            }
            else if (strExtenstion.ToLower() == "xls" || strExtenstion.ToLower() == "xlsx")
            {
                filetype = "application/vnd.ms-excel";
            }
            else if (strExtenstion.ToLower() == "ppt" || strExtenstion.ToLower() == "pptx")
            {
                filetype = "application/vnd.ms-powerpoint";
            }
            else if (strExtenstion.ToLower() == "pdf")
            {
                filetype = "application/pdf";
            }
            else if (strExtenstion.ToLower() == "txt" || strExtenstion.ToLower() == "log")
            {
                filetype = "application/txt";
            }
            else if (strExtenstion.ToLower() == "msg")
            {
                filetype = "application/vnd.ms-outlook";
            }
            else if (strExtenstion.ToLower() == "png" || strExtenstion.ToLower() == "jpg" || strExtenstion.ToLower() == "jpeg" || strExtenstion.ToLower() == "png" || strExtenstion.ToLower() == "gif")
            {
                filetype = "application/paint";
            }
            else
            {
                filetype = "application/octet-stream";
            }

            return File(buffer, filetype, fileName);
        }

Open in new window

It is not working properly. If I try to open a textfile it opens but I can see in the content (I have some swedish characters) that the encoding is wrong.

How can I fix this?

Best regards
RTSOL
0
Comment
Question by:RTSol
  • 7
  • 3
  • 2
12 Comments
 
LVL 78

Expert Comment

by:David Johnson, CD, MVP
ID: 41772942
If I try to open a textfile it opens but I can see in the content (I have some swedish characters) that the encoding is wrong.
This question has nothing to do with javascript.  If you do a binary compare of the original file and the file from the database is it identical?
0
 

Author Comment

by:RTSol
ID: 41772954
Hi,

The thing is that I have another site - normal ASP.NET - in which I open the same file from the database with a handler.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.IO;
using System.Text.RegularExpressions;

namespace MT
{
    /// <summary>
    /// Summary description for DocHandler
    /// </summary>
    public class DocHandler : IHttpHandler
    {

        public static string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["dbMTConnectionString"].ConnectionString;
        public static string sql = string.Empty;

        public void ProcessRequest(HttpContext context)
        {
            //String docName = context.Server.UrlDecode(context.Request.QueryString["docName"].Replace(' ', '_'));
            String docName = context.Server.UrlDecode(context.Request.QueryString["docName"]);
            docName = Regex.Replace(docName, " ", "\u00A0");
            String documentID = context.Request.QueryString["documentID"];
            String[] strExtenstionParts = docName.Split('.');
            String strExtenstion = strExtenstionParts[strExtenstionParts.Length - 1];
            byte[] buffer = null;
            byte[] txContext = null;
            string pathName = String.Empty;

            using (SqlConnection spConn = new SqlConnection())
            {
                spConn.ConnectionString = ConnectionString;
                SqlCommand cmd = new SqlCommand("SELECT documentContent.PathName() AS FilePath FROM Documents WHERE documentID = '" + documentID + "'", spConn);
                spConn.Open();
                pathName = cmd.ExecuteScalar() as string;

                //Obtain a Transaction Context
                SqlTransaction transaction = spConn.BeginTransaction("ItemTran");
                cmd.Transaction = transaction;
                cmd.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";
                txContext = cmd.ExecuteScalar() as byte[];

                //Open and read file using SqlFileStream Class
                SqlFileStream sqlFileStream = new SqlFileStream(pathName, txContext, FileAccess.Read);
                buffer = new byte[sqlFileStream.Length];
                sqlFileStream.Read(buffer, 0, buffer.Length);

                //Cleanup
                sqlFileStream.Close();
                cmd.Transaction.Commit();
            }

            context.Response.Clear();
            context.Response.Buffer = true;

            if (strExtenstion.ToLower() == "doc" || strExtenstion.ToLower() == "docx")
            {
                context.Response.ContentType = "application/vnd.ms-word";
                context.Response.AddHeader("content-disposition", "attachment;filename=" + docName);
            }
            else if (strExtenstion.ToLower() == "xls" || strExtenstion.ToLower() == "xlsx")
            {
                context.Response.ContentType = "application/vnd.ms-excel";
                context.Response.AddHeader("content-disposition", "attachment;filename=" + docName);
            }
            else if (strExtenstion.ToLower() == "ppt" || strExtenstion.ToLower() == "pptx")
            {
                context.Response.ContentType = "application/vnd.ms-powerpoint";
                context.Response.AddHeader("content-disposition", "attachment;filename=" + docName);
            }
            else if (strExtenstion.ToLower() == "pdf")
            {
                context.Response.ContentType = "application/pdf";
                context.Response.AddHeader("content-disposition", "attachment;filename=" + docName);
            }
            else if (strExtenstion.ToLower() == "txt" || strExtenstion.ToLower() == "log")
            {
                context.Response.ContentType = "application/txt";
                context.Response.AddHeader("content-disposition", "attachment;filename=" + docName.Replace(" ", "_"));
            }
            else if (strExtenstion.ToLower() == "msg")
            {
                context.Response.ContentType = "application/vnd.ms-outlook";
                //context.Response.AddHeader("content-disposition", "attachment;filename=" + docName);
                context.Response.AddHeader("content-disposition", "inline;filename=" + docName);
            }
            else if (strExtenstion.ToLower() == "png" || strExtenstion.ToLower() == "jpg" || strExtenstion.ToLower() == "jpeg" || strExtenstion.ToLower() == "png" || strExtenstion.ToLower() == "gif")
            {
                context.Response.ContentType = "application/paint";
                context.Response.AddHeader("content-disposition", "attachment;filename=" + docName);
            }
            else
            {
                context.Response.ContentType = "application/octet-stream";
                context.Response.AddHeader("content-disposition", "attachment;filename=" + docName);
            }

            

            context.Response.Charset = "";
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);

            context.Response.BinaryWrite(buffer);

            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

Open in new window


In this site I get the file to open correctly and if I compare it with the original file they are identical.

Best regards
RTSOL
0
 

Author Comment

by:RTSol
ID: 41773059
Hi,

I made some tests. I have a very small text file with the characters AÅÄÖ. In the controller the array 65, 197, 196, 214 is passed to the javascript call. They are all the correct character codes for the characters in the file. However, in the javascript side only the character A has the correct code. The swedish characters all have the code 65533. It seems my knowledge of javascript is to limited. Can someone please help me to pass the correct array to the client? It now looks like this
    function openDoc(e) {
        var selected = $(e.currentTarget).closest('tr').find('td:first').text();
        var name = $(e.currentTarget).closest('tr').find('td:nth-child(2)').text();
        $.ajax({
            url: "@Url.Action("OpenFile", "Home")",
            data: { id: selected, fileName: name },
            success: function (data) {
                console.log("1: " + data.charCodeAt(0) + ", 2: " + data.charCodeAt(1) + ", 3: " + data.charCodeAt(2) + ", 4: " + data.charCodeAt(3));
                console.log("1: " + data[0] + ", 2: " + data[1] + ", 3: " + data[2] + ", 4: " + data[3]);
                console.log(data);
            }
        });
    }

Open in new window

Best regards
RTSOL
0
 
LVL 78

Expert Comment

by:David Johnson, CD, MVP
ID: 41773076
what is your doctype for the page? do you have any encoding ?
0
 

Author Comment

by:RTSol
ID: 41773086
I am not sure I understand. My original question was about decoding. The controller is passing this:
return File(buffer, filetype, fileName);
where buffer is the array 65, 197, 196, 214, filetype is "application/txt" and filename is the name of the file.
0
 
LVL 78

Expert Comment

by:David Johnson, CD, MVP
ID: 41773336
Are you displaying the output or actually downloading the file. Displaying will use the character encoding of the page
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 82

Expert Comment

by:leakim971
ID: 41773404
try this :
    function openDoc(e) {
        var selected = $(e.currentTarget).closest('tr').find('td:first').text();
        var name = $(e.currentTarget).closest('tr').find('td:nth-child(2)').text();
        $.ajax({
            contentType:"application/x-javascript; charset:ISO-8859-1"
            url: "@Url.Action("OpenFile", "Home")",
            data: { id: selected, fileName: name },
            success: function (data) {
                console.log("1: " + data.charCodeAt(0) + ", 2: " + data.charCodeAt(1) + ", 3: " + data.charCodeAt(2) + ", 4: " + data.charCodeAt(3));
                console.log("1: " + data[0] + ", 2: " + data[1] + ", 3: " + data[2] + ", 4: " + data[3]);
                console.log(data);
            }
        });
    }

Open in new window

or just be sure to use UTF-8 EVERYWHERE (page, database, server side, client side, EVERYWHERE)
0
 

Author Comment

by:RTSol
ID: 41774611
Hi guys,

I am lost in the encoding jungle. I got everything to work with text files - they download ok and open ok. However, any other file like word files download ok but can not be opened.

I have another approach that works better. In the controller I get the file in the database and then download it to a folder in the server passing the file name to the client. Then, on the client side, I create a link like this:
    function downloadDoc(e) {
        var selected = $(e.currentTarget).closest('tr').find('td:first').text();
        var name = $(e.currentTarget).closest('tr').find('td:nth-child(2)').text();
        $.ajax({
            url: "@Url.Action("DownloadFile", "Home")",
            data: { id: selected, fileName: name },
            success: function (filename) {
                var link = document.createElement('a');
                link.href = "../../DownLoads/" + filename;
                link.mimetype = "application/vnd.ms-outlook";
                console.log(link);
                link.download = name;
                link.click();
            }
        });
    }

Open in new window

This works fine for all files except for msg files. They don't download and if I run the url in the browser I get the error shown in the attachment. It seems to be a MIME problem. If you can hint me how to fix this I am all set.

Best regards
RTSOL
MIME..jpg
0
 
LVL 82

Expert Comment

by:leakim971
ID: 41774644
<< I am lost in the encoding jungle >>
Yeah, that's why I said : Go UTF-8 everywhere you can. And stop to work with data inside database, this data have wrong encoding and give you false tests and results.
0
 

Author Comment

by:RTSol
ID: 41774652
Hi,

Do you have a solution for my MIME problem?

Best regards
RTSOL
0
 

Accepted Solution

by:
RTSol earned 0 total points
ID: 41775121
Ok - I solved it. I will close the ticket now
0
 

Author Closing Comment

by:RTSol
ID: 41782787
All issues solved by me.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction This article shows how to use the open source plupload control to upload multiple images. The images are resized on the client side before uploading and the upload is done in chunks. Background I had to provide a way for user…
JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now