I've got a server method that takes and codifies a list of strings, since IE9 doesn't read json format, what I want is to set the string in the content of an http response message. I seems to do it well but when I get the response I can's find the response on the body, what I can see is only the length of what I set in the response message.
here is the code:
public HttpResponseMessage Upload()
{
HttpResponseMessage m = new HttpResponseMessage(HttpStatusCode.OK);
List<string> returnlist = new List<string>();
for (int i = 0; i < Request.Files.Count; i++)
{
//string treatment
}
HttpResponseMessage response = new HttpResponseMessage();
response.Content = new StringContent(string.Join(",", returnlist));
return response;
}
this is what the string contains "file1,file2,file3"
but I can't find it debugging in visual studio or firebug
The response that I get is:
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
Content-Type: text/plain; charset=utf-8
}
How can I set and then get the response message?
In case of need the js here is it:
self.uploadfiles = function () {
//startSpinner();
if (!self.isOldIE()) {
var loc = window.location;
base_url = loc.protocol + "//" + loc.host;
baseUrl = base_url + "/";
var save = true;
var xhr = new XMLHttpRequest();
xhr.open('POST', baseUrl + 'Home/Upload');
xhr.send(formdata);
xhr.onreadystatechange = function (data) {
//The responseText is the same as above
if (xhr.responseText.length > 0) {
//do stuff
}
};
Try this code
var response = Request.CreateResponse(HttpStatusCode.OK, string.Join(",", returnlist));
return response;
Try this to get the response using Javascript:
var xhr = new XMLHttpRequest();
xhr.open('POST', baseUrl + 'Home/Upload', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
alert(xhr.responseText);
} else {
// do something about the error
}
};
xhr.send(formdata);
Note the third boolean parameter of the open() method for getting asynchronously.
For some reason the browsers doesn't show the entire body of the http response. So my solution was to write the header of the response and get the header from js.
Maybe somebody knows why the browsers doesn't show the body, or has a better solution.
This is my controller:
public HttpResponseMessage Upload()
{
HttpResponseMessage m = new HttpResponseMessage(HttpStatusCode.OK);
List<string> returnlist = new List<string>();
for (int i = 0; i < Request.Files.Count; i++)
{
HttpPostedFileBase file = Request.Files[i]; //Uploaded file
//Use the following properties to get file's name, size and MIMEType
int fileSize = file.ContentLength;
if (file.FileName != "")
{
string fileName = string.Format("{0}.{1}", Guid.NewGuid().ToString(), file.FileName.ToString().Split('.')[1].ToString());
returnlist.Add(fileName);
}
}
//Here I write the response message headers
HttpResponseMessage response = new HttpResponseMessage();
response.Content = new StringContent(string.Join(",", returnlist), Encoding.UTF8, "text/html");
response.Headers.Add("data", string.Join(",", returnlist));
return response;
}
And here is how I get the header response:
var xhr = new XMLHttpRequest();
xhr.open('POST', baseUrl + 'Home/Upload');
xhr.send(formdata);
xhr.onreadystatechange = function (data) {
if (xhr.responseText.length > 0) {
//header response
var response = xhr.responseText;
}
Related
I am having problem with .stl file download in c# Angular JS MVC.
While the file is downloading I am not able to open the file in 3d shape or another software supporting stl file extension.
vm.FileDownload = function (id, hash,filename) {
var defer = $q.defer();
threeShapeRepo.getFile(id, hash, filename).then(function (data) {
if (data !== null) {
var file = new Blob([data], {
type: 'application/stl'
});
var fileURL = URL.createObjectURL(file);
var link = document.createElement('a');
link.href = fileURL;
link.target = '_blank';
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
//window.URL.revokeObjectURL(url);
defer.resolve(data);
});
}
From repository.js
function getFile(id, hash, fileName) {
var params = {
'Id': id,
'Hash': hash,
'FileName': fileName
}
var url = 'https://' + window.location.host + '/api/' + 'ThreeShape' + '/' + 'getFileAsync';
return $http.post(url, params, { responseType: 'blob' }).then(function (data) {
if (data.data.Content.indexOf("validation failed")!==-1) {
logError(data.data.Content);
return null;
}
return data.data;
});
}
In c# back end code:
public async Task<string> getFileAsyncInternal(GetFile request)
{
var response = new GetThreeShapeCasesResponse();
IList<GetOneThreeShapeCaseResult> tempCaseList = new List<GetOneThreeShapeCaseResult>();
IRestResponse restResponse;
var retryCount = 0;
HttpStatusCode statusCode;
int numericStatusCode;
var requestUrl = "";
InitializeThreeShapeClient();
var restRequest = new RestRequest(Method.GET);
if (request.Hash != null)
{
requestUrl = threeShapeServerLocation + "api/cases/"+ request.Id+"/attachments/"+ request.Hash;
}
ThreeShapeAPIClient.BaseUrl = new Uri(requestUrl);
var getTokenOperation = await retreive3ShapeBearerTokenInternal();
var myToken = getTokenOperation.TokenValue;
var tokenString = "Bearer " + myToken;
restRequest.AddHeader("Authorization", tokenString);
restResponse = ThreeShapeAPIClient.Execute(restRequest);
numericStatusCode = (int)restResponse.StatusCode;
System.Web.HttpResponse httpresponse = System.Web.HttpContext.Current.Response; ;
if (numericStatusCode == 200)
{
var strResult = restResponse.Content;
//return strResult;
string fileName = request.FileName;
httpresponse.ClearContent();
httpresponse.Clear();
byte[] buffer = new byte[restResponse.Content.Length];
System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
{
FileName = fileName,
Inline = true // false = prompt the user for downloading; true = browser to try to show the file inline
};
httpresponse.Headers.Add("Content-Disposition", "attachment;filename="+request.FileName+ ";filename*=UTF-8''" + request.FileName);
httpresponse.Headers.Add("Content-Length",Convert.ToString(restResponse.Content.Length));
httpresponse.Headers.Add("Contenty-Type", ((RestSharp.RestResponseBase)restResponse).ContentType);
httpresponse.Output.Write(restResponse.Content);
return restResponse.Content;
}
else if (retryCount == 0 && numericStatusCode == 401)
{
response.DidError = true;
response.ErrorMessage = restResponse.Content;
}
return restResponse.Content;
}
I have been struggling to make the downloaded file open. Any kind of help is deeply appreciated.
Response i am getting in content object is
I would start by comparing file contents of a clean copy and corrupt downloaded copy for clues. Is the downloaded copy really corrupt or is it actually empty? Do you see a pattern in the corrupt copies? etc Goodluck!
I'm trying to communicate with some server but the Authorization header gets removed when I use a GET request.
My code (please excuse the mess):
public ApiResponse MakeApiRequest(string path, string body, Dictionary<string, string> header,
Dictionary<string, string> query, string method)
{
var queryBuilder = new StringBuilder("?");
foreach (var queryPair in query)
{
queryBuilder.Append(queryPair.Key + "=" + queryPair.Value + "&");
}
var queryString = queryBuilder.ToString();
queryString = queryString.Substring(0, queryString.Length - 1);
var request = (HttpWebRequest) WebRequest.Create(new Uri(ApiServer + path + queryString));
request.Timeout = 5000;
request.UserAgent = "VSpedSync/DevBuild";
request.Method = method;
foreach (var headerPair in header)
{
if (headerPair.Key.ToLower().Equals("user-agent")) continue;
if (headerPair.Key.ToLower().Equals("authorization"))
{
request.PreAuthenticate = true;
}
request.Headers.Add(headerPair.Key, headerPair.Value);
}
Debug.WriteLine("preauth "+request.PreAuthenticate);
if (!body.Equals(""))
{
var stream = request.GetRequestStream();
var streamWriter = new StreamWriter(stream);
streamWriter.Write(body);
streamWriter.Close();
}
HttpWebResponse response;
try
{
response = (HttpWebResponse) request.GetResponse();
}
catch (WebException ex)
{
response = (ex.Response as HttpWebResponse);
if (response == null)
throw;
}
foreach (string requestHeader in request.Headers)
{
Debug.WriteLine(" --> "+requestHeader+": "+request.Headers.Get(requestHeader));
}
var statusCode = response.StatusCode;
var responseHeaders = new Dictionary<string, string>();
foreach (string headerKey in response.Headers)
{
var headerVal = response.Headers.Get(headerKey);
responseHeaders.Add(headerKey, headerVal);
}
var responseBody = "NONE";
try
{
var streamReader = new StreamReader(response.GetResponseStream());
responseBody = streamReader.ReadToEnd();
}
catch (Exception)
{
responseBody = "ERROR";
// ignored
}
return new ApiResponse(
statusCode,
responseBody,
!responseBody.Equals("ERROR") && !responseBody.Equals("NONE"),
responseHeaders
);
}
This is how I call the method:
var apiResponse = api.MakeApiRequest("auth/check/", "", new Dictionary<string, string>()
{
{"Authorization", "Bearer " + token.token},
{"test", "f"}
}, new Dictionary<string, string>(), "GET");
The headers that are sent when I use the GET method:
--> User-Agent: VSpedSync/DevBuild
--> test: f
--> Host: localhost:55445
The headers that are sent when I use the POST method:
--> User-Agent: VSpedSync/DevBuild
--> Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
--> test: f
--> Host: localhost:55445
Am I doing something wrong?
Edit: Seems to be solved. I'm using RestSharp now instead of the normal WebRequest.
You can try to use the HttpClient instead of the WebRequest. I tried the following and the authorization header stayed in the request after sending it.
const string ApiServer = "https://google.com";
static readonly HttpClient _httpClient = new HttpClient();
static async Task Main()
{
InitializeClient();
var headers = new Dictionary<string, string>()
{
{ "Authorization", "Bearer e45jsh56" },
{ "Test", "test_value" }
};
var paramterers = new Dictionary<string, string>()
{
{ "pageNum", "3" },
{ "pageSize", "100" }
};
var response = await MakeApiCallAsync("mypath", "request_body", headers, paramterers, "GET");
Console.WriteLine($"Status Code: {response.StatusCode}.");
}
static void InitializeClient()
{
// Set the base URI
_httpClient.BaseAddress = new Uri(ApiServer);
// Set Timeout to 5 seconds
_httpClient.Timeout = new TimeSpan(hours: 0, minutes: 0, seconds: 5);
// Set the default User Agent
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("VSpedSync/DevBuild");
}
static async Task<ApiResponse> MakeApiCallAsync(string path,
string body, Dictionary<string, string> headers,
Dictionary<string, string> query, string method)
{
// Generate query string
string queryString = '?' +
string.Join(separator: '&', values: query.Select(q => $"{q.Key}={q.Value}"));
// Create the relative URL
string relativeUrl = path + queryString;
// Create the Http Method object
HttpMethod httpMethod = new HttpMethod(method);
// Create the request object
HttpRequestMessage request = new HttpRequestMessage(httpMethod, relativeUrl);
// Set headers to the request
foreach (KeyValuePair<string, string> h in headers)
{
if (!h.Key.Equals("UserAgent", StringComparison.OrdinalIgnoreCase))
{
request.Headers.Add(h.Key, h.Value);
}
}
// Set the content of the request
if (!string.IsNullOrEmpty(body))
{
request.Content = new StringContent(body);
}
// Send the request
HttpResponseMessage response = await _httpClient.SendAsync(request);
// Display request headers
foreach(var h in request.Headers)
{
Console.WriteLine($" --> {h.Key}: {string.Join(';', h.Value)}.");
}
// Process the response body
string responseBody = "NONE";
try
{
// Read the content as a string
responseBody = await response.Content.ReadAsStringAsync();
}
catch
{
responseBody = "ERROR";
}
// Return the api response
return new ApiResponse
{
StatusCode = response.StatusCode,
ResponseBody = responseBody,
ValidResponse = !responseBody.Equals("NONE") && !responseBody.Equals("ERROR"),
ResponseHeaders = response.Headers.ToDictionary(h => h.Key, h => string.Join(';', h.Value)),
};
}
Output
--> Authorization: Bearer e45jsh56.
--> Test: test_value.
--> User-Agent: VSpedSync/DevBuild.
Status Code: BadRequest.
Maybe try to use the WebHeaderCollection.Add(HttpRequestHeader, String) overload method.
public static ApiResponse MakeApiRequest(string path, string body, Dictionary<string, string> headers,
Dictionary<string, string> query, string method)
{
// Generate the query string
string queryString = '?' +
string.Join(separator: '&', values: query.Select(q => $"{q.Key}={q.Value}"));
// Create request obejct
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(ApiServer + path + queryString));
request.Timeout = 5000;
request.UserAgent = "VSpedSync/DevBuild";
request.Method = method;
// Set headers to the request
foreach (KeyValuePair<string, string> h in headers)
{
if (h.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase))
{
request.Headers.Add(HttpRequestHeader.Authorization, h.Value);
}
else if (!h.Key.Equals("UserAgent", StringComparison.OrdinalIgnoreCase))
{
request.Headers.Add(h.Key, h.Value);
}
}
foreach (string requestHeader in request.Headers)
{
Debug.WriteLine(" --> " + requestHeader + ": " + request.Headers.Get(requestHeader));
}
// ...
// .... Continue ....
// ...
return null;
}
Lately i have been trying to post a file from .net controller through .net controller using HttpClient,
to a Java Rest Service and failed many times as i was unable to send the file in the correct format.
below ajax call in the working jQuery way to invoke the service and pass the file with meta data key.
function Upload() {
var data = new FormData();
data.append('file', document.getElementById("file").files[0])
var metaData = [{"symbolicName": "DocumentTitle","dataType": "string","value": "Test CSEPF Document"}]
data.append('metaData', JSON.stringify(metaData));
$.ajax({
url: 'http://xxx:xx/FileNetCoreRestServices/AddDocument',
type: "POST",
dataType: 'json',
data: data,
contentType: false,
processData: false,
success: function (data) {
debugger
}
});
}
Request payload when posted with ajax
------WebKitFormBoundaryaCyKxSim0zzwhHK7
Content-Disposition: form-data; name="file"; filename="4.pdf"
Content-Type: application/pdf
------WebKitFormBoundaryaCyKxSim0zzwhHK7
Content-Disposition: form-data; name="metaData"
[{"symbolicName":"DocumentTitle","dataType":"string","value":"Test CSEPF Document"}]
------WebKitFormBoundaryaCyKxSim0zzwhHK7--
Now i want the same thing to be replicated in the .net controller side,
As per my research i know that i need to use MultipartFormDataContent and HttpClient in order to get this working.
below is the .net code i have written in order to upload the file to the service.
List<string> lstFilesToBeUploaded = null;
try
{
string FileTransferApiUrl = "http://xxx:xx/FileNetCoreRestServices/AddDocument";
lstFilesToBeUploaded = new List<string>();
string OperatorSourceRootFolderPath = Server.MapPath(System.Configuration.ConfigurationSettings.AppSettings["UploadLocation"]);
if (Directory.Exists(OperatorSourceRootFolderPath))
{
lstFilesToBeUploaded = Directory.GetFiles(OperatorSourceRootFolderPath).ToList();
}
foreach (string filePart in lstFilesToBeUploaded) // improvement - this is sequential, can be made threaded
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("metaData", "[{'symbolicName':'DocumentTitle','dataType':'string','value':'Test CSEPF Document'}]");
using (var content = new MultipartFormDataContent())
{
byte[] Bytes = System.IO.File.ReadAllBytes(filePart);
var fileContent = new StreamContent(new MemoryStream(Bytes));
fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = Path.GetFileName(filePart) };
content.Add(fileContent);
var response = client.PostAsync(FileTransferApiUrl, fileContent).Result;
if (response.IsSuccessStatusCode)
{
var responseData = response.Content.ReadAsStringAsync().Result;
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
When i run this code i get the response as
{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Access-Control-Allow-Origin: * $WSEP: Transfer-Encoding: chunked Connection: Close Date: Wed, 27 Jun 2018 11:41:39 GMT Server: WebSphere Server: Application Server: Server/7.0 Content-Language: en-US Content-Type: text/html; charset=ISO-8859-1 }}
I am not entirely sure how the MultipartFormDataContent works, it would be helpful if any one points out where i am going wrong.
After so many failed attempts and research i was able to call the service with the file, and below is the working code which i used in order to achieve this.
#region FILENET Upload
string FileLocation = Server.MapPath(System.Configuration.ConfigurationSettings.AppSettings["FileLocation"]);
var FileNetRestServiceURL = "http://xxx:xx/FileNetCoreRestServices/AddDocument";
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
//Working - Default Values
//var values = new[]
//{new KeyValuePair<string, string>("metaData", "[{'symbolicName':'DocumentTitle','dataType':'string','value':'Test CSEPF Document'}]")};
//Real Values
var values = new[]
{new KeyValuePair<string, string>("metaData", "[{'symbolicName':'"+Path.GetFileNameWithoutExtension(FileLocation).ToString()+"','dataType':'string','value':'"+Path.GetFileNameWithoutExtension(FileLocation).ToString()+"'}]")};
//Convert the file into ByteArrayContent as the service is expecting a file object
content.Add(new ByteArrayContent(System.IO.File.ReadAllBytes(FileLocation)), "file", Path.GetFileName(FileLocation).ToString());
foreach (var keyValuePair in values)
{
content.Add(new StringContent(keyValuePair.Value), keyValuePair.Key);
}
var response = client.PostAsync(FileNetRestServiceURL, content).Result;
if (response.IsSuccessStatusCode)
{
var responseData = response.Content.ReadAsStringAsync().Result;
}
}
}
#endregion
try something like:
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
var values = new[]
{
new KeyValuePair<string, string>("metaData", JsonConvert.SerializeObject("[{'symbolicName':'DocumentTitle','dataType':'string','value':'Test CSEPF Document'}]"))
};
foreach (var keyValuePair in values)
{
content.Add(new StringContent(keyValuePair.Value), keyValuePair.Key);
}
var fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(filePart));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Foo.txt"
};
content.Add(fileContent);
var requestUri = "http://xxxx:xxxx/CSEPFCoreRestServices/addDocument";
var result = client.PostAsync(requestUri, content).Result;
}
}
Having trouble getting my from data out of Request in C#. What I have is angular $http posting to a proxy api. Problem is that Request.Form is empty; same goes for Request.InputStream.
Angular:
$http({
method: "POST",
url: '/apiproxy/projects/' + data.Project.Id + '/recruiting-groups',
data: angular.toJson(group, false)
});
C#:
public ActionResult Index(string pathInfo)
{
var url = Settings.GetValue<string>("QualService") + "/" + pathInfo + "?" + Request.QueryString;
//Get stuff from the back end
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
client.Headers[HttpRequestHeader.Cookie] = Request.Headers["Cookie"];
client.Headers[HttpRequestHeader.Authorization] = "Basic " +
Convert.ToBase64String(
Encoding.UTF8.GetBytes(
"x:{0}".Fmt(UserSession.ApiKey)));
try
{
var responseBytes = Request.HttpMethod == "POST" ? client.UploadValues(url, Request.Form) : client.DownloadData(url);
var result = new ContentResult();
result.Content = Encoding.UTF8.GetString(responseBytes);
result.ContentEncoding = Encoding.UTF8;
result.ContentType = "application/json";
return result;
}
catch(Exception e)
{
Logger.Error("Error while proxying to the API: ", e);
}
}
return Json(false);
}
When I look at network tab in chrome I can see the data being passed:
No matter what though Request.Form is null. And for that matter Request.InputStream is empty. What is going on?
You might want to try adding one of the following header types:
application/x-www-form-urlencoded
multipart/form-data
I'm trying to send a 9MB .xls file as a response from web api controller method. The user will click a button on the page and this will trigger the download via the browser.
Here's what I've got so far but it doesn't work however it doesn't throw any exceptions either.
[AcceptVerbs("GET")]
public HttpResponseMessage ExportXls()
{
try
{
byte[] excelData = m_toolsService.ExportToExcelFile();
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new MemoryStream(excelData);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Data.xls"
};
return result;
}
catch (Exception ex)
{
m_logger.ErrorException("Exception exporting as excel file: ", ex);
return Request.CreateResponse(HttpStatusCode.InternalServerError);
}
}
Here is the coffeescript/javascript jquery ajax call from a button click in the interface.
$.ajax(
url: route
dataType: 'json'
type: 'GET'
success: successCallback
error: errorCallback
)
Now that I think about it perhaps the dataType is wrong and shouldn't be json...
Works also as a HTTP GET method, but don't use $ajax, instead use
window.open(url);
C# code:
[HttpGet]
[Route("report/{scheduleId:int}")]
public HttpResponseMessage DownloadReport(int scheduleId)
{
var reportStream = GenerateExcelReport(scheduleId);
var result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(reportStream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Schedule Report.xlsx"
};
return result;
}
JS code:
downloadScheduleReport: function (scheduleId) {
var url = baseUrl + 'api/Tracker/report/' + scheduleId;
window.open(url);
}
I had to make a couple of small changes to get this to work
First: Change the method to a post
[AcceptVerbs("POST")]
Second: Change from using the jQuery ajax lib to use a hidden form, here's my service function for doing the hidden form and submitting it.
exportExcel: (successCallback) =>
if $('#hidden-excel-form').length < 1
$('<form>').attr(
method: 'POST',
id: 'hidden-excel-form',
action: 'api/tools/exportXls'
).appendTo('body');
$('#hidden-excel-form').bind("submit", successCallback)
$('#hidden-excel-form').submit()
Hopefully there's a better way to do this but for the time being it's working and downloading the excel file nicely.
I experienced the same problem.
Problem solved with the following:
window.open(url)
It will store the excel file created in a folder in the system and once its sent to Browser, it will be deleted .
//path to store Excel file temporarily
string tempPathExcelFile = AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.Hour + DateTime.Now.Minute +
DateTime.Now.Second + DateTime.Now.Millisecond +
"_temp";
try
{
//Get Excel using Microsoft.Office.Interop.Excel;
Excel.Workbook workbook = ExportDataSetToExcel();
workbook.SaveAs(tempPathExcelFile, workbook.FileFormat);
tempPathExcelFile = workbook.FullName;
workbook.Close();
byte[] fileBook = File.ReadAllBytes(tempPathExcelFile);
MemoryStream stream = new MemoryStream();
string excelBase64String = Convert.ToBase64String(fileBook);
StreamWriter excelWriter = new StreamWriter(stream);
excelWriter.Write(excelBase64String);
excelWriter.Flush();
stream.Position = 0;
HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
httpResponseMessage.Content = new StreamContent(stream);
httpResponseMessage.Content.Headers.Add("x-filename", "ExcelReport.xlsx");
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel");
httpResponseMessage.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment");
httpResponseMessage.Content.Headers.ContentDisposition.FileName = "ExcelReport.xlsx";
httpResponseMessage.StatusCode = HttpStatusCode.OK;
return httpResponseMessage;
}
catch (Exception ex)
{
_logger.ErrorException(errorMessage, ex);
return ReturnError(ErrorType.Error, errorMessage);
}
finally
{
if (File.Exists(tempPathExcelFile))
{
File.Delete(tempPathExcelFile);
}
}
//Javascript Code
$.ajax({
url: "/api/exportReport",
type: 'GET',
headers: {
Accept: "application/vnd.ms-excel; base64",
},
success: function (data) {
var uri = 'data:application/vnd.ms-excel;base64,' + data;
var link = document.createElement("a");
link.href = uri;
link.style = "visibility:hidden";
link.download = "ExcelReport.xlsx";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
error: function () {
console.log('error Occured while Downloading CSV file.');
},
});
In the end create an empty anchor tag at the end of your html file. <a></a>
For.NetCore you can simply Return type as File.
public IActionResult ExportAsExcel()
{
try
{
using (var ms = new MemoryStream())
{
var data = ExportData(); // Note: This Should be DataTable
data.ConvertAsStream(ms);
ms.Position = 0;
return File(ms.ToArray(), "application/octet-stream", "ExcelReport.xlsx");
}
}
catch (Exception e)
{
_logger.LogError(e.Message, e);
throw;
}
}
This will return a file when you click a particular button
public FileResult ExportXls(){
//the byte stream is the file you want to return
return File(bytes, "application/msexcel")
}