ASP NET MVC and HTML5 audio - file not playing - asp.net-mvc

I am trying to create a table containing audio files, which should start playing when the user clicks the play button. This is what I've tried so far:
Controller:
[HttpGet]
public ActionResult PlayFile(string FilePath)
{
WebClient WC = new WebClient();
WC.Credentials = new System.Net.NetworkCredential("username", "password");
byte[] buff = WC.DownloadData(FilePath);
var SplitFileName = FilePath.Split('\\');
string FileName = "Recording_" + SplitFileName[SplitFileName.Count() - 1];
Response.AddHeader("Content-Disposition", "inline; filename=" + FileName);
MemoryStream stream = new MemoryStream(buff);
return new FileStreamResult(stream, "audio/wav");
//I have also tried:
//return File(buff, "audio/wav");
}
The audio tags look like this:
<td>
<audio controls preload='none'>
<source src='/Components/PlayFile?FilePath=[filename.wav]' type='audio/wav'>
</audio>
</td>
When running the site locally in Chrome, all the files have the length 0:00, and you can click the play button once but the file is not played. After the play button has been clicked once it is not possible to click it again. It is however possible to download the file
and play it. When running the site locally in Firefox, the files also have the length 0:00, and when you click the play button the control disappears. It is also possible to download the file in Firefox. Does anyone know what could be causing this?

The problem was that the audio files were in GSM format and needed to be converted to PCM. This code works:
[HttpGet]
public ActionResult PlayFile(string FilePath)
{
WebClient WC = new WebClient();
WC.Credentials = new System.Net.NetworkCredential("username", "password");
byte[] buff = WC.DownloadData(FilePath);
var SplitFileName = FilePath.Split('\\');
string FileName = "Recording_" + SplitFileName[SplitFileName.Count() - 1];
MemoryStream ms = new MemoryStream();
ms.Write(buff, 0, buff.Length);
ms.Seek(0, SeekOrigin.Begin);
MemoryStream outputStream = new MemoryStream();
using (NAudio.Wave.WaveFileReader reader = new WaveFileReader(ms))
using (NAudio.Wave.WaveStream waveStream = NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(reader))
using (NAudio.Wave.WaveFileWriter waveFileWriter = new WaveFileWriter(outputStream, waveStream.WaveFormat))
{
byte[] bytes = new byte[waveStream.Length];
waveStream.Position = 0;
waveStream.Read(bytes, 0, (int)waveStream.Length);
waveFileWriter.Write(bytes, 0, bytes.Length);
waveFileWriter.Flush();
}
return File(outputStream.ToArray(), "audio/wav");
}

Can you try with below as its working for me.
public FileResult PlayFile(string FilePath)
{
return new FilePathResult(FilePath, "audio/wav");
}
Also, try changing "audio/wav" to "audio/mp3", if it helps.

Related

itextsharp generates blank PDF on server but works on dev machine in MVC

