I'm trying to get a report from SSRS Rest API. I can see it when I navigate to the URL
https://myPC:443/ReportService?%2fSSRS%2fPatientèle&rs:Command=Embed&rc:LinkTarget=main&Hospital=CHRU%20Strasbourg
in chrome
When I navigate there in the browser I can see my report.
So I've tried to get the HTML from a controller:
[HttpGet]
public async Task<string> GetReportAsHTML()
{
using (var client = new HttpClient())
{
using (var result = await client.GetAsync("http://myPC:80/ReportService?%2fSSRS%2fPatientèle&rs:Command=Embed&rc:LinkTarget=main&Hospital=CHRU%20Strasbourg"))
{
if (result.IsSuccessStatusCode)
{
return await result.Content.ReadAsStringAsync();
}
}
}
return "";
}
It's returning 401 unauthorized, and the statement in the if is never reached.
Can someone please explain how I can resolve this problem so I get the correct response?
EDIT
I tried both, I mean in http & https, and both return the report without authentification. Http access (http://localhost:80/...) was even better because charts aren't displayed, only tables. With https access, I get the following picture instead of the charts:
If you need to embed reports, you can also consider doing so in an <iframe> - just point its src to the report URL.
<iframe src="https://myPC:443/ReportService?%2fSSRS%2fPatientèle&rs:Command=Embed&rc:LinkTarget=main&Hospital=CHRU%20Strasbourg "></iframe>
The added benefits are:
iframes usually share cookies with their parent, so if the report server needs such authentication it may work immediately
if the report is somehow interactive (say, it actually returns an html page with filters, dropodwns and the like) - your end user would get that too instead of static HTML that might even break when taken out of its context
You may also want to look into ready-made Blazor report viewer components - perhaps your reporting solution vendor already has one.
It seems like url in your code do not match the one you use through Chrome? Could this be the issue?
Related
I trying to upload a file using pug, multer and express.
The pug form looks like this
form(method='POST' enctype="multipart/form-data")
div.form-group
input#uploaddata.form-control(type='file', name='uploaddata' )
br
button.btn.btn-primary(type='submit' name='uploaddata') Upload
The server code looks like this (taken out of context)
.post('/uploaddata', function(req, res, next) {
upload.single('uploaddata',function(err) {
if(err){
throw err;
} else {
res.json({success : "File upload sucessfully.", status : 200});
}
});
})
My issue is that while the file uploads successfully, the success message is not shown on the same page, ie: a new page is loaded showing
{success : "File upload sucessfully.", status : 200}
As an example for other elements (link clicks) the message is displayed via such javascript:
$("#importdata").on('click', function(){
$.get( "/import", function( data ) {
$("#message").show().html(data['success']);
});
});
I tried doing a pure javascript in order to workaround the default form behaviour but no luck.
Your issue has to do with mixing form submissions and AJAX concepts. To be specific, you are submitting a form then returning a value appropriate to an AJAX API. You need to choose one or the other for this to work properly.
If you choose to submit this as a form you can't use res.json, you need to switch to res.render or res.redirect instead to render the page again. You are seeing exactly what you are telling node/express to do with res.json - JSON output. Rendering or redirecting is what you want to do here.
Here is the MDN primer on forms and also a tutorial specific to express.js.
Alternatively, if you choose to handle this with an AJAX API, you need to use jquery, fetch, axios, or similar in the browser to send the request and handle the response. This won't cause the page to reload, but you do need to handle the response somehow and modify the page, otherwise the user will just sit there wondering what has happened.
MDN has a great primer on AJAX that will help you get started there. If you are going down this path also make sure you read up on restful API design.
Neither one is inherently a better strategy, both methods are used in large-scale production applications. However, you do need to choose one or the other and not mix them as you have above.
I am developing an SPA application using AngularJS working with REST Web API, on top of a very small layer of ASP.NET MVC4. For reasons not important here, I am not using the default Account Controller of MVC4.
basically, I want to share "tasks" between users. My goal is to be able send the URL of a specific "task" entity to any user, via email. Clicking on that URL should launch the authentication. Following a successful authentication, I want to display the real task page info.
AngularJS causes my URLs to have # sign, or a URL of a page displaying the task "XYZ123" is:
http://hostname.com/#/tasks/XYZ123
ASP.NET redirects the unauthorized access to that URL to:
http://hostname.com/Home/Login?ReturnUrl=%2f#/tasks/XYZ123
This is OK, but the relevant controller method "cuts out" the path from #, so in:
public ActionResult Login(string returnUrl)
the value of 'returnUrl' will be just "/"
So, I am losing the path: I would like to build a "Connect with Facebook" link having the original URL, like:
http://hostname.com/Login/ExternalLogin?ReturnUrl=%2F#/tasks/XYZ123
but I cannot.
What is the right way to solve this issue?
I can think of creating my own redirection service URL without # tag, but this solution implies additional work, and covers only a case when the system is sending a message with task URL - humans will still try to copy/paste the location URL from the browser.
Thanks for any hint.
Max
Yes. A browser cuts '#/tasks/XYZ123' and requests page without that hash.
Although the hash itself apears on the logon page - it's the browser's work again.
Hash is not traveling to the server.
So when a browser loads the logon page with ?ReturnUrl=%2f#/tasks/XYZ123 we can rewrite Form action and encode the hash.
If the form looks like:
<form action="/Home/Login" method="post" >
...
</form>
The javascript code should look like:
<script src="~/js/jquery.js"></script>
<script type="text/javascript">
$(function() {
var search = $(location).attr('search') || '';
var hash = $(location).attr('hash') || '';
if (hash.length === 0) {
if (window.history.pushState) {
window.history.pushState('login', 'Login', '/Home/Login');
}
} else if (search === '?ReturnUrl=%2f') {
$('form').attr('action', '/Home/Login' + search + encodeURIComponent(hash) );
}
});
</script>
The part with window.history.pushState is required for the following:
If there is no hash, then for a SPA its URL (more likely) will be:
http://hostname.com/Home/Login?ReturnUrl=%2f
so here we try to replace URL (without page reload) with more accurate
http://hostname.com/Home/Login
You can use the properties of Request (like .Urlor .QueryString) to get the original url (and url parameters), instead of relying on the automatic binding of returnUrl parameter.
Replace # in the returnUrl with %23
I'm using woocommerce JSON API to retrieve the data of some products like price, SKU, etc...
The thing is that I get an error using this API. I've installed the plugin succesfully and activated it in the WordPress Dashboard.
I've tried the example given in GitHub exactly as the author says.
Here's my javascript code:
$(document).on('pageinit','#restau' ,function(){
var url = 'http://danielvivancos.com/edu/wordpress/shop/?callback=?';
params = { action: 'woocommerce_json_api', proc:"get_products"};
params.arguments = {token: 1234, per_page: 2, page: 1}
jQuery.getJSON(url,params).done(function (data) {
alert("success");
console.log(data);
console.log(url);
}).error(function(jqXHR, textStatus, errorThrown){
alert(jqXHR.responseText);
});
});
At first it didn't do anything, and I didn't understand what was happening but then I added the .error() function and it threw me an error...
Here http://danielvivancos.com/edu/directebre_app_jquerymobile/ you will find the three alerts displayed when you click on any of the three products.
Hope someone can help me or give me some ideas to solve it.
Thank you all!
The API Almost always returns some kind of error string and error code. The one time when it wouldn't would be if there was a PHP error (Even then it tries to catch the error and return something).
One thing you may need to do is to visit the users settings page, setup your permissions, and then save the settings for that API User. Whenever a new method is added to the API you will have to visit this page and resave it.
Another thing to do is to try and run php tests/get_products.php and see what happens. Most of the API functions have a tests file that you can run from the command line to test the API.
Also, while I am very happy you are using it :) it is still unfinished and in the early stages of development.
It looks like your example is working though?
Could you post a bit more about what error you are getting?
When I click on one of the items, it takes me to a page where a popup shows up with a bunch of HTML, this normally means that your API page is not setup properly (if it is making an api request). You will need to setup the API page ( Just create a wordpress page, or use an existing one) Then in the WooCom menu select JSON Api, and set the API page from the dropdown list. Remember to save.
I am working in a Mobile project (using Titanium Studio), in which i have the below situation
1) My Mobile app contacts Rails backend to check some data, say check validity of a
user id.
2) I found a way to load web pages in Mobile app, i.e., WebView
3) I could able to load the desired url, ex http://www.mydomain.com/checkuser?uid=20121
which would return data like status:success
But i need to read this data to show whether the response from server is a success or failure, how do i achieve this?
NOTE : The above mentioned scenario is an usecase, but actually what happens is i load a third party url in WebView and when user enters the data and submits, the result will be posted back to my website url.
EDIT : So the process is like below
1) WebView loaded with third party url like http://www.anyapiprovider.com/processdata
2) User will enter set of data in this web page and submits the page
3) The submitted data will be processed by the apiprovider and it returns data to my web page say http://www.mydomain.com/recievedata
This is the reason why i am not directly using GET using HTTPClient
FYI : I tried to fire Ti.APP events right from the actual web page as suggested by few articles, but most of them says this will work only if the file loaded is in local and not a remote file. Reference Link
Please suggest me if my approach has to be improved.
Thanks
If you don't want to follow Josiah's advice, then take a look at the Titanium docs on how to add a webview.addEventListener('load',... event listener and use webview.evalJS() to inject your own code into the third party HTML.
Maybe you can inject code to trap the submit event and fire a Ti event to trigger the downloading of data from your website.
Communication Between WebViews and Titanium - Remote Web Content Section
I found a solution for my problem
1) Load the http://www.mydomain.com/checkuser?uid=20121 in a webview
2) Let user enter and submit data to third party url
3) Recieve the response from third party url and print only <div id="result">status:success</div> in http://www.mydomain.com/recievedata page.
4) Add event listener for the web view as follows
webView.addEventListener('load', function(data)
{
//Add condition to check if the loaded web page has any div with id = result (to check if this is /recievedata page)
alert(webView.evalJS("document.getElementById('result').innerHTML"));
});
The above alert would print the result status:success, read it in webview load event
and take actions in web accordingly.
It works fine for me.
Instead of loading it in a WebView why not just GET it using a HTTP Client? This is much cleaner, and more standards based:
var xhr_get = Ti.Network.createHTTPClient({
onload : function(e) {
// Here is your "status:success" string
var returnValue = this.responseText;
},
onerror : function(e) {
Ti.API.info(this.responseText);
Ti.API.info('CheckUserProgressOnActivity webservice failed with message : ' + e.error);
}
});
xhr_get.open('GET', 'http://www.mydomain.com/checkuser?uid=20121');
xhr_get.send();
I'm currently writing a web widget, and I would like to fill the content of this widget with some HTML data generated by a wicket component on my server.
To do that, the server will output the HTML data via JSONP. So far so good.
However I need to get this HTML data. How can I get on the server the HTML output from some wicket component?
I dont know if this can be applied to your configuration, but I am using a view lines of code to retrieve rendered html which I wrote some time ago for building html based emails to be able to use wicket components in it
protected final String renderPage(Component page) {
final Response oldResponse = RequestCycle.get().getResponse();
BufferedWebResponse tempResponse = new BufferedWebResponse((WebResponse) RequestCycle.get().getOriginalResponse());
try {
RequestCycle.get().setResponse(tempResponse);
page.render();
}
finally {
RequestCycle.get().setResponse(oldResponse);
}
return tempResponse.toString();
}
As this rendering is made within an actual webapplication cycle but independently from the actual requestcycle, it is recommended to preserve the original requestcycle. The page will be rendered in your temporary webresponse from which you can retrieve the rendered html output.
Hope this may be what you are looking for
You might find everything you need in this Wicket Wiki article and the linked source code: Use wicket as template engine
Although I must admit that I never tried that, just read it and remembered for further reference...