JavaScriptResult writing the content on Response Stream itself - javascript

I am absolute new to MVC but have worked on ASP.NET. I was doing unit testing and functionality testing of one module and found some weird behavior (it's an old code base).
There is a non-controller class which inherits from ActionFilterAttribute and has method which gets invokes for every action method execution, I believe. This has call to a controller action method using Response.Redirect() like
HttpContext.Current.Response.Redirect("/FAQ/GetContent/?querystringkey=value");
Actual controller/action method code
public JavaScriptResult GetContent(string querystringkey)
{
string url = "/FAQPage.html?key=" + querystringkey;
return JavaScript("window.location.href = '" + url + "'");
}
This works fine and does the redirection to FAQPage.html page but in case exception occurs while executing any action method, instead of redirecting to FAQPage.html page it writes the JavaScript content window.location.href = '/FAQPage.html?key=value' to the response stream itself.
Thus a blank screen appears with this JavaScript line. Am not able to figure out why is this happening? MSDN doc says, JavaScriptResult creates a JavaScript object which is written to response stream.
Please let know what is the issue here and how can I resolve this.

Related

FOSJSRoutingBundle - Routing.generate doesn't do anything

I'm facing a bit of a trouble with the FOSJsRoutingBundle in Symfony4 when trying to load a new template from my Javascript file.
I followed the instructions over here.
The route I want to call is as follow :
/**
* #Route("/", name="homepage", options={"expose" = true})
*/
public function homepage()
{
return $this->render('home.html.twig');
}
When
Routing.generate('homepage');
alert("Finished!");
in my Javascript file gets called, the alert gets displayed and nothing else happens. I should probably add that I'm obviously not on the homepage when this gets called.
However, if I purposefully misspell the name of the Route or if I call a route that has not been exposed via
options={"expose" = true}
I do get an error :
Error: The route "misspelled_route" does not exist. 2 router.js:220:27
and no alert gets displayed, which leads me to believe that I followed the instructions on the Symfony website correctly (?).
Am I missing something obvious or poorly using the bundle ?
Thank you very much !
I'm not entirely sure if I'm supposed to answer my own question like this, but if anybody has the same problem when following the Symfony website's instruction on FOSJsRoutingBundle :
Routing.generate returns a String. If you're like me and want the page to redirect, you can use
window.location.href = Routing.generate('your_route_name');
Thanks to pbenard for this !

my jQuery parameter is not recognized by the C# method in which is accessed in script area

I tried to access the my C# method in my JavaScript, but this method is not accepting the local parameters and saying, the parameter does not exist in the current context.
var typeofServiceNumber = $("#serviceType").val();
#MyStaticClass.StringEncoding(Convert.ToString(typeofServiceNumber));
The above typeofServiceNumber is not recognized by the method
Razor code is executed server side before the HTML is returned in the response stream.
Javascript is executed client side within the resultant HTML.
Therefore you cannot pass a Javascript variable through to a Razor method, and you receive the message that typeOfServiceNumber is not recognized.
To be recognized, it would either need to be handled server side via data being passed to the View (ViewBag, Model etc), or it would need to be declared and assigned to within Razor tags on the page itself.
EDIT: to clarify the last point:
var typeofServiceNumber = $("#serviceType").val();
#MyStaticClass.StringEncoding(Convert.ToString(typeofServiceNumber))
The first line you have here is all happening in the browser of the end user.
The second line is all happening on the server. You see the error message because you are trying to pass "typeofServiceNumber" to your method, and the variable isn't even declared at that point.
Without knowing exactly what you're trying to achieve it's hard for me to give a precise answer as to how to solve your problem. But here are two possibilities:
1) You know what $("#serviceType").val() is going to be before you serve the web page to the end user because that value is being set server side.
Controller:
public ActionResult MysteryController()
{
...your code here to work out what the service type is...
ViewBag.serviceType = serviceType;
return View();
}
View:
...lots of lovely html and such...
<script>
#MyStaticClass.StringEncoding(Convert.ToString(ViewBag["serviceType"]));
</script>
I can't see what the output of #MyStaticClass.StringEncoding() is but I have to assume at this point that it is doing whatever it is supposed to do.
Although the logic is split between the controller and the view, all of this is happening server side.
The second half of my point "or it would need to be declared and assigned to within Razor tags on the page itself." refers to the fact that one variation of this method could involve manipulating data in the View itself by enclosing it in a Razor code block like this:
#{
var typeofServiceNumber = #MyStaticClass.StringEncoding(Convert.ToString(ViewBag["serviceType"]));
}
The alternative, which I did not really address originally is:
2) You don't know what the value of $("#serviceType").val() is going to be before the page is loaded because it is being set by the end user and your function needs to be used before the data is submitted to the server:
If that's the case then #MyStaticClass.StringEncoding(Convert.ToString(typeofServiceNumber)) is no good to you, you will have to replicate the function in JavaScript and include it in the webpage itself.

Error when using YUI3: "Y.QueryString.parse is not a function"