I am using itextsharp to generate PDF in MVC application and this works very well on dev machine. When i deploy this on pre-production machine, this generates blank PDF page and no exception. I tried quick debugging using logging to see if I'm getting content or not after line StringReader sr = new StringReader(sb.ToString()); and i see it has content.
After some research I found one faced similar issue and he resolved this issue just by writing document.Open() after PdfWriter.GetInstance. Source: "The document is not open" error only in production with iTextSharp
After that, I thought to use code which worked for many developers How to convert HTML to PDF using iTextSharp and I still see blank PDF on pre-production but works on dev machine.
I doubt if itextsharp has some sort of dependency on operation system or office suit (with itextsharp latest updates) because as I said it works on dev machine.
Here's the code which generates blank PDF on production machine Windows Server 2012 R2.
public ActionResult DownloadOrderReceipt(string id)
{
string companyName = "Name Here";
int orderNo = 2303;
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[5]
{
new DataColumn("ProductId", typeof(string)),
new DataColumn("Product", typeof(string)),
new DataColumn("Price", typeof(int)),
new DataColumn("Quantity", typeof(int)),
new DataColumn("Total", typeof(int))
});
dt.Rows.Add(101, "Sun Glasses", 200, 5, 1000);
dt.Rows.Add(102, "Jeans", 400, 2, 800);
dt.Rows.Add(103, "Trousers", 300, 3, 900);
dt.Rows.Add(104, "Shirts", 550, 2, 1100);
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter hw = new HtmlTextWriter(sw))
{
StringBuilder sb = new StringBuilder();
// generate invoice header
sb.Append("<table width='100%' cellspacing='0' cellpadding='2'>");
sb.Append("<tr><td align='center' style='background-color: #18B5F0' colspan = '2'><b>Order Sheet</b></td></tr>");
sb.Append("<tr><td colspan = '2'></td></tr>");
sb.Append("<tr><td><b>Order No: </b>");
sb.Append(orderNo);
sb.Append("</td><td align = 'right'><b>Date: </b>");
sb.Append(DateTime.Now);
sb.Append(" </td></tr>");
sb.Append("<tr><td colspan = '2'><b>Company Name: </b>");
sb.Append(companyName);
sb.Append("</td></tr>");
sb.Append("</table>");
sb.Append("<br />");
// generate invoice items grid
sb.Append("<table border = '1'>");
sb.Append("<tr>");
foreach (DataColumn column in dt.Columns)
{
sb.Append("<th style = 'background-color: #D20B0C;color:#ffffff'>");
sb.Append(column.ColumnName);
sb.Append("</th>");
}
sb.Append("</tr>");
foreach (DataRow row in dt.Rows)
{
sb.Append("<tr>");
foreach (DataColumn column in dt.Columns)
{
sb.Append("<td>");
sb.Append(row[column]);
sb.Append("</td>");
}
sb.Append("</tr>");
}
sb.Append("<tr><td align = 'right' colspan = '");
sb.Append(dt.Columns.Count - 1);
sb.Append("'>Total</td>");
sb.Append("<td>");
sb.Append(dt.Compute("sum(Total)", ""));
sb.Append("</td>");
sb.Append("</tr></table>");
// export html string into PDF
StringReader sr = new StringReader(sb.ToString());
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
pdfDoc.Open();
htmlparser.Parse(sr);
pdfDoc.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=Invoice_" + orderNo + ".pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Write(pdfDoc);
Response.End();
}
}
return new EmptyResult();
}
Any help on this is highly appreciated.
Updated 1 (still same issue)
I just updated and simplified my code according to suggestions, but I still see same issue:
public ActionResult DownloadOrderReceipt(string id)
{
var order = orderRepository.Get(id);
if (order == null)
return new EmptyResult();
using (MemoryStream stream = new MemoryStream())
{
string htmlContent = "<p>Write this on PDF Page</p>";
StringReader sr = new StringReader(htmlContent);
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 100f, 0f);
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, stream);
pdfDoc.Open();
XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
pdfDoc.Close();
return File(stream.ToArray(), "application/pdf", "Invoice_121212.pdf");
}
}
This also works on dev machine but on pre-production this generates blank PDF page.
Updated 2 (still same issue)
My attempt to fix this working on pre-production is ON. Here's the another two samples which I just tried and no help.
public ActionResult DownloadOrderReceipt(string id)
{
byte[] bytes;
using (var ms = new MemoryStream())
{
using (var doc = new Document())
{
using (var writer = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
var example_html = #"<p>This <em>is </em><span class=""headline"" style=""text-decoration: underline;"">some</span> <strong>sample <em> text</em></strong><span style=""color: red;"">!</span></p>";
var example_css = #".headline{font-size:200%}";
// example 1
//using (var srHtml = new StringReader(example_html))
//{
// XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml);
//}
// example 2
using (var msCss = new MemoryStream(Encoding.UTF8.GetBytes(example_css)))
{
using (var msHtml = new MemoryStream(Encoding.UTF8.GetBytes(example_html)))
{
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss);
}
}
doc.Close();
}
}
bytes = ms.ToArray();
}
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=Invoice_1212121212.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(bytes);
Response.End();
return new EmptyResult();
}
SOLUTION
Updating this question after long time, because i noticed new comments.
In the process of code review I found that developer had wrote logic to minify HTML content dynamically that caused the bites removed from PDF too and hence empty PDF.
This works for me, MemoryStream is important:
public class PDFController : Controller
{
// GET: PDF
public ActionResult Index(string address)
{
SelectPdf.HtmlToPdf converter = new SelectPdf.HtmlToPdf();
SelectPdf.PdfDocument doc = converter.ConvertUrl(address);
var bytes = doc.Save();
MemoryStream mstream = new MemoryStream(bytes);
doc.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=kundenvereinbarung.pdf");
Response.Buffer = true;
mstream.WriteTo(Response.OutputStream);
Response.End();
return null;
}
}

