My AngularJS application is interacting with ASP.NET Web API to full fill the request which is working fine. it has an use case that allows user to download user specific secure PDF document. I have implemented this functionality as below
AngularJS:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
$scope.DownloadHandler = function (id, downloadURL) {
FileStreamManager.getPdf(id, downloadURL)
.then(function (result) {
// success
window.open(downloadURL + id, '_self', '');
},
function (result) {
$scope.errors = result.data;
});
};
Note : downloadURL is the Controller call like \ImageRepo\Get
Web Api Controller I have this implementation:
HttpResponseMessage response = new HttpResponseMessage();
// DB call to to build the URL
string fileName = "myLocation\Image\doc.pdf";
if (!fileProvider.Exists(fileName))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
FileStream fileStream = fileProvider.Open(fileName);
response.Content = new StreamContent(fileStream);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = fileName;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentLength = fileProvider.GetLength(fileName);
return response;
Which is working fine. Due to the security issue, i was asked to implement this by using HttpHanlder which is pretty new to me. I have some question on the same.
Should my AngularJS ng-click calls to my .ashx handler directly instead of a Controller URL? Or Should this call route through Controller? How?
I have DB calls to build the image URL and update some the status. Can this be done in Handler itself?
How would i make sure my documents are secured while downloading?
Please help.
Related
I am currently trying to create a remote method in loopback that will query a firebase database using the Firebase Admin SDK in NodeJS.
It works, but the issue I am having is that I am unable to make it realtime. It keeps crashing with an error pointing to the callback function being called more than once.
Here is a snippet of the code for my remote method:
'use strict';
module.exports = function(Scusers) {
var admin = require("firebase-admin");
Scusers.listItems = function(cb) {
// Get a database reference
var db = admin.database();
var ref = db.ref("users");
// Attach an asynchronous callback to read the data at our posts reference
var items = [];
// return list of users ordered by key and push each object into an array
ref.orderByKey().on("value", function(snapshot) {
snapshot.forEach(function(data) {
items.push(data.val());
});
// return array
cb(null, items);
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
};
}
If I change this line:
ref.orderByKey().on
for:
ref.orderByKey().once
It works, but on my front-end which is coded in AngularJS, it won't see the changes unless I manually call a refresh.
What should be the best approach to this? Sorry if it is unclear or my approach is wrong, I am so new at this. Thanks!
I am new to Angular, and trying to figure out how the best way to do this is. In my Django view, I authenticate a user, storing that user in request.user. Is there a way to retrieve that request.user in an Angular module. Can I retrieve it through Angular's $http service ? Looked around, but couldn't find a solution to this...yet, and thought I would try good ole Stack Overflow.
function bindPusher() {
var defer = $q.defer();
var channelName = 'private-account-' + Session.account.id;
var channel = $pusher.client.subscribe(channelName);
channel.bind('pusher:subscription_succeeded', function (data) {
$log.debug('Pusher subscribed: ' + channel.name);
PushListener.bindAndListen(channel);
defer.resolve(data);
});
channel.bind('pusher:subscription_error', function (status) {
if (status === 403) {
var msg = 'Pusher channel not authorized.';
$log.warn(msg);
defer.reject(msg);
}
});
return defer.promise;
}
Angular runs in the browser, Django runs on the server. Use a JSON string to send the data of Django's request.user to the browser, where Angular can unwrap that JSON string into a Javascript object.
So, you are correct, $http.get('/path/my-user.json') could read the request.user's data.
$http.get('/path/my-user.json').then(function (response) {
$scope.user = response.data.user;
}, function (reject) {
// error
});
In your Django view, you would send the data as a JSON encoded string.
def my_view(request):
data = {'username': request.user.username,
'is_staff': request.user.is_staff}
return JsonResponse(data)
But, these are Django and Angular, so there are many things to automate much of this, once you understand the basics. Namely Django Restframework and the Angular Resource Service.
I am new to AngularJS and the question may not be very smart.
I am trying to redirect to a new page with data-binding from Spring Controller.
My requirement is that when I click on a button/hyperlink on a page (say page 1), my Spring Controller performs business and determines which page to display (either page 2 or page 3). The data in the redirected page is populated from Spring Controller during redirection using query params.
My problem is that the page redirects just fine. But I am unable to retrieve the query params in AngularJS, though I can view them in the redirection request URL in browser (Google developer tools).
I have only added the relevant code :
Controller method called from first jsp page (say page1.jsp) to redirect to page2 (pageToRedirectTo.jsp)
In page1.jsp, there is a button that calls the method for page redirection along with form object.
<button ng-click="ctrl.onClickOfPage1ButtonRedirect ()">Page Redirect</button>
app.js
var angularApp = angular.module('angularApp',[]);
AngularJs Controller
this.onClickOfPage1ButtonRedirect = function(){
Page1Service.redirectToNewPage()
.then(
function(d) {
$scope.myVal = d;
var e1 = angular.element(document.getElementById("dir"));
e1.html(d);
$compile(e1.contents())($scope);
},
function(errResponse){
console.error('Error.');
}
);
};
AngularJS Service that sends request to Spring Controller
Page1Service.js
angularApp.factory('Page1Service', ['$http', '$q', function($http, $q){
return {
redirectToNewPage: function() {
return $http.post('/requestMappingUrlFromPage1')
.then(
function(response){
return response.data;
},
function(errResponse){
return $q.reject(errResponse);
}
);
}
};
}]);
Spring Controller
#RequestMapping(value="/requestMappingUrlFromPage1", method = RequestMethod.POST)
public ResponseEntity<Void> redirectToNewPage(){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
List<ResponseDTO> responseDTO = new ArrayList<ResponseDTO>();
//Business logic to populate responseDTO list ....
String responseJson= new Gson().toJson(responseDTO);
UriComponentsBuilder b = UriComponentsBuilder.fromPath("/pageToRedirectTo");
UriComponents uriComponents = b.queryParam("responseDTOList", responseJson).build();
return new ResponseEntity<Void>(headers,HttpStatus.FOUND);
}
Now, when I get the response in Page1Service.js, it displays the response.data as the html content of the page being redirected to. In Google Chrome developer tools, I can see the query parameters :
responseDTOList:[{"parameter1":"123","parameter2":"Name","parameter3":false,"parameter4":false},{"parameter1":"123123","parameter2":"Name1","parameter3":false,"parameter4":false}]
Response received in Page1Service.js
Object {data: "<!DOCTYPE html>
↵<html ng-app="angularApp">
↵<head>
.......
↵</body>
↵
↵</html>", status: 200, config: Object, statusText: "OK"}
Is there a way to retrieve this data?
I have tried using $route.params, but it is undefined. Also, I am not using ng-route. Using $location is also not useful as all my pages are dynamically embedded in the custom dir tag in home page, so $location.absUrl() always gives the home page url.
Any suggestions are much appreciated. Thanks a lot in advance!!
I have added the browser header params that shows the response object in my Query Params. Angular response.data, however, displays just the HTML content, and I am unable to retrieve the query params.
Link to view the Browser headers : browser headers
The idea which pop in my head after examine your problem is that the one way of achieving your target is to convert angularJS page into Thymeleaf page. Its very simple to convert it and your all angularJS code will remain same. Please see Thymeleaf doc for this purpose.
Then simply you can get params in js script like this
<script th:inline="javascript">
/*<![CDATA[*/
var message = [[${message}]];
console.log(message);
/*]]>*/
</script>
Once you got your parms in Javascript then you can easily get into angularJS Controller.
If you are getting Page1Service.js response.data as HTML you can use JSON.parse to parse the content and get data.
it will be helpful to provide ans if you make it more clear "when I get the response in Page1Service.js, it displays the response.data as the html content of the page being redirected to."
I am not sure of it is possible to retrieve response data from query parameters in AngularJS.
However, I solved my problem by retrieving the query params in the GET request of the redirected page in Spring Controller. Then, I am sending it back to Angular Service via the HttpServletResponse header and retrieving it back in AngularJS.
Probably not the ideal solution, but that's the fix I could find in a short period without major restructuring of my code.
Spring Controller for redirection from page1 to page2
#RequestMapping(value="/requestMappingUrlFromPage1", method = RequestMethod.POST)
public ResponseEntity<Void> redirectToNewPage(){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
List<ResponseDTO> responseDTO = new ArrayList<ResponseDTO>();
//Business logic to populate responseDTO list ....
String responseJson= new Gson().toJson(responseDTO);
UriComponentsBuilder b = UriComponentsBuilder.fromPath("/pageToRedirectTo");
UriComponents uriComponents = b.queryParam("responseDTOList", responseJson).build();
return new ResponseEntity<Void>(headers,HttpStatus.FOUND);
}
Redirected Page Controller mapping
#RequestMapping(value="/pageToRedirectTo",method = RequestMethod.GET)
public String getpageToRedirectTo(#RequestParam(required=false, name="responseDTOList")String temp, HttpServletRequest request,HttpServletResponse response) {
try{
if(temp!=null){
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//JSON from String to Object
List<ResponseDTO> objList = mapper.readValue(temp,TypeFactory.defaultInstance().constructCollectionType(List.class,ResponseDTO.class));
if(objList!=null){
String jsonList = new Gson().toJson(objList);
response.setHeader("responseDTOList", jsonList);
}
}
}catch(JsonMappingException jme){
logger.error("JsonMappingException : ", jme);
}catch(JsonParseException jpe){
logger.error("JsonParseException : ", jpe);
}
catch(IOException ioe){
logger.error("IOException : ", ioe);
}catch(Exception e){
logger.error("Error : ", e);
}
return "pageToRedirectTo";
}
Page1Service.js
angularApp.factory('Page1Service', ['$http', '$q', function($http, $q){
return {
redirectToNewPage: function() {
return $http.post('/requestMappingUrlFromPage1')
.then(
function(response){
var customResponse = {};
customResponse.responseDTOList= response.headers('responseDTOList');
customResponse.pageData = response.data;
return customResponse;
},
function(errResponse){
return $q.reject(errResponse);
}
);
}};}]);
AngularJS Controller
this.onClickOfPage1ButtonRedirect = function(){
Page1Service.redirectToNewPage()
.then(
function(d) {
$scope.responseList = d.responseDTOList;
$scope.myVal = d.pageData;
var e1 = angular.element(document.getElementById("dir"));
e1.html(d);
$compile(e1.contents())($scope);
},
function(errResponse){
console.error('Error.');
}
);
};
I need to upload an image taken from my mobile device to my server. I found the angular-upload library to which makes reference. I need to do is to transform the image base 64, send it by post to my server because the server is where I will work with her. And the other, send from my server and work it from the application to run.
var server = URL_BASE+'addView/';
var trustAllHosts = true;
var ftOptions = new FileUploadOptions();
ftOptions.fileKey = 'file';
ftOptions.fileName = $scope.imagen.substr($scope.imagen.lastIndexOf('/') + 1);
ftOptions.mimeType = 'image/jpeg';
ftOptions.httpMethod = 'POST';
console.log(ftOptions);
$cordovaFileTransfer.upload(encodeURI(server), $scope.imagen, ftOptions, trustAllHosts)
.then(function(result) {
console.log(result)
}, function(err) {
// Error
console.log(err);
}, function (progress) {
});
ionic file transfer
I'm personally using Cordova file transfer for upload & download content from a server.
Base64 encoding
Don't know where is your image stored and how you retrieve it, but, either you specify that the image is base64 encode into the HTML file delimiter
OR
You transform your image using a canvas
See that post for more info : https://stackoverflow.com/a/20285053/3687474
You haven't specified what you really need so:
Here you have a factory
//Factory you register on your module
angular
.module('myApp')
.factory('sendBase64Image', sendBase64Image)
function sendBase64Image($http) {
var urlBase; //url to be filled in
var base64 = {};
base64.sendBase = function (baseImg) {
var request = $http({
method: "post",
url: urlBase,
headers: {
'Content-type': 'application/json'
},
data : baseImg
});
}
return base64;
}
You should then inject it via dependency injection to your controller and perform call to the server.
If you want to do something with a response use success() method to handle promise response.
I am trying to get PDF document from Web API, and want to show in Angular App. Getting "Failed to load PDF document error".
I have followed
"AngularJS: Display blob (.pdf) in an angular app" post.
Whereas, i can download the same file successfully by following "Download file from an ASP.NET Web API method using AngularJS" post.
Looks like i am getting the file as "Chunked Transfer Encoded". Somehow this is not getting decoded when trying to show in angular app. Please advise.
Web API Code:
HttpResponseMessage result = null;
var localFilePath = #"C:\Test.pdf";
if (!File.Exists(localFilePath))
{
result = Request.CreateResponse(HttpStatusCode.Gone);
}
else
{// serve the file to the client
result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
result.Content.Headers.ContentDisposition.FileName = "Test.pdf";
result.Content.Headers.Add("x-filename", "Test.pdf");
}
return result;
Angular Controller:
myModule.controller("pdfviewerController", function ($scope, $http, $log, $sce) {
$http.post('/api/Sample/GetTestFile', {responseType:'arraybuffer'})
.success(function (response) {
var file = new Blob([response], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
$scope.content = $sce.trustAsResourceUrl(fileURL);
});
});
HTML Template:
<embed ng-src="{{content}}" style="width:200px;height:200px;"></embed>
problem is there in controller.
{responseType:'arraybuffer'} is verymuch required.
For $http.get - It should be second parameter.
For $http.post - It should be third parameter.
In above case, i am using $http.post and i have passed {responseType:'arraybuffer'} as second parameter.
$http.post('/api/Sample/GetTestFile', {responseType:'arraybuffer'})
Corrected code
$http.post('/api/Sample/GetTestFile','', {responseType:'arraybuffer'})