I'm building a Squarespace page, and I want to have an outgoing link on the page whose query parameters are set according to query parameters on the page itself. Since Squarespace embeds YUI3 in every site automatically, I'm trying to use that (even though I have more experience with jquery).
Example: The page is loaded as http://example.com/page/?email=foo#bar.com. I have a link on the page that goes to http://another.example.com/page which should be modified to go to http://another.example.com/page?address=foo#bar.com.
The following code does exactly what I need when I paste it in the browser console:
var MyButton = Y.all('a[href="http://another.example.com/page"]');
var QueryString = Y.QueryString.parse(window.location.search.substring(1));
MyButton.setAttribute('href','http://another.example.com/page?address=' + QueryString.email);
However, when I put that code in the page source, then when the page loads, the following error appears in the console: Uncaught TypeError: Y.QueryString.parse is not a function
My current theory is that YUI3 loads asynchronously in pieces, and this code runs at a point when Y.all is available but Y.QueryString.parse is not... is that right? What would be the best solution to this?
Yui3 is indeed built around asychonous modules loading, in this case you miss the querystring module.
You need to wrap your code with a Y.use call:
Y.use('querystring', function(Y) {
var MyButton = Y.all('a[href="http://another.example.com/page"]');
var QueryString = Y.QueryString.parse(window.location.search.substring(1));
MyButton.setAttribute('href', 'http://another.example.com/page?address=' + QueryString.email);
});

Setting window.location in JavaScript hangs

I have an ASP.NET MVC app. My app uses jQuery on the client side. The user can enter values into several fields and click "Refresh". The Refresh is behaving oddly.
When Refresh is clicked, I execute the following JavaScript:
function refresh() {
var chosen = "(someField eq 'value')";
try {
if (chosen) {
var url = 'http://localhost:8089/item&c=' + chosen;
alert(url);
window.location = url;
} else {
window.location = 'http://localhost:8089/item';
}
return false;
} catch (ex1) {
alert(ex1);
}
}
The value for chosen is actually generated via a function. I've noticed when I use a certain type of control, the page hangs. Here is what is odd, I can see the request made in Fiddler. Yet, my breakpoint in my controller action is never hit. If I copy and paste the url from the alert call into the address bar, my breakpoint gets successfully hit. So, I'm totally confused.
Due to the fact this involves a specific control, I at first assumed this was a JavaScript error. However, I do not see any JavaScript error in the console. I also checked to see if any exceptions were being swallowed and I did not see any.
The fact I see the request in Fiddler, would imply that I'm getting to the web server. Yet, if I have a breakpoint on the very first line of the controller action, I would expected that to trip. It does not trip in the scenario where I use the control. It does trip if I do NOT use the control. The result in Fiddler sits at '-'. It never returns. Plus, I do not get an exception thrown in my ASP.NET view.
I'm totally stuck on this and looking for ideas of potential causes. Thank you.
This behavior is usually the result of a problem during model binding for the controller.
A quick step to try is making sure the query string values you are sending are properly encoded.
var chosen = "(someField eq 'value')";
chosen = encodeURIComponent(chosen);
Would eliminate any bad character problems that the model binder might be having.

Overwrite a javascript variable from webdriver

I'm not sure whether is there any solution for my issue but, unfortunately I haven't found any article or information about it.
The situation is the following. We have a site which uses jQuery heavily and there is a service which refreshes a part of the site in every 5th or 10th second. Due to this half of the time I got this error from WebDriver:
"Element not found in the cache - perhaps the page has changed since it was looked up"
According to the Internet I got this error when the DOM tree has changed between the moment when the WebElement has been initialized and when I want to use it to perform, for example, a click event.
According to our developers our jquery solution has a variable which controls whether the page will be refreshed or not. So, to solve my issue I have to overwrite this variable. I have to overwrite this variable in that way the jQuery will be able to understand it - I mean in the same instance if this definition is proper in this context.
So, I would like to ask whether is possible or not? If so, than I would like to ask a small example.
Thanks in advance!
AndrĂ¡s
I can only agree with Aleh.
Using JavaScriptExecutor is the only way to handle such issues.
I had a problem with jQuery jNice library and couldn't find any other solution.
Here is an example in Java for filling a text field:
JavascriptExecutor js = (JavascriptExecutor) webDriver;
js.executeScript("document.getElementsByName('<field_name_gets_here>')[0].value='" + your_value + "'");
If the JavaScript variable you mentioned is global, then yes - you can overwrite it by executing JavaScript from your Selenium. For example, if that variable is called doRefresh, you can overwrite it by executing JS like this: doRefresh = false; from Selenium.
If that variable is not global, the above won't work. However, it sounds like the elements in question might be dynamically loaded via ajax - in which case the xhr object is global and you can access it instead.
So, first you can make a local copy of the xhr object and then overwrite the original (effectively disabling it) by executing JavaScript from Selenium:
// create a copy of the xhr object for later use
var xhrHolder = window.XMLHttpRequest;
// overwrite the original object to disable it
window.XMLHttpRequest = {};
Then find your element via Selenium as you would normally. And proceed with your test.
When finished, you can put the xhr object back in place (so the page can continue refreshing and doing ajax) by executing JavaScript from Selenium:
// put the xhr object back
window.XMLHttpRequest = xhrHolder;
You can try my approach - I created my own wrapper for situations where page might be loading. The below part of code tries to search element in the loop, for three seconds (configurable). BTW the driver variable below is instance of WebDriver
private WebElement foundElement;
public WebElement find(By by){
for (int milis=0; milis<3000; milis = milis+200){
try{
foundElement = driver.findElement(by);
}catch (Exception e){
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
return foundElement;
}
And later in the code:
WebElement submitButton = find(By.id("submitNewBid"));
submitButton.click();
I believe it is possible. Example for c#:
((IJavaScriptExecutor)driver).ExecuteScript("window.$('.class').data('var') = 0;")

Categories