PDFSharp download file thru filestream

I am new to this library but I couldn't find anything about downloading to the filestream with this library, I could only find a document.Save(filepath) option which is not always allowed.
I would like to create a filestream so the file gets downloaded to the directed Downloads folder.
Could someone point me in the right direct?
There is a Save overload that takes a MemoryStream object instead of path to a file.
The PDFSharp website has an example showing how to do this:
private void Page_Load(object sender, System.EventArgs e)
{
// Create new PDF document
PdfDocument document = new PdfDocument();
this.time = document.Info.CreationDate;
document.Info.Title = "PDFsharp Clock Demo";
document.Info.Author = "Stefan Lange";
document.Info.Subject = "Server time: " +
this.time.ToString("F", CultureInfo.InvariantCulture);
// Create new page
PdfPage page = document.AddPage();
page.Width = XUnit.FromMillimeter(200);
page.Height = XUnit.FromMillimeter(200);
// Create graphics object and draw clock
XGraphics gfx = XGraphics.FromPdfPage(page);
RenderClock(gfx);
// Send PDF to browser
MemoryStream stream = new MemoryStream();
document.Save(stream, false);
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", stream.Length.ToString());
Response.BinaryWrite(stream.ToArray());
Response.Flush();
stream.Close();
Response.End();
}

can eml directly open with outlook, instead eml file will download then click it to open in outlook?

I have an asp.net MVC application, below code works file.
But the code is that, When navigate to Email action in browser, an EML file is download, then when we click on that file, the file will open with outlook.
Can it be possible, when action calls, then EML file will directly open with outlook, instead of download and then click to open??
Code
public async Task<FileStreamResult> Email()
{
string dummyEmail = "test#localhost.com";
var mailMessage = new MailMessage();
mailMessage.From = new MailAddress(dummyEmail);
mailMessage.To.Add("dejan.caric#gmail.com");
mailMessage.Subject = "Test subject";
mailMessage.Body = "Test body";
// mark as draft
mailMessage.Headers.Add("X-Unsent", "1");
// download image and save it as attachment
using (var httpClient = new HttpClient())
{
var imageStream = await httpClient.GetStreamAsync(new Uri("http://dcaric.com/favicon.ico"));
mailMessage.Attachments.Add(new Attachment(imageStream, "favicon.ico"));
}
var stream = new MemoryStream();
ToEmlStream(mailMessage, stream, dummyEmail);
stream.Position = 0;
return File(stream, "message/rfc822", "test_email.eml");
}
private void ToEmlStream(MailMessage msg, Stream str, string dummyEmail)
{
using (var client = new SmtpClient())
{
var id = Guid.NewGuid();
var tempFolder = Path.Combine(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name);
tempFolder = Path.Combine(tempFolder, "MailMessageToEMLTemp");
// create a temp folder to hold just this .eml file so that we can find it easily.
tempFolder = Path.Combine(tempFolder, id.ToString());
if (!Directory.Exists(tempFolder))
{
Directory.CreateDirectory(tempFolder);
}
client.UseDefaultCredentials = true;
client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
client.PickupDirectoryLocation = tempFolder;
client.Send(msg);
// tempFolder should contain 1 eml file
var filePath = Directory.GetFiles(tempFolder).Single();
// create new file and remove all lines that start with 'X-Sender:' or 'From:'
string newFile = Path.Combine(tempFolder, "modified.eml");
using (var sr = new StreamReader(filePath))
{
using (var sw = new StreamWriter(newFile))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (!line.StartsWith("X-Sender:") &&
!line.StartsWith("From:") &&
// dummy email which is used if receiver address is empty
!line.StartsWith("X-Receiver: " + dummyEmail) &&
// dummy email which is used if receiver address is empty
!line.StartsWith("To: " + dummyEmail))
{
sw.WriteLine(line);
}
}
}
}
// stream out the contents
using (var fs = new FileStream(newFile, FileMode.Open))
{
fs.CopyTo(str);
}
}
}
With Chrome you can make it automatically open certain files, once they are downloaded.
.EML should attempt to open in Outlook.
I am not sure about other browsers, but Chrome seemed to be the only one with this option.
It's not a pefect solution because if someone downloaded an .EML from another website in Chrome, it will open automatically aswell.
I recommend having Chrome dedicated to your Web application.
You sure can open local .eml file with Outlook.
But in context of web application, you must firstly download it.

