Call OpenFileDialog Silverlight from JavaScript - javascript

I'm trying to call a function in a Silverlight 4 component to open a file dialog and upload a file to the server. Everything works well within Silverlight but I'd like to call the component from JavaScript. So I call the button click handler from a C#-function which is [ScriptableMember]. I get the following error when calling the function:
System.Security.SecurityException: Dialogs must be user-initiated.
at System.Windows.Browser.ManagedObjectInfo.Invoke(ManagedObject obj, InvokeType
invokeType, String memberName, ScriptParam[] args) at
System.Windows.Hosting.ManagedHost.InvokeScriptableMember(IntPtr pHandle, Int32 nMemberID,
Int32 nInvokeType, Int32 nArgCount, ScriptParam[] pArgs, ScriptParam& pResult,
ExceptionInfo& pExcepInfo)
I based my code on the tutorial by Tim Heuer that can be found here: http://www.silverlight.net/learn/videos/silverlight-videos/openfiledialog-and-file-upload/
I understand why the error is thrown, sort of, the 'click' from the user is done in JavaScript and probably is not going through to Silverlight. For Silverlight this is merely a function call.
Is this new policy from Silverlight 4? Is it still possible to only use Silverlight behind to screens to upload a file? Any help is appreciated.

I believe in Silverlight 2 this may have been permitted, but ever since it has not. This was a breaking behavior change, requiring the action to be "user initiated" through a user action -in- Silverlight: something like a key press or mouse click on a button with a click event handler.
There isn't a way to pop up and open the file dialog any other way.

Related

Error: Could not complete the operation due to error 8150002e

I am working on a Outlook VSTO add-in, in which I am using 'System.Windows.Forms.WebBrowser' to display the add-in functionality.
One functional requirement is to have oauth connection to cloud accounts (like OneDrive, Dropbox). When user clicks a button (e.g. 'Connect OneDrive'), we call 'window.open' in JavaScript code (ES6) with the oauth-url.
The issue which I am facing is, if user doesn't enter any credentials and close the window, and then again try to connect the cloud account (by clicking the 'Connect OneDrive'), I am getting an exception (Error: Could not complete the operation due to error 8150002e.).
I couldn't find any information about the error code '8150002e' on web.
This exception is not always present but comes around 50% of the times.
Any help would be appreciated in this.
what I have tried:
changing the windowName param every time window.open is called
having global var for window Object.
Using _blank parameter to open a new window every time.
After 5-6 times, the error comes up, after 5-6 times error goes away and auth window start coming up like before.
Opening a simple static HTML page in 'window.open' to verify if the issue has something to do with HTML page. The above issue is still present.
Resetting the System.Windows.Forms.WebBrowser programmatically.
Removing the cookies.
Instead of calling window.open from JavaScript code, we call VSTO code to open the browser window, the error is still there.
Edit: Created a minimal viable example at
https://github.com/vinay-x/SampleAddin
Code related to the issue:
SDXOLForm1.cs (navigates the browser to SamplePage.HTML hosted on localhost:8001)
SamplePage.HTML (contains a button, which calls window.open function).
The sample application has a windows form which contains a webBrowser control, which navigates to a simple HTML page which contains a button.
Had to deal with some IE11 stuff and I ran across this question. The solution I found to fix this issue is to set the window variable to null prior to calling window.open.
So for your example you have this:
function myFunction() {
window.open("https://www.w3schools.com", 'BackfliptOAuth', "width=800,height=800,center=true,useContentSize=true");
}
I modified it to this:
var win = null;
function myFunction() {
win = null;
win = window.open("https://www.w3schools.com", 'BackfliptOAuth', "width=800,height=800,center=true,useContentSize=true");
}

How to call an onclick javascript function directly in url?

I want to call to a onclick function as I am writting script for MikroTik RouterBoard in order to restart my Modem by just visiting a simple link directly but what I found was that the page from which Modem is rebooting there is a button which calls to a onlick function as :
<input type="button" onclick="btnReset()" value="Reboot">
So is there any way that I can Call this onclick function directly in a http url like :
http://admin:hunter#192.168.1.1/resetrouter.html?btnReset()=Reboot
Here is MikroTik Script which I am writting but it can't do the job..It need a direct link which it visits only and downloads a file..!
If anyone MikroTik Scripting person can help will be greatful..Until then if there is any way to do it in direct url so then that will be great..!
{
/tool fetch url="http://admin:hunter#192.168.1.1/resetrouter.html?btnReset()=Reboot" mode=http
}
That's not possible to perform js code from a hyperlink (unless the page has script inside, specifically for this and it's checking for some parameter...) .
However there are some tools which could help you perform desired action in other way:
Install Custom JS for Web Sites plugin and define js script which would be executed after your http://admin:hunter... page would be loaded in browser.
For your case it would be simple function call:
btnReset()
Analyse body of btnReset() function( probably that function sends http request) and construct same request with cURL, see cURL Tutorial.
Take a look on Bookmarklet, which is a bookmark stored in a web browser that contains JavaScript commands.
Get familiar with PhantomJS or Selenium and write simple script which would perform desired action for you.
The btnReset() function is probably just a dialog followed by a URL fetch. Open the javascript console, type btnReset.toString() and have a look. If you see a URL in there, try visiting that directly.
You need a very specific URL "http://admin:hunter#192.168.1.1/rebootinfo.cgi". In my case the function btnReset() calls "rebootinfo.cgi". I followed the below steps to find "rebootinfo.cgi".
Open the "save/reboot" page or equivalent page of your router.
Inspect the button "Reboot", i.e, right click on the particular button and click "Inspect" from the menu.
In the developer tool now opened to the right, note the function for the onclick attribute in the highlighted line. E.g. in my case, btnReset() from the line "input type="button" onclick="btnReset()" value="Reboot".
Go to the console tab on the developer tool and paste the function name without parenthesis E.g., btnReset (not btnReset() ) and hit enter.
In the function definition for btnReset(), look for the exact command that is responsible for rebooting the router. In my case it was "rebootinfo.cgi".
That's it, construct the URL.

