I have made previous posts about my custom visualization not working in Spotfire:
https://stackoverflow.com/questions/25390099/awesomium-javascript-handler-being-called-indefinitely
Returning value to C# function from Javascript not working in Awesomium
and I have finally narrowed it down to the offending line.
In my document, I load a source script:
<script src="http://d3js.org/d3.v3.min.js"></script>
This seems to break my entire custom visualization; it infinitely tries to reload the page, from what I've seen. Here is my C# code:
private void WebViewOnDomReady(object sender, EventArgs eventArgs)
{
webView.DomReady -= WebViewOnDomReady;
webView.CreateObject("jsobject");
//webView.SetObjectCallback("jsobject", "callNETNoReturn", JSHandler);
webView.SetObjectCallback("jsobject", "callNETWithReturn", JSHandler);
//webView.ExecuteJavascript("myMethod()");
var result = webView.ExecuteJavascriptWithResult("myMethodProvidingReturn('foo')");
MessageBox.Show("Stuff:" + result.ToString());
}
private void JSHandler(object sender, JSCallbackEventArgs args)
{
var result = webView.ExecuteJavascriptWithResult("myMethodProvidingReturn('foo')");
MessageBox.Show(result.ToString());
MessageBox.Show("Got method call with no return request");
}
And here is my Javascript code:
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
function myMethod() {
document.write("In myMethod, calling .NET but expecting no return value.<br/>");
jsobject.callNETNoReturn();
}
function myMethodExpectingReturn() {
document.write("In myMethodExpectingReturn, calling .NET and expecting return value.<br/>");
var returnVal2 = jsobject.callNETWithReturn("foo");
document.write("Got value from .NET: " + returnVal2 + "<br/>");
}
function myMethodProvidingReturn(whatToReturn) {
var returnVal = whatToReturn + "bar";
document.write("Returning '" + returnVal + "' to .NET.");
return returnVal;
}
</script>
Interestingly enough, the HTML loads fine if I don't try and call a Javascript function and get the return value in C#. However, when I try to return the result of the JS function and print it in C#, including the script src line breaks my entire code; it infinitely returns a blank message judging from the MessageBoxes that I have set.
This is completely baffling me, as it seems to mean that the HTML is being loaded over and over again. Setting the script src tag, for some odd reason, causes this infinite loop.
What exactly is happening?
Thanks
Related
I am working on a cefsharp based browser and i am trying to implement a search engine into the browser, but the code I have tried docent work, it doesn't really have any errors but when i star the project and type something i the text field nothing happens and it dosent load the search engine i entered into the code, the only time the textbox loads anything is when a url is typed.
This is the code used in the browser that docent work
private void LoadUrl(string url)
{
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute))
{
WebUI.Load(url);
}
else
{
var searchUrl = "https://www.google.com/search?q=" + WebUtility.HtmlEncode(url);
WebUI.Load(searchUrl);
}
}
i have also tried
void LoadURl(String url)
{
if (url.StartsWith("http"))
{
WebUI.Load(url);
}
else
{
WebUI.Load(url);
}
}
i was also suggested to try
private void LoadUrl(string url)
{
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute))
{
WebUI.LoadUrl(url);
}
else
{
var searchUrl = "https://www.google.com/search?q=" + Uri.EscapeDataString(url);
WebUI.LoadUrl(searchUrl);
}
}
We have here really few Information on how your code works. But what I notice is that you use WebUtility.HtmlEncode for the search query. WebUtility has also a WebUtility.UrlEncode Method, that how I understand your question makes more sense it the context. This is the documentation for the method: https://learn.microsoft.com/de-de/dotnet/api/system.net.webutility.urlencode
The Url you are generating is invalid. You need to use Uri.EscapeDataString to convert the url param into a string that can be appended to a url.
// For this example we check if a well formed absolute Uri was provided
// and load that Url, all others will be loaded using the search engine
// e.g. https://github.com will load directly, attempting to load
// github.com will load the search engine with github.com as the query.
//
if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
{
chromiumWebBrowser.LoadUrl(url);
}
else
{
var searchUrl = "https://www.google.com/search?q=" + Uri.EscapeDataString(url);
chromiumWebBrowser.LoadUrl(searchUrl);
}
nothing happens and it dosent load the search engine
You need to subscribe to the LoadError event to get actual error messages. It's up to you to display errors to the user. The following is a basic example:
chromiumWebBrowser.LoadError += OnChromiumWebBrowserLoadError;
private void OnChromiumWebBrowserLoadError(object sender, LoadErrorEventArgs e)
{
//Actions that trigger a download will raise an aborted error.
//Aborted is generally safe to ignore
if (e.ErrorCode == CefErrorCode.Aborted)
{
return;
}
var errorHtml = string.Format("<html><body><h2>Failed to load URL {0} with error {1} ({2}).</h2></body></html>",
e.FailedUrl, e.ErrorText, e.ErrorCode);
_ = e.Browser.SetMainFrameDocumentContentAsync(errorHtml);
}
For testing purposes you can also copy and paste the searchUrl string you've generated and try loading it in Chrome to see what happens, you should also get an error.
I have a text field that contains a 2 digit value by default. I want to clear it before I type a new value. I was using TextSlider.Clear(); but after the latest ChromeDriver update, it's no longer working so I am trying to workaround it using backspace. Currently I am doing two backspaces, one at a time.
TextSlider.SendKeys(Keys.Backspace);
TextSlider.SendKeys(Keys.Backspace);
I also tried DELETE but that's also not working. Is there any way to do this in a single line?
Thank you all,
i have managed to workaround using ctrl A and Delete
TextSlider.SendKeys(Keys.Control + "a");
TextSlider.SendKeys(Keys.Delete);
TextSlider.SendKeys(Keys.Backspace + Keys.Backspace);
First try to fix like how TextSlider.Clear(); is not working. There might me loading issue, SendKeys method will work. Try to add wait for page to load properly.
If still not working then you can use,
TextSlider.Click();
TextSlider.Clear();
But below functionality will definatly work,
TextSlider.SendKeys(Keys.Backspace + Keys.Backspace);
Instead of using Keys.Backspace, ideally to clear a text field you need to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using ElementToBeClickable Method (IWebElement):
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(TextSlider)).Clear();
Using ElementToBeClickable Method (By):
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(By.CssSelector("css_TextSlider")).Clear();
Another option is to clear the text element by using Javascript. Due to issues occurring in certain parallel testing situations, I stopped relying on the SendKeys function some time ago. Instead, I use these functions now to set a certain text:
private void SetText(IWebElement element, string text, bool clearOldText)
{
// Clear old text if needed
if (clearOldText)
{
LogInfo("Clearing " + element.ToString() + #" from any text.");
SetElementValue(element, "");
}
element.Click();
SetElementValue(element, text);
}
public string SetElementValue(IWebElement element, string value)
{
ScrollToElement(element);
PaintElement(element, "yellow");
var exec = (IJavaScriptExecutor)this;
var script = #"
var el = arguments[0];
el.value = '" + value + #"';
try
{
if (""createEvent"" in document) {
var evt = document.createEvent(""HTMLEvents"");
evt.initEvent(""change"", false, true);
el.dispatchEvent(evt);
}
else
el.fireEvent(""onchange"");
}
catch(err){ return err; }
return ""Javascript executed."";
";
LogInfo("Setting value to '" + value + "' for " + element.ToString());
var result = exec.ExecuteScript(script, element);
Recorder?.AddScreenshot();
return result.ToString();
}
Personally I dislike the hardcoded javascript a bit, but it always did the job reliably. "SetElementValue" is called twice in this code to ensure correct handling of certain events in my tests: it might not be necessary in other cases.
So, I am dynamically generating jQuery using C# and sending it to the webpage.
The problem is it appears to be generating correct jQuery according to the file and according to Js Fiddle but it does not actually work on the page.
The jsFiddle is here http://jsfiddle.net/ER2hE/
Now I looked up how to send javacript to the website. It should work like this.
http://msdn.microsoft.com/en-us/library/bb359558.aspx
and my code which does that is this method
private void sendScript(string script)
{
const string someScript = "alertMe";
//send the built script to the website.
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), someScript, script, true);
}
This is super simple it has worked for other pieces of code calling. But it has not for this instance.
The code that calls it is this in my C#
private void populateGroups()
{
//this generates correct javascript according to the file and JS fiddle but unfortunately doees not work.
string splitme = "USE ACES SELECT GroupName, GroupID FROM PrimaryGroup ORDER BY GroupName";
DataTable dt = fillDataTable(splitme);
string script = "";
foreach (DataRow dr in dt.Rows)
{
//add the locations to the <select> box
script += " $('#groupList').append('<option value=\" " + dr.ItemArray[1].ToString() + " \"> " + dr.ItemArray[0].ToString() + " </option>'); ";
}
sendScript(script);
JSErrorLog(script, "GROUPS");
}
The whole thing is being called on startup
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack == false)
{
populateMakes();
populateLocation();
populateGroups();
}
}
The jQuery its generating also works in JSFiddle I am pulling this from a method that writes the javascript it generates in a method calling here is the fiddle JSErrorLog.
http://jsfiddle.net/ER2hE/
Oh and my html in my aspx file looks like this
<div class="row2">
<span>Group</span>
<select id="groupList" multiple="multiple" onclick="setGroups()" class="normalsize">
</select>
</div>
I believe that is everything. I just want my stuff to work. I am willing to post any additional code, just ask. If you have an idea as to why its not working, let me know.
When does it actually execute that code? Before or after the element with id "groupList" exists in the DOM? My guess is before.
Solution? Wrap your code inside a document.ready handler.
jQuery(function($) {
$('#groupList').append('<option value=" 46 "> AC Units </option>');
// etc etc
});
Return simple string js code. And run it with eval()
This is a part of the C# code where i want to insert the network graph:
DetailsBody3.Text = "<tr class=\"space\">";
DetailsBody3.Text += "<td>" + "<div id=\"center-container\"><div id=\"infovis\"></div> />";
DetailsBody3.Text += "</div></td>";
DetailsBody3.Text += "</tr>";
In the "infovis" div in the graph code, the graph exists.
And in the graph javascript file:
function init1(){
// init data
}
var fd = new $jit.ForceDirected({
//id of the visualization container
injectInto: 'infovis',
// some other code,
}
I want to call the int1() function and draw the graph in the table created in C# above.
Javascript code runs in the browser. Your ASP.Net C# code runs in the server.
What you actually want to do is add this to the section of your your .aspx file:
<script type="text/javascript">
$(document).ready(
function(){
init();
}
);
</script>
This will call your javascript init() method once the page has loaded.
Try...
Page thisPage = HttpContext.Current.Handler as Page;
if (!thisPage.ClientScript.IsStartupScriptRegistered("run_init1")) {
thisPage.ClientScript.RegisterStartupScript(
thisPage.GetType(),
"run_init1",
"init1();",
true);
}
The above may need to be adjusted a bit depending on what version of the .Net Framework you are using (this works with version 4.0).
I am trying to call a JavaScript function from my ascx control code behind in the catch block.
I have tried the below two ways but they don't seem to work.
Page.ClientScript.RegisterClientScriptBlock(typeof(string), "script", "test();", true);
ScriptManager.RegisterStartupScript(Page, GetType(), "err_msg", "alert('error');", true);
The function is called if I place the code Under "PageLoad" but doesn't get called when placed in catch block.Should I do any different to call a JavaScript function from catch block. Please suggest.
Thanks
Have you tried this?
Page.ClientScript.RegisterStartupScript(typeof(string), "script", "test();", true);
I cant recall off the top of my head if that is equivalent to the ScriptManager option in the question.
Also you need to make sure that the "script key" value you are passing in is unique otherwise asp.net will discard all but the first instance of the registered script with the same key.
might want to try this:
.cs
public String ScriptToRun = "test();";
.aspx
$(document).ready(function() {<%=ScriptToRun %>}); //or you can register event to document mannually
Remember that whatever you done in backend is going to generate HTML, Css& javascript to browser.
update:
I tried the following code, it works in my case. could you please provide more detail?
.cs
public String script = "";
protected void Page_Load(object sender, EventArgs e)
{
throwExcep();
}
private void throwExcep()
{
try
{
throw new NotImplementedException();
}
catch (Exception e)
{
script = "console.log('exception throws from backend message: ["+e.Message+"]')";
}
}
.aspx:
<script>
$(document).ready(function(){
<%=script %>
});
</script>
Javascript does not like at all special characters and NewLine (\r\n) characters. Replace all of those and it will work.
Example:
string test = msgError.Replace("'", "");
test = Server.HtmlEncode(test).Replace(Environment.NewLine, "<br />");
Page.ClientScript.RegisterStartupScript(
typeof(string),
"MyKeyCatch",
//script,
"showErrorMessage('"+test+"');",
true);
What is the catch block for and where is it?
If code in a catch block is executed it usually means that something failed, maybe that failure also is the reason the JS call does not go through.