How to make the .xlsx file download

The below is used to create the .xls file and download the file.
I want to download it to .xlsx file. If i simply change the extension into ".xlsx", the report directly opens in the browser. I want it to open in .xlsx extension. Kindly help me.
Below is the code reference for you,
//setting the application path to a variable
strPath = Server.MapPath("ExcelFiles");
//Creating a file name
strExportPath = "Card" + intRnd.ToString() + intRnd1.ToString() + ".xls";
hidFilePath.Value = "ExcelFiles/" + strExportPath;
//Creating the full path with the filename
strExcelPath = strPath + "\\" + strExportPath;
Session["AK_SC_CRD_EXCEL_PATH"] = strExcelPath;
StreamWriter objStreamWriter = new StreamWriter(strExcelPath, true);
//Write the XL Contents to a stream writer.
objStreamWriter.WriteLine(strXLContents);
objStreamWriter.Close();
objStreamWriter = null;
Thanks.
You may need to add a MIMETYPE for xslx to your response.
.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Similar to below;
Response.ContentType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Adding Following code will force your file download instead of opening in the browser.
Response.AddHeader("content-disposition", "attachment;filename=yourfilename.xlsx");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
/*Add your code here to write file to response stream*/
Response.End();
Use following code to download Excel:-
HttpContext context = HttpContext.Current;
FileStream fs = null;
BinaryReader br = null;
byte[] data = null;
try
{
if (File.Exists(filePath))
{
FileInfo file = new FileInfo(filePath);
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
br = new BinaryReader(fs, System.Text.Encoding.Default);
data = new byte[Convert.ToInt32(fs.Length)];
br.Read(data, 0, data.Length);
context.Response.Clear();
context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
context.Response.AddHeader("content-disposition", "attachment; filename=" + file.FullName);
context.Response.AddHeader("Content-Length", file.Length.ToString());
context.Response.BinaryWrite(data);
context.Response.Flush();
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}

Download functionality MVC 4

I have created a web api which connects users to dropbox via OAuth. I am using an API to interact with Dropbox, which works locally as I would like, however when I deploy the API to my Azure server, I am unable to download. I had anticipated this would happen, as my API is currently hard codded to a path on my machine.
Here is the method I am using:
NOTE: I call this method through an ActionResult, as part of the MVC portion of my project
public FileSystemInfo DownloadFile(string root, string path)
{
var uri = new Uri(new Uri(DropboxRestApi.ApiContentServer),
String.Format("files?root={0}&path={1}",
root, UpperCaseUrlEncode(path)));
var oauth = new OAuth();
var requestUri = oauth.SignRequest(uri, _consumerKey, _consumerSecret, _accessToken);
var request = (HttpWebRequest) WebRequest.Create(requestUri);
request.Method = WebRequestMethods.Http.Get;
var response = request.GetResponse();
var metadata = response.Headers["x-dropbox-metadata"];
var file = ParseJson<FileSystemInfo>(metadata);
using (Stream responseStream = response.GetResponseStream())
using (MemoryStream memoryStream = new MemoryStream())
{
byte[] buffer = new byte[1024];
int bytesRead;
do
{
bytesRead = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, bytesRead);
} while (bytesRead > 0);
file.Data = memoryStream.ToArray();
}
return file;
}
This is where I call the method in my action result.
var file = api.DownloadFile("dropbox", "Public/downloadThis.jpg");
path = file.Path;
file.Save(#"....\Desktop\DemoTest\Downloads\downloadThis.jpg"); --- this is the problem & *Save* is a stream writer
Is there a procedure to follow when downloading files from a server on a browser?
public ActionResult download(Models.downloadModel dowld, Models.LoggerView log)
{
string TC_ID = Request.QueryString["id"].ToString();
string filename = TC_ID+"_LoggerData" + ".zip";
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "attachment;filename=" + filename);
Response.TransmitFile(Server.MapPath("~/files/" + filename));
Response.End();
}

Resources