Silverlight ShowDialog() throws security exception when triggered throguh javascript

I have a javascript function like below.
var object;
$(document).ready(function () {
$("#buttonA").click(function (e) {
object.doWork(); //triggers a method in Silverlight
});
});
Method in Silverlight
private void doWork()
{
SaveFileDialog dialog = new SaveFileDialog();
dialog.ShowDialog(); //throws error "Dialogs must be user-initiated"
}
Any ideas why the error is thrown. I do not have any break points set in the doWork method in silverlight. The button click event in javascript seems to be user initiated event. Please suggest a solution to this problem.
Thanks,
Dialogs must be user-initiated in the sense that they have to occur due to a user interaction event (click, button press etc) within the Silverlight component. (In fact "due to" is really a restriction of having to occur within a certain period after the interaction, rather than some strict restriction such as relating to the call stack)
From the perspective of the Silverlight security restriction, this is just an arbitrary javascript method calling into Silverlight, and so this will not be possible (for good reason). You would need to open the dialog from a real Silverlight button.
If you really need to raise some kind of dialogs from a Silverlight control called via javascript, you may need to actually call back out to open a dialog in JavaScript/HTML (or some kind of popover in either environment).

Android: Calling javascript from WebView

We're coding an app for Android. It's a WebView that contains Html5 pages. We're using loadUrl() webview's method, in order to push some native OS variables to html, such as:
webview.loadUrl("javascript:myJavascriptFunc('" + myAndroidOSVar + "');");
It works pretty fine. But if we are typing on an input from page while loadUrl() is called, we lose focus of our input fields, even if javascript function called just changes a flag on cache.
Do you know other way to call a Javascript function from WebView instead of loadUrl()?
This is the closest you can get to avoiding the issue: WebView hides soft keyboard during loadUrl(), which means a keyboard cannot stay open while calling javascript
Basically you are avoiding the loadUrl call by queuing up commands on the native side and at an interval letting the JS bridge get the commands and execute using JS eval() or something.
I'm not sure exactly how it will respond if you have multiple fields in the webview, but I came up with a workaround to keep the keyboard shown: https://stackoverflow.com/a/18776064/513038. It may be worth trying.
yes, there is a way by adding a JavaScriptInterface to your WebView , refer this tutorial for more explanation and details

What does the JS function 'postMessage()' do when called on an html object tag?

I was recently searching for a way to call the print function on a PDF I was displaying in adobe air. I solved this problem with a little help from this fellow, and by calling postMessage on my PDF like so:
//this is the HTML I use to view my PDF
<object id="PDFObj" data="test.pdf" type="application/pdf"/>
...
//this actionscript lives in my air app
var pdfObj:Object = htmlLoader.window.document.getElementById("PDFObj");
pdfObj.postMessage([message]);
I've tried this in JavaScript as well, just to be sure it wasn't adobe sneaking in and helping me out...
var obj = document.getElementById("PDFObj");
obj.postMessage([message]);
Works well in JavaScript and in ActionScript.
I looked up what the MDC had to say about postMessage, but all I found was window.postMessage.
Now, the code works like a charm, and postMessage magically sends my message to my PDF's embedded JavaScript. However, I'm still not sure how I'm doing this.
I found adobe talking about this method, but not really explaining it:
HTML-PDF communication basics
JavaScript in an HTML page can send a message to JavaScript in PDF content by calling the postMessage() method of the DOM object representing the PDF content.
Any ideas how this is accomplished?
"postMessage" is essentially one half of a publish/subscribe model for JavaScript.
You can post any message you like, but it relies on something listening for that message event. So your postMessage is essentially you throwing an event over the fence, hoping that something is waiting on the other side to do something with the event. On the other side of the fence is (hopefully) an event listener like this:
window.addEventListener("message", doSomethingWithTheMessage, false);
function doSomethingWithTheMessage(event) {
alert("Do Something!");
}
More information here: https://developer.mozilla.org/en/DOM/window.postMessage
In your specific example, when you embed an object such as a PDF, Flash or something along those lines, they may well listen for events in exactly this way.

Categories

Resources