Dailycode.info

Short solution for short problems

Download a UTF-8 (with BOM) csv file from API with javascript

I had a webservice that generated a csv file. At first everything seemed ok. But when de users start testing, there were problems with special characters like ë and é and more  when the csv was opened with Excel. With notepad there were no problems. 
A colleague found out that it had something todo with UTF-8 witout BOM. If we changed the encoding to utf-8 (with BOM) then it opened correct in Excel. 
Now I first started to change  the API, trying all kinds of fixes. But at the end it was the front end were the problem occurred. The API side (.Net) looked like this:

#region Export
[Route("GetExport")]
[HttpPost]
[EnableCors(origins: "http://myserver.be", headers: "*", methods: "POST, OPTIONS", exposedHeaders: "Content-Disposition,MyFileName", SupportsCredentials =true)]
public HttpResponseMessage GetExport(BusinessObjects.ExportRequest request)
{
    this.LogMessage("GetExport IN API", JsonConvert.SerializeObject(request));
    HttpResponseMessage resultMessage;            

    if (request != null && request.IsValid())
    {

        var content = "Joëlle;Mark;Peter";
        var encoding = Encoding.UTF8;
        resultMessage = new HttpResponseMessage(HttpStatusCode.OK);
        resultMessage.Content = new StringContent(content, encoding, "text/csv");
        resultMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = request.GetFileNameForRequest()
        };
        resultMessage.Content.Headers.Add("MyFileName", request.GetFileNameForRequest());
    }
    else
    {
        resultMessage = new HttpResponseMessage(HttpStatusCode.BadRequest)
        {
            Content = new StringContent("Invalid ExportRequest.")
        };
    }

    return resultMessage;
}

Up to here everything was working ok. I found out that the problem was rather on the client side were I was getting the file:

There were 2 implementations (first for internet explorer, second for real browsers):

if (window.navigator.msSaveOrOpenBlob) { //Source: http://stackoverflow.com/questions/17836273/export-javascript-data-to-csv-file-without-server-interaction
    var blob = new Blob([decodeURIComponent(encodeURI(rslt.data.toString()))], {
        type: "text/csv;charset=utf-8"
    });
    navigator.msSaveBlob(blob, rslt.fileName);
}
else {
    var element = angular.element("<a/>");
    element.attr({
        href: "data:attachment/csv;charset=utf-8" + encodeURI(rslt.data.toString()),
        target: "_blank",
        download: (rslt.fileName) 
    })[0].click();
}

Now the only thing that did the trick was adding UTF-8 BOM at the start of the text. It was a little different for IE and the rest of the world.

if (window.navigator.msSaveOrOpenBlob) { //Source: http://stackoverflow.com/questions/17836273/export-javascript-data-to-csv-file-without-server-interaction
    var blob = new Blob([decodeURIComponent(encodeURI('\ufeff'+rslt.data.toString()))], {
        type: "text/csv;charset=utf-8"
    });
    navigator.msSaveBlob(blob, rslt.fileName);
}
else {
    var element = angular.element("<a/>");
    element.attr({
        href: "data:attachment/csv;charset=utf-8,%EF%BB%BF" + encodeURI(rslt.data.toString()),
        target: "_blank",
        download: (rslt.fileName) 
    })[0].click();
}

Now when I open the downloaded file in Excel, the special characters are showing fine.


ORACLE: How to find unused tables or indexes

There is a way to see how much reads and writes are done on a table. This query gives an overview of all reads done on tables and indexes. If you export this and generate it every week, compare and see what tables and indexes are used. No need to enable auditing. 

SELECT  vss.owner,
        vss.object_name,
        vss.subobject_name,
        vss.object_type ,
        vss.tablespace_name ,
        SUM(CASE statistic_name WHEN 'logical reads' THEN value ELSE 0 END
            + CASE statistic_name WHEN 'physical reads' THEN value ELSE 0 END) AS reads ,
        SUM(CASE statistic_name WHEN 'logical reads' THEN value ELSE 0 END) AS logical_reads ,
        SUM(CASE statistic_name WHEN 'physical reads' THEN value ELSE 0 END) AS physical_reads ,
        SUM(CASE statistic_name WHEN 'segment scans' THEN value ELSE 0 END) AS segment_scans ,
        SUM(CASE statistic_name WHEN 'physical writes' THEN value ELSE 0 END) AS writes
FROM    v$segment_statistics vss
WHERE   vss.owner NOT IN ('SYS', 'SYSTEM') and VSS.TABLESPACE_NAME = 'USERS'
GROUP BY vss.owner,
        vss.object_name ,
        vss.object_type ,
        vss.subobject_name ,
        vss.tablespace_name
ORDER BY object_type,  reads DESC;



EF: add new Migration when there are multiple migration configurations in your project

You could get this error:

More than one migrations configuration type 'Configuration' was found in the assembly 'BDO.DataLayer.MSSQL'. Specify the fully qualified name of the one to use.

And then look for a while for a solution. You'll find that you need to tell what configuratin type to use, but not so easy to find is how to get this name.

So extend the add-migration command like this (Verbose parameter shows the SQL that is being rendered):

Add-Migration "VATRefundExtraProperties" -ConfigurationTypeName "DataLayer.MSSQL.Migrations.Configuration" -Force –Verbose
And after update the database:

update-database -ConfigurationTypeName "DataLayer.MSSQL.Migrations.Configuration" -Force
You can also add the Verbose flag here if you like.

More info on the attributes for ?-migration: