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.
Related
I have to implement a way to select values from an ASP horizontal menu (generated with a config file). The generation of the menu is not an issue: my actual problem is to find a way for the user to access its values without using postbacks.
I am working on a big and old project that was coded with the intent of not using PostBack requests at all. Postback are by design unexpected and considered as bugs.
In order to reach my goal, I tried to code a JavaScript trigger for the MenuItemClick event that ends with return false, in order to avoid postbacks (currently the JavaScript code is limited to a simple test alert and the false return, for testing purposes). But this doesn't work: I can't get the event to fire the JavaScript function: a post back happens, which is undesired.
The complete code consist of thousands lines (most of them unrelated to the issue), here is an abridged version with only the relevant lines:
Default.aspx:
<%# Register TagPrefix="CRB" Namespace="ConfigurableReportBuilder.PageControls" Assembly="ConfigurableReportBuilder" %>
<form id="form1" class="page" runat="server">
<CRB:HorizontalMenu ID="MainMenu" runat="server" RootNode="Menu/Items" StyleClass="ui-menu ui-state-hover"/>
//this works fine, no issue here.
</form>
Default.aspx.cs:
(...)
if (this.IsPostBack)
throw new Exception("PostBack requests are not expected to occur");
//Ensure that "PostBack requests" (which are unexpected and therefore indicate bugs) become recognized by a specific exception which is thrown here
Workspace.js:
var WS = (function ($) {
var test = function (event) {
alert("test");
return false; //prevent postback
};
(...)
return {// This dictionary contains references to public methods used in the project
test: test,
(...)
}
}
$(document).on("menuitemclick", '#MainMenu', WS.test); //setting the event trigger
I have found a solution that does achieve the desired goal, but beware, it doesn't respect good practices of coding. There might be better solutions available, but i can't find any.
The idea is to abandon the MenuItemClick event based logic and revert to the default behavior of an ASP menus, having URLs as clickable menu items(NavigateUrl). The URLs will are accessible in the main page without any postback, they can therefore be used to carry the information... as small JavaScript codes.
In order to do this, one must set raw Javascript code as NavigateUrl parameters during the initialization of the menu items:
protected MenuItem getMenuItem(XmlNode menuNode)
{//function that initialize a MenuItem with an XML node as parameter
MenuItem mi = new MenuItem(); //creating a MenuItem object
//Assigning its properties:
mi.Text = menuNode.Attributes["text"].Value;
if (menuNode.Attributes["description"] != null)
mi.ToolTip = menuNode.Attributes["description"].Value;
if (menuNode.Attributes["configfile"] != null) {
mi.Value = menuNode.Attributes["configfile"].Value;
mi.NavigateUrl = "javascript:alert('"+mi.Value+"');"; //Note that this isn't an URL
}
}
The URL from the ASP menu are therefore not links but functions that will be executed by in the main page, without going though any event. Theses function can therefore be used to retrieve the desired values, without going though any postbacks-events : in the example I just gave, an alert window displays the selected dropdown value.
We have a use case where we need to block Drupal's core ajax error handling from alerting users (we're handling the error reporting on our own). Previously another developer had commented out a line in the core ajax.js file, to prevent Drupal from spawning the alert box, but I'd like to handle it without touching core.
From the core, drupal.js:
/**
* Displays a JavaScript error from an Ajax response when appropriate to do so.
*/
Drupal.displayAjaxError = function (message) {
// Skip displaying the message if the user deliberately aborted (for example,
// by reloading the page or navigating to a different page) while the Ajax
// request was still ongoing. See, for example, the discussion at
// http://stackoverflow.com/questions/699941/handle-ajax-error-when-a-user-
// clicks-refresh.
if (!Drupal.beforeUnloadCalled) {
alert(message);
}
};
My current fix, is to override the Drupal.displayAjaxError function and change the Drupal.beforeUnloadCalled property that determines whether or not to alert the error:
var ajax_error_backup = Drupal.displayAjaxError;
Drupal.displayAjaxError = function (message) {
Drupal.beforeUnloadCalled = true;
ajax_error_backup(message);
};
My question, is whether or not this is an appropriate fix? I know that I could also override the function and just leave it empty - costing fewer lines, and not invoking another call to the original function (and saving the object I've created by backing up the original in ajax_error_backup).
Am I adding complexity to keep things tidy, or should I just override with:
Drupal.displayAjaxError = function (message) {
//empty
};
To clarify - the desire is to never have this ajax alert occur, so there's not functional difference between my desire to keep things neat/tidy, and just overriding the function with a blank one - there isn't a case where want this alert to succeed.
Thanks in advance for helping this old dog think through something with fresh eyes.
In this case, there isn't one option that seems to be clearly better than the other. It should be handled on a case by case basis, and in this case, either of the methods really is adequate.
I personally opted for using the slightly more expensive method of overriding the function and calling it back, because I felt that it might be somewhat more future-proof:
var ajax_error_backup = Drupal.displayAjaxError;
Drupal.displayAjaxError = function (message) {
Drupal.beforeUnloadCalled = true;
ajax_error_backup(message);
};
If Drupal were to extend the function on their end in the future, there might be another condition that we wouldn't want to override.
Overriding with the empty function would be the cheapest, but would also potentially be a bit heavy handed.
It seems that either approach is valid, and is probably best handled case-by-case.
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.
Solution below: Edit #2
I've a HTML-list the user is able to sort. I don't want to save the data after every drag/drop action, so I save the data on unload: in a cookie and database. Thats working, but:
After saving the data the list is hidden and I get a "syntax error" in this line:
<!DOCTYPE html>
It's strange because everything works fine after refreshing the same page (F5) without changing anything.
I try to find the cause but no success. That's the flow:
1. visit the page (index.php)
2. change the list (set: list_is_dirty = true)
3. click any internal link (call $(window).unload( ... save_data() ... )
4. target page appears without the list (syntax error!)
5. refreshing the page (everything works fine)
Do you have any idea how to find this error? Any tools or strategies? Or maybe the same experience with the unload function?
Thanks in advance!
Edit:
Some code:
var list_is_dirty = false;
// document ready?
$(function() {
function sort_list() {
// some code, not important
}
sort_list();
$(window).unload(function() {
if (list_is_dirty == true) {
/* ---------- HERE's the error! ---------- */
/* The error occures when I try to call the script.php
I tried load(), $.post(), $.get() but nothing works.
The string is correct. I'm not even able to call any of
these functions without params.
*/
// send data to script.php to save data
$("#div").load("script.php?str="+list_data_str);
$.cookie("list_data", list_data_str);
}
});
}
Edit #2 / Solution:
I don't know why, but everything works with window.onbeforeunload instead of jQuery.unload(). An explaination would be great! I'm sorry for this confusing thread!
window.onbeforeunload = function(e) {
$("#div").load("script.php");
}
I think that your issue is with: list_data_str as it's not defined anywhere.
if you are trying to say that you want to do AJAX post for example, then obviously you need to look for success event
else it appears that what your demo code is missing something because you can do it the way you are trying if at the receiving script you use $_GET over the URL and not pay attention to any parameters.. In other words, you are missing the object and when you refresh the page it's loaded into the DOM. Apparently that could be the issue that you are describing, I would suggest that you post a bit more of relevant to your issue code.. like the receiving script or any errors from a debugger like Firebug.
Regarding how to test it, you might want to use console.log in supported browsers or simply alert when is setting up the cookie.
var global list_is_dirty = false;
function sort_list(list, list_is_dirty) {
// some code, not important
//check the list and the flag
//you should return a value, else it does not make sense to use a function here.. note the var defined as global
return list; //?? not sure what to return as don't know what this code does from the posting
}
jQuery(function($)
{
$(window).load(function(e){
var list_data_str= sort_list( );
// send data to script.php to save data
e("#div").load('script.php?str='+list_data_str);
//on unload destroy the cookie perhaps?? or if it's not set a session variable
e.cookie("list_data", list_data_str);
...
The unload event
$(window).unload(function(e) {
$("#div").load("script.php?str="+list_data_str);
$.cookie("list_data", list_data_str);
}
});
}
....
// About your EDIT: Are you passing in here any parameters to the script? Because I think the problem is at that logic.
window.onbeforeunload = function(e) {
$("#div").load("script.php");
I have been having a strange problem with an external javascript file function skipping over windows.location. my program was supposed to take in information from forms then create validate it and after it was validated send it to a php file with get.
I simplified my code to look like
function validation(){
var alerting;//receives from forms commented out
alerting="";
var url="phpadd.php";//after this i would validate it and create the alert but all of that is commented out and irrelevant
if(alerting==""||alerting==null)
{
windows.location=url;
}
else
{
alert(alerting);
}
}
and it didn't work.
Here is the real funny thing
when I include an alert at the end after windows.location it calls the php file. When I don't it doesn't.
for instance
function validation(){
var alerting;//receives from forms commented out
alerting="";
var url="phpadd.php";//after this i would validate it and create the alert but all of that is commented out and irrelevant
if(alerting==""||alerting==null)
{//I also create the code here to put values In the url but I commented them all out so this is my effective code.
windows.location=url;
alert(url);
}
else
{
alert(alerting);
}
}
works but it has to print out the alert first. On the other hand when I don't have an alert after the windows.location call It doesn't work at all.(and I know it works with the alert because It is then redirected to the php file which I know works too). It doesn't have to be alert(url) either It could be alert anything really. in fact it did work with a while(1) loop done afterward but almost crashed the browser first. It's like it is leaving the function before it does what it is supposed to and forgetting about it.
I have tried it in firefox and in google chrome without either way working.
also if you can't find a way to do this. if you could give me a way to take in values from a form to javascript and then send valid values to a php file without windows.location(i've tried every other variant I have found also like: windows.location.href location.href location.assign(url))
I would appreciate it.
by the way The code I left out is not causing the problem because it is commented out where it doesn't work and in the one where it works that is irrelevant because it works it just puts up an alert I don't want.
You should be calling
window.location = url;
not
windows.location = url;