Unable send excel file data to web api - angularjs

In my angular app , I am trying to upload an excel file to web api from Angular JS but I am unable to do so .
The method in the server web api is not being hit.
The angular code looks like :
$scope.file = null;
//UPLOAD FILE CODE
var formdata;
$scope.getTheFiles = function ($files) {
console.log($files[0].type);
formdata = new FormData();
angular.forEach($files, function (value, key) {
formdata.append(key, value);
});
};
// NOW UPLOAD THE FILES.
$scope.uploadFiles = function () {
var request = {
method: 'POST',
url: BasePath + 'uploadNative/UploadFiles/',
data: formdata,
headers: {
'Content-Type': undefined
}
};
// SEND THE FILES.
console.log(formdata);
if (formdata != null || formdata != undefined) {
$http(request)
.success(function (response) {
if (response != "Failed!") {
console.log("Succeeds");
}
else {
console.log("Failed");
}
})
.error(function () {
});
}
And the UI MVC controller which should invoke the web api controller causes exception.
public async Task<JsonResult> UploadFiles()
{
System.Web.HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;
string url = BaseURL + "api/Upload/groupmembershipupload/";
string res = await Models.Resource.PostFileAsync(url, Token, hfc, ClientID);
var result = (new JavaScriptSerializer()).DeserializeObject(res);
return Json(result);
}
This PostFileAsync fires the exception.
using (client = new HttpClient())
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data"));
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + oauthToken);
client.DefaultRequestHeaders.Add("ClientID", ClientID);
var content = new MultipartFormDataContent();
System.Web.HttpPostedFile hpf = data[0];
byte[] fileData = null;
using (var sds = new BinaryReader(hpf.InputStream))
{
fileData = sds.ReadBytes(hpf.ContentLength);
}
content.Add(new ByteArrayContent(fileData, 0, fileData.Count()));
//using (response = await client.PostAsJsonAsync(url + "?=" + DateTime.Now.Ticks, data))
using (response = await client.PostAsync(url + "?=" + DateTime.Now.Ticks, content))
{
...the response is Http Error 415 "Unsupported Media Type". It does not call the service.

Change the headers to:
headers: {
'Content-Type': 'multipart/form-data'
}

Related

Angularjs Form data is not binding at server side during file uploade

When im tring to uploade my file into server im getting an Error as TypeError: $http(...).success is not a function(…)
Angular File change code
$scope.ChechFileValid = function (file) {
debugger;
var isValid = false;
if ($scope.SelectedFileForUpload != null) {
if ((file.type == 'image/png' || file.type == 'image/jpeg' || file.type == 'image/gif') && file.size <= (512 * 1024)) {
$scope.FileInvalidMessage = "";
isValid = true;
}
else {
$scope.FileInvalidMessage = "Selected file is Invalid. (only file type png, jpeg and gif and 512 kb size allowed)";
}
}
else {
$scope.FileInvalidMessage = "Image required!";
}
$scope.IsFileValid = isValid;
};
This is my file submit button Code
$scope.SaveFile = function () {
$scope.IsFormSubmitted = true;
$scope.Message = "";
$scope.ChechFileValid($scope.SelectedFileForUpload);
if ($scope.IsFormValid && $scope.IsFileValid) {
FileUploadService.UploadFile($scope.SelectedFileForUpload, $scope.FileDescription).then(function (d) {
alert(d.Message);
ClearForm();
}, function (e) {
alert(e);
});
}
else {
$scope.Message = "All the fields are required.";
}
};
This is my factory code
fac.UploadFile = function (file, description) {
var formData = new FormData();
formData.append("file", file);
formData.append("description", description);
var defer = $q.defer();
return $http({
url: 'http://localhost:59838/Api/Home/Sales',
data: JSON.stringify(formData),
headers: { 'content-type': 'application/json' },
transformRequest: angular.identity,
method: 'POST',
})
.success(function (d) {
defer.resolve(d);
})
Here im getting Error as angular.js:15018 Possibly unhandled rejection: {"data":{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:59838/Api/Home/Sales'.","Message
You are getting the $http(...).success is not a function(…)
because the ".success" method has since been deprecated, use ".then" instead. More info on the following link Check Deprecation notice
As for the second error, it could be the result of improper URI, maybe your route is expecting a query parameter, ie : http://localhost:59838/Api/Home/Sales?XXXX, check the full error for more infos
ie : (No HTTP resource was found that matches the request URI ..."
(parameter XXXX is mandatory))

asp.net 415 Unsupported Media Type with formData POST

Problem :
API controller cannot access HTTP request data which are included FormData object in HTTP request
I need to pass file object data appended in FormData Object in http Post request to asp.net api controller and front-end is angularjs.i can not retrieve http request data from api controller.my code is below. please look into this, it would be great :)
when i pass,
Content-type : undefined
the error says 415 Unsupported Media Type
if Content-type: multipart/form-data then cannot access data from API controller.
Front-end
$scope.submit = function (files) {
var formData = new FormData();
var getFormData = function(appendFiles){
if (appendFiles.length) {
angular.forEach(appendFiles,function(file){
if(!file.uploaded){
formData.append("imgFiles",file);
file.uploaded = true;
}
});
} else {
formData.append('imgFiles', files);
}
console.log(formData.values());
return formData;
}
$http({
url : "URL",
method: "POST",
data: getFormData(files),
headers: {
'Content-Type': undefined
},
transformRequest: angular.identity,
})
.then(
function (resp) {
// alert(JSON.stringify(resp));
console.log(resp)
},
function (resp) {
console.log(resp)
}
);
};
Api controller Method
[HttpPost]
[Route("route")]
public string UploadFiles(List<HttpPostedFileBase> files)
{
var filesToDelete = HttpContext.Current.Request.Files;
//i need to access file here.using param or otherway
return stat;
}
I have solved the problem.i have changed the api controller method as below,
[HttpPost]
[Route("route")]
public async Task<string> UploadFiles()
{
FileUploadService fileService = new FileUploadService();
if (!Request.Content.IsMimeMultipartContent())
{
this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
var uploadFolder = "upload folder physical path"
//this method is in below
var provider = GetMultipartProvider(uploadFolder);
await Request.Content.ReadAsMultipartAsync(provider);
foreach (MultipartFileData fileData in provider.FileData)
{
var physicalPath = fileData.LocalFileName;
var fileName = fileData.Headers.ContentDisposition.FileName;
}
return "return value";
}
private MultipartFormDataStreamProvider GetMultipartProvider(string uploadFolder)
{
try
{
var root = HttpContext.Current.Server.MapPath(uploadFolder);
if (!Directory.Exists(root))
{
Directory.CreateDirectory(root);
}
return new MultipartFormDataStreamProvider(root);
}
catch (Exception ex)
{
throw ex;
}
}

downloading text file in postman but not in browser using restapi in angularjs

$scope.newFile is my response from backend. Actually my response should be a text file, which is working in postman.But in browser , I am getting
Cannot GET
/Organizer/%7B%22data%22:%22id/tname/temail/tphone/twebsite/tvenue/ttags/n83/tAny%20Name/ta#b.com/t9009009009/thttp://www.anyname.com/tHall%20A/ttag1,%20tag2,%20tag3/nsunitha/tsunitha#gmail.com/t55555541/thttp://www.sunitha.com/nSuhasini/tsuha#gmail.com/t955555544/thttp://www.suha.com/nRaichel/traichel#gmail.com/t955548458/thttp://www.raichel.com/n%22,%22status%22:200,%22config%22:%7B%22method%22:%22GET%22,%22transformRequest%22:[null],%22transformResponse%22:[null],%22jsonpCallbackParam%22:%22callback%22,%22headers%22:%7B%22Authorization%22:%22Token%2013946cc6c575d61b042b01b6905f1d239b3d9b08%22,%22Accept%22:%22application/json,%20text/plain,%20*/*%22%7D,%22url%22:%22http://http://localhost/1290//entity/campaigns/download_exhibitors/%22%7D,%22statusText%22:%22OK%22,%22xhrStatus%22:%22complete%22%7D
Service.js
var url =' http://localhost/1290/';
function downloadExhibitor() {
var token = 129821sahh;
var auth = "Token" + ' ' + token;
var config = {
headers: {
'Content-Type': 'text/plain',
'Authorization': auth
}
}
return $http.get(url + 'entity/campaigns/download_exhibitors/', config)
.then(successHandler, errorHandler);
}
function successHandler(response){
/* we've got file's data from server */
return response.data;
}
function errorHandler(error){
/* we've got error response from server */
throw new Error('ERROR ' + error);
}
and eventually the service invocation
JS:
$scope.newFile = "";
service.downloadExhibitor()
.then(function(data){
$scope.newFile = data;
}, function(error){
console.log(error);
});
HTML:
<button class="btn" ng-click="downloadAllExhibitors();">
<a ng-href="{{newFile}}" target="_blank">Download</a></button>
You can try below code in controller...
var file = new Blob([data], {
type : 'text/plain'
});
if (navigator.userAgent.indexOf('MSIE') !== -1
|| navigator.appVersion.indexOf('Trident/') > 0) {
window.navigator.msSaveOrOpenBlob(file);
} else {
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
Following code in controller made my work simple , and it downloaded the file finally.
var file = new Blob([data], {
type: 'text/plain'
});
if (navigator.userAgent.indexOf('MSIE') !== -1 ||
navigator.appVersion.indexOf('Trident/') > 0) {
window.navigator.msSaveOrOpenBlob(file);
} else {
var a = window.document.createElement("a");
a.href = window.URL.createObjectURL(file, {
type: "text/plain"
});
a.download = "filename.csv";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}

Fill angular model from response

I am getting response like
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.ByteArrayContent, Headers:
{
x-filename: StatementofAccount.pdf
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=StatementofAccount.pdf
}
now i need to use "x-filename: StatementofAccount.pdf" but i am not able to fetch this.
I fill this response to my model like
$scope.dataDetail = response.data;
but when I tried to get
console.log($scope.dataDetail.StatusCode)
or
console.log($scope.dataDetail.Headers.x-filename)
but its showing undefined.
plz get me an idea where i am doing wrong or how to achieve this.
I tried from the following way..plz get me idea where i am wrong.....
c#
....
byte[] bytes = memoryStream.ToArray();
memoryStream.Close();
httpResponseMessage.Content = new ByteArrayContent(bytes.ToArray());
httpResponseMessage.Content.Headers.Add("x-filename", fileName);
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
httpResponseMessage.Content.Headers.ContentDisposition.FileName = fileName;
httpResponseMessage.StatusCode = HttpStatusCode.OK;
return httpResponseMessage;
in angularjs
$http({
method: 'post',
url: basePath + '/profile/downloadpdf_fromedit',
// data: JSON.stringify($scope.paginginfostmntaccnt),
responsetype: 'arraybuffer',
headers: {'content-type': 'application/pdf'},
// headers: { 'content-type': 'application/json' }
})
.then(function (response) {
// console.log(response.data);
$scope.dataDetail = response.data;
console.log($scope.dataDetail)
1. var file = new Blob([response.data], { type: 'application/pdf' });
saveAs(file, 'StatementofAccount.pdf');
//url-file:///C:/Users/tushar/Downloads/StatementofAccount.pdf
//failed to load pdf
2.var file = new Blob([response], { type: 'application/pdf' });
var fileurl = URL.createObjectURL(file);
window.open(fileurl);
//url- blob:http://localhost:16311/02f8d85e-74c0-4ccd-b937-22f02cc3866c
//failed to load pdf document
3.
.success(function (data, status, headers, config) {
// any required additional processing here
var results = [];
results.data = data;
results.headers = headers();
results.status = status;
results.config = config;
console.log(results)
$("#loading").hide();
headers = headers();
var filename = headers['x-filename'];
var contentType = headers['content-type'];
if (!filename) {
filename = headers["x-filename"] || 'statementAccount.pdf';
}
var linkElement = document.createElement('a');
try {
var blob = new Blob([data], { type: contentType });
var url = window.URL.createObjectURL(blob);
linkElement.setAttribute('href', url);
linkElement.setAttribute("download", filename);
var clickEvent = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false
});
linkElement.dispatchEvent(clickEvent);
$("#loading").hide();
console.log("filename" + filename);
} catch (ex) {
console.log("catch"+ex);
$("#loading").hide();
}
})
//url-file:///C:/Users/tushar/Downloads/statementAccount.pdf
//failed to load pdf document
To access the headers of the response you need to use response.headers instead of response.data the data portion contains body of the response.

Download PDF using Angular

I'm trying to download PDF from a WebApi using Angular but the file is only 15 bytes. If I log the data being received from the WebApi it's an arraybuffer with the expected size
The WebApi
[HttpGet]
public HttpResponseMessage MatchRegistrationReport(int matchId)
{
try
{
var gen = new MSReports.Components.MatchRegistration();
byte[] bytes = gen.GeneratePDF(matchId, 10);
var stream = new MemoryStream(bytes);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(stream)
//Content = new ByteArrayContent(bytes)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = gen.ReportName + ".pdf"
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return result;
}
catch (Exception ex)
{
Log.Error(ex.Message);
return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message);
}
}
The Angular controller
$scope.Print = function () {
$scope.message = "Downloading";
reportResource.printMatchRegistration($scope.match.Id).then(function (data, status, headers, config) {
var file = new Blob([data], {
type: 'application/csv'
});
//trick to download store a file having its URL
var fileURL = URL.createObjectURL(file);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = 'MatchRegistration.pdf';
document.body.appendChild(a);
a.click();
//$scope.message = "Completed";
}, function (data, status, headers, config) {
$scope.message = "A error occurred";
});
}
and the resource
printMatchRegistration: function (matchId) {
return $http({
method: 'get',
url: this.getApiPath() + "MatchRegistrationReport?matchId=" + matchId,
headers: {
'Content-type': 'application/pdf',
},
responseType: 'arraybuffer'
});
I believe it has something to do with the content-type but can' figure out what.
Hi just found the answer
Change to this
reportResource.printMatchRegistration($scope.match.Id).then(function (response) {
var file = new Blob([response.data], {
type: 'application/pdf'
});
and this
printMatchRegistration: function (matchId) {
var data = { 'matchId': matchId };
return $http({
method: 'get',
url: this.getApiPath() + "MatchRegistrationReport",
params: data,
headers: {
'Content-type': 'application/pdf',
},
responseType: 'arraybuffer'
});
},

Resources