Question

While doing Silverlight's interoperability with JavaScript I've faced a strange behaviour in my Silverlight Out-of-Browser (OOB) application. My goal is to http-post some data to the specific site. We can post data using WebClient or HTTPWebRequest classes. But then how to redirect the response to external web browser? I thought I would generate a dynamic HTML form with post method and invoke a JavaScript function from Silverlight which would submit the form. Unfortunately it only submits the form with target="_self" and not with target="_blank". Code for loading generated html string into Silverlight's WebBrowser control:

WebBrowser wb = parameter as WebBrowser;
if (wb == null)
    return;

wb.NavigateToString(GetHtml());

Simple test method to generate HTML:

private string GetHtml ()
{
    StringBuilder sb = new StringBuilder ();
    sb.Append ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
    sb.Append ("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
    sb.Append ("<head><title></title>");
    sb.Append(
        "<script type=\"text/javascript\">function submitForm(){" +
        "document.forms[0].submit(); window.external.notify(\"Form Submitted!\");}</script>");
    sb.Append("</head>");
    sb.Append ("<body>");
    sb.Append ("<form id=\"mainForm\" name=\"formName1\" action=\"http://localhost:53222/ReceivePost.aspx\" method=\"POST\" target=\"_blank\">");
    sb.Append ("<input type=\"text\" name=\"u\" value=\"username\"/>");
    sb.Append ("<input type=\"password\" name=\"p\" value=\"password\"/>");
    sb.Append ("<input type=\"submit\" value=\"Submit\"/>");
    sb.Append("</form>");
    sb.Append("</body></html>");
    return sb.ToString ();
}

which generates such HTML page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript">
            function submitForm(){
                document.forms[0].submit();
                window.external.notify("Form Submitted!");
            }
        </script>
    </head>
    <body>
        <form id="mainForm" name="formName1" action="http://localhost:53222/ReceivePost.aspx" method="POST" target="_blank">
            <input type="text" name="u" value="username"/>
            <input type="password" name="p" value="password"/>
            <input type="submit" value="Submit"/>
        </form>
    </body>
</html>

And the code for invoking JS function:

innerWebBrowser.ScriptNotify += (o, args) =>
    {
        MessageBox.Show("JS says: " + args.Value);
    };
innerWebBrowser.InvokeScript ("submitForm");

As I said, this code works fine with target set to "_self" but doesn't work with target set to "_blank". Even if I press Submit button with a mouse the post data is not sent, just web site is rendered in external browser without post data. Is it due to the security mechanism in Silverlight? I should also mention that I am posting to the same site where Silverlight app is published: http://localhost:53222 (well it's not published yet as I run it straight from VisualStudio in OOB mode). Thus it shouldn't be categorized as cross-site scripting I guess...

Is there any way to post data to some website (not necessarily from the same domain) and redirect the response to external browser?

Anyway, your comments are most welcome.

Was it helpful?

Solution

I've come up with a workaround which performs exactly what I wanted (starts external browser and loads specific web site while posting some parameters to it). Instead of using WebBrowser control HTML file (similar as in the question) with Form and a JavaScript to submit the form onLoad event is generated. Then the generated HTML content is written into the file system and started with default browser later on.

File may be created with similar code:

using (StreamWriter file = File.CreateText (filePath))
{
    file.WriteLine (GetHtml());
    file.Close ();
}

Default browser may be opened with something like the following code:

using (dynamic shell = AutomationFactory.CreateObject ("WScript.Shell"))
{
    shell.Run (filePath, 7, false);
}

And after the default browser is up and running we may delete the file we just generated:

if (File.Exists (filePath))
{
    File.Delete (filePath);
}

Please note that in order to create/delete a file your SL application needs to be trusted application. That is, it has to have elevated permissions (check Application.Current.HasElevatedPermissions property).

Access local file system in Silverlight 5. In SL 4 one could use com interoperability and Scripting.FileSystemObject to access local file system.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top