Error refreshing a web page

ieerror3

This is browser normal behavior. if the current page is a result of a postback (button clicked rather than a hyperlink), then to do a refresh the browser needs to post the data again (rerunning the page logic);
because so many sites failed to handle this on their purchase page, the browsers had to add this message to prevent double buys.

How to suppress this behavior
Browser displays that message only if page is result of submitting form with method POST. Which is how any buttom works in .NET you can get away with that if any action (i.e. button click) you will end with Response.Redirect somewere. Then it will me method “GET”.

Advertisements

UFrame: UpdatePanel and IFRAME combined

UFrame combines the goodness of UpdatePanel and IFRAME in a cross browser and cross platform solution. It allows a DIV to behave like an IFRAME loading content from any page either static or dynamic. It can load pages having both inline and external Javascript and CSS, just like an IFRAME. But unlike IFRAME, it loads the content within the main document and you can put any number of UFrame on your page without slowing down the browser. It supports ASP.NET postback nicely and you can have DataGrid or any other complex ASP.NET control within a UFrame. UFrame works perfectly with ASP.NET MVC making it an replacement for UpdatePanel. Best of all, UFrame is implemented 100% in Javascript making it a cross platform solution. As a result, you can use UFrame on ASP.NET, PHP, JSP or any other platform.

<div class=”UFrame” id=”UFrame1″ src=”SomePage.aspx?ID=UFrame1″ >
  <p>This should get replaced with content from Somepage.aspx</p>
</div>

Response from SomePage.aspx is rendered directly inside the UFrame. Here you see two UFrame’s are used to load the same SomePage.aspx as if they are loaded inside IFRAME. Another UFrame is used to load AnotherPage.aspx that shows photos from Flickr.

See it in action!
You can test UFrame from:
http://labs.dropthings.com/UFrame2005 – Visual Studio 2005 version, .NET 2.0 implementation showing regular ASP.NET 2.0 controls work as usual
http://labs.dropthings.com/UFrameMvc – Visual Studio 2008 version shows ASP.NET MVC works fine making UFrame an ultimate replacement for UpdatePanel

What is UFrame?
UFrame can load and host a page (ASP.NET, PHP or regular html) inside a DIV. Unlike IFRAME which loads the content inside a browser frame that has no relation with the main document, UFrame loads the content within the same document. Thus all the Javascripts, CSS on the main document flows through the loaded content. It’s just like UpdatePanel with IFRAME’s src attribute.

The features of UFrame are:

  • You can build regular ASP.NET/PHP/JSP/HTML page and make them behave as if they are fully AJAX enabled! Simple regular postback will work as if it’s an UpdatePanel, or simple hyperlinks will behave as if content is being loaded using AJAX.
  • Load any URL inside a DIV. It can be a PHP, ASP.NET, JSP or regular HTML page.
  • Just like IFRAME, you can set src property of DIVs and they are converted to UFrames when UFrame library loads.
  • Unlike IFRAME, it loads the content within the main document. So, main document’s CSS and Javascripts are available to the loaded content.
  • It allows you to build parts of a page as multiple fully independent pages.
  • Each page is built as standalone page. You can build, test and debug each small page independently and put them together on the main page using UFrames.
  • It loads and executes both inline and external scripts from loaded page. You can also render different scripts during UFrame postback.
  • All external scripts are loaded before the body content is set. And all inline scripts are executed when both external scripts and body has been loaded. This way the inline scripts execute when the body content is already available.
  • It loads both inline and external CSS.
  • It handles duplicates nicely. It does not load the same external Javascript or CSS twice.

Download the code

You can download latest version of UFrame along with the VS 2005 and VS 2008 (MVC) example projects from CodePlex: www.codeplex.com/uframe
Please go to the “Source Code” tab for the latest version. You are invited to join the project and improve it or fix bugs.

(Sursa: http://www.codeproject.com/KB/aspnet/uframe.aspx)

Build dynamic IFrames in ASP.NET

Create the HtmlGenericControl object that will eventually render as an iframe and specify whatever attributes this iframe will have:

// Create new iframe control
HtmlGenericControl searchFrame = new HtmlGenericControl(“iframe”);
searchFrame.ID = “searchFrame”;
searchFrame.Attributes.Add(“class”, “searchFrame”);
searchFrame.Attributes.Add(“frameborder”, “0”);

Then, you can add it to the PlaceHolder’s controls collection:

// Add it to the Controls collection of the PlaceHolder control
searchHolder.Controls.Add(searchFrame);

Finally,  add the PlaceHolder control into ascx document where I’d like the iframe to eventually be:

<div class=”searchContainer”>
   <asp: PlaceHolder id=”searchHolder” runat=”server” />
</div>

Now, an iframe will appear in the outputted HTML code where the placeholder once was. But more than that, since was used an ASP.NET control to actually create the iframe, the iframe will be named uniquely. We even know what it’ll be called: this.UniqueID + “_searchFrame”. This is beneficial since you can now reference that iframe by name throughout  JavaScript code and show it or hide it when necessary.

If you are going to use this on a secure page (using https), you’ll have to set the src of the iframe to something on the site, otherwise you get a warning (at least in IE) telling you that the page contains secure and non-secure items. I’ve seen people create a blank HTML page in the site and set the src to that. I set the src = “javascript:;”. That takes care of the warning. If you have inherited your user control from either a User Control or a Web Control, you can implement the marker interface INamingContainer and multiple instances of your controls will have a unique name. I’m not certain if you can do that with a user control, but I can’t think of any logical reason why you couldn’t.

(sursa: http://www.roryhansen.ca/2005/08/22/using-iframes-in-aspnet/)

DataTable – Serializable

Problems using an XML Web service that returns a DataTable
Symptons:
When you browse to the URL of an XML Web service that returns a DataTable from one of its Web methods, you may receive the following error message:
System.Data.DataRelation cannot be serialized because it does not have a default public constructor.
You may also see an error message similar to the following when you try to set a Web reference to this XML Web service in the Visual Studio .NET integrated development environment (IDE):
Internal Server Error. Unable to request “http://localhost/Webservice1/Service1.asmx?WSDL&#8221;. The server responded with error code “ProtocolError”.
With the .NET Framework 1.1 Service Pack 1 (SP1), you may receive the following error message:
System.NotSupportedException: Cannot serialize member System.ComponentModel.MarshalByValueComponent.Site of type System.ComponentModel.ISite because it is an interface.
You may also receive a blank page instead of any of these error messages if Show friendly HTTP error messages is enabled in Microsoft Internet Explorer. By default, the Show friendly HTTP error messages option is enabled.

If you try to add a Web reference to an XML Web service that returns a DataTable, you may receive the following error message:
The document at the url http:///vdir/service1.asmx was not recognized as a known document type.

Cause
The DataTable, DataRow, DataView, and DataViewManager objects cannot be serialized and cannot be returned from an XML Web service. To return less than a complete DataSet, you must copy the data that you want to return to a new DataSet.

Solution:
To resolve this issue, return a DataSet instead of a DataTable. DataSet objects can contain one or more DataTable objects.
Datatable is not returned through webservice beacause if you could, you could use for other non .net applications–and it a matter of policy I guess. But from the webservice prospective this should be considered a poor practice as well as from a service-orientation perspective. One of the tenets of service-orientation is that services share contract and schema … and nothing else. Passing a DataSet between Web services violates this tenet, and the result is that it will only work so long as both endpoints are always .NET platforms. (Microsoft products).
A better solution would be to pass entity data that is domain- or business-specific. Not a DataTable, but a set of data that has an actual XSD schema generated in the WSDL for the Web services so that it can be used by clients on any platform. (Microsoft doesnt want folks to use any other platform and so any support thereof is removed)

Make Your JavaScript Data Model Smarter With Object Events

As today’s web applications continue to evolve and get more complex, it has become a lot more commonplace to keep a data model present inside of your javascript. You would then write various widgets, modules, or whatever that would get their data from the model, rather than querying some other web service independently (and if you aren’t doing this, you should!). While centralizing all your data into a nice, organized model that different parts of your code can access, it’s often a challenge to integrate an efficient way to notify the code that depends on these models when the stored data is updated. Lucky for us, Ryan Johnson has created a surprisingly small library that will allow our data model to notify anything that depends on it that it has updated (or loaded, or whatever you’d like in fact).

Before we dig in to the notifications, let’s do a little work to set up an example and some assumptions we’ll be operating under for the sake of this article. First, as prototype is my weapon of choice, that’s what we’ll be using. We’ll also be using prototype as Object.Event uses it as well! Now, let’s pretend that we have a website that has some social networking aspect of some kind. We want to display a short list of who’s currently online (say the 6 most recently active people) in some sort of side bar, and perhaps a count of the total members online in a footer element. Rather than having both these elements poll the server at some interval to update their information, let’s create a little data model that these areas can use instead.

Step 1 – Create a Data Model
For the sake of brevity, this will be stubbed out in a lot of places, but we’ll create enough functionality to get the concepts across.

var WhosOnlineSummary = Class.create(
{
initialize: function initialize()
{
this.totalOnlineUsers = 0;
this.whosOnline = new Hash();
this.loading = true;

// do our initial fetch
this.fetchUsers();

// set this up to poll for new data every thirty seconds…
this.dataPoller = new PeriodicalExecuter(function(pe)
{
this.fetchUsers();
}.bind(this), 30);
},

fetchUsers: function fetchUsers()
{
// this would probably do some other stuff too

new Ajax.Request(‘/your/data/service’,
{
onComplete: function(response)
{
this.update(response.responseText);
}.bind(this)
})
},

update: function update(data)
{
// and you’d have some sort of logic
// here to update the data… here’s a stub..

// I’m assuming the data returned is a JSON object here…

if(‘totalOnlineUsers’ in data)
{
this.totalOnlineUsers = data.totalOnlineUsers;
}

// and update our “who’s online” stuff…
if(‘onlineUsers’ in data)
{
// simple way to refresh, just kill the current list 🙂
this.whosOnline = new Hash();

// pretend online users is an array of json objects here…
// [ { id: userId, name: username, etc.}, {…}, … ]
data.onlineUsers.each(function(user)
{
this.whosOnline.set(user.id, user);
}.bind(this));
}

if(this.loading)
{
this.loading = false;
}
}
});

// get this globally namespaced… we’ll just declare it here for
// the sake of keeping things easy… you probably shouldn’t do
// this in real life 😉
var whosOnline = ”;

Event.observe(window, ‘load’, function() {
whosOnline = new WhosOnlineSummary();
});
OK, as you can see, we’ve got a very simple data model that updates itself every thirty seconds, and that our other “widgets” can easily tap into for their information. I’m not going to write these widgets out to any great extent, but I will create a small stub for the total online users functionality to help us out here.

Step 2 – Create Some Widgets
Now that we have a model, let’s start leveraging it to do something meaningful. As I just mentioned, this is only a stub, but it should give you a nice idea of where we’re going…

var TotalOnlineUsers = Class.create(
{
initialize: function(element)
{
this.domElement = element;

// any other useful variables could go here…

this.parseOnlineUsers();
},

parseOnlineUsers: function parseOnlineUsers()
{
// nice and simple 😉
this.domElement.update(‘Currently ‘ + whosOnline.totalOnlineUsers + ‘ users online’);
}
});

And now we’re essentially ready to do some fun stuff. As you can see, all this looks nice, but our TotalOnlineUsers widget has no way of knowing when it needs to update the display, as there’s no way to know when the data model has changed. Enter Object.Event…

Step 3 – Make Your Data Model Smart
So, we need to get our data model publishing events that our widgets can listen for. This is actually pretty darn simple since all the heavy lifting has been done for us. Let’s go ahead and leverage the power of Object.Event (I’ll provide download links at the end of this article). The first thing we need to do is provide the data model with the “event” functionality. This is a simple one-liner that we can put right after our class declaration. It looks like this:


if(this.loading)
{
this.loading = false;
}
}
});

Object.Event.extend(WhosOnlineSummary);

That’s it! Now, all that remains for us to do is to create events inside this object that can be observed (we’ll cover the actual observing shortly). This is done through simple additions of “notify” functions. Since we’ve extended our data model class, this is also a cinch. I’ll modify the update function to include two “events”:


update: function update(data)
{
// and you’d have some sort of logic
// here to update the data… here’s a stub..

// I’m assuming the data returned is a JSON object here…

if(‘totalOnlineUsers’ in data)
{
this.totalOnlineUsers = data.totalOnlineUsers;
}

// and update our “who’s online” stuff…
if(‘onlineUsers’ in data)
{
// simple way to refresh, just kill the current list 🙂
this.whosOnline = new Hash();

// pretend online users is an array of json objects here…
// [ { id: userId, name: username, etc.}, {…}, … ]
data.onlineUsers.each(function(user)
{
this.whosOnline.set(user.id, user);
}.bind(this));
}

if(this.loading)
{
this.loading = false;
this.notify(‘whosOnlineLoaded’);
}

this.notify(‘whosOnlineUpdate’);
}
…As you can see, we can create any custom events that we want, and we can name them whatever we want. Pretty cool stuff, huh? So, there’s only one thing that remains, and that’s making our widget listen for these events.

Step 4 – Make our Widgets Listen for Events
You’ll notice I created two events in our data model, but we’re only going to use one for this example. Let’s get right to it, as there’s no real need for explanation here…

var TotalOnlineUsers = Class.create(
{
initialize: function(element)
{
this.domElement = element;

// any other useful variables could go here…

// watch for updates from the data model
whoseOnline.observe(‘whosOnlineUpdate’, function()
{
this.parseOnlineUsers()
}.bind(this));

this.parseOnlineUsers();
},

parseOnlineUsers: function parseOnlineUsers()
{
// nice and simple 😉
this.domElement.update(‘Currently ‘ + whosOnline.totalOnlineUsers + ‘ users online’);
}
});

Wrapping Up
Hopefully, you can see the huge benefit of approaching your apps this way, and integrating Object.Event. If you’ll remember, our so-called page also has a who’s online list. You could create a widget that also observes the “whosOnlineUpdate” event, so it will update whenever the model changes as well. We’ve effectively made the load on the server smaller, since we’ve only got one thing calling our data service, instead of 2 (in this case, but I’m sure there are many practical applications that would have many more somewhat redundant calls). We also know that our presentation will be in sync across all the different elements on this page, which leads to a much slicker user experience. The best part of all this? We’ve made very, very small tweaks to our code, and they were very unobtrusive as well. Enjoy, and thank Ryan for his bad-ass javascript kung-fu if you’ve got a moment!

(sursa: www.webmonkey.com)
alte resurse:
http://livepipe.net/core>Object.Event – Created by Ryan Johnson
Prototype Framework

Ajax Page Methods Will Always Have Session

In my ongoing process of performance optimization, I noticed the use of an ASP.NET Ajax Page Method in a certain page. It looked something like this:

[WebMethod(true)]

public static bool HasDataBeenUpdated(DateTime lastUpdateTime)

{

   //Checks something in the cache against this date

   //….

}

Page methods are a way to Ajax-ly call a static method on the page, instead of creating a specific web-service for this. As you can see, this method was marked with [WebMethod(true)]. This property is usually used in web services, but ASP.NET Ajax employs it for page-methods as well (it is rather the same thing). The constructor we used for this attribute is defined like this:

public WebMethodAttribute (

   bool enableSession

)

That means that passing true will cause ASP.NET to load the Session for this request, making it more costly. The HasDataBeenUpdated method can be changed so it won’t need the Session. Since it was being called every 5 seconds from the client, it had to be very efficient. The changes were made, and was able to turn off Session by using [WebMethod(false)]. Thing is, it didn’t really get turned off. The request was still slower than it should have been. Apparently, if you use a page-method, Session will be loaded even if you explicitly pass false to the enableSession parameter.

The documentation doesn’t mention this, but the example there is about Session access, so that should have probably tipped me off. This issue seems rather weird to me. I understand that maybe the defaults should change (web-services methods default to no-session) when you write [WebMethod] and nothing else. Maybe. But since I’m explicitly asking for no-Session mode, the result is surprising.
If they wanted page-methods to behave differently from web-service methods, they should have used a different attribute for it. Anyway, the solution is simple: I ended up moving the method to an .asmx web-service and calling it instead.

(sursa: http://blogs.microsoft.co.il/blogs/)

Using PageMethods to access Session data

There are two C# methods in the page. One overrides the the OnLoad method and stores a value in session state for demonstration purposes. The other is a static method decorated with the WebMethod attribute that can be called from JavaScript. It retrieves the value for the given key from session state. Currently, only static methods are callable use the PageMethods object in the browser.
In the JavaScript code, there is a pageLoad method which will be called automatically by the ASP.NET AJAX script library. The PageMethods object is used to invoke the method on the server. It provides callbacks for success and error. The success callback just displays the value retrieved from session state on the server.

 <%@ Import Namespace=”System.Web.Services” %>
<script runat=”server” language=”C#”>
protected override void OnLoad(EventArgs e) {
    HttpContext.Current.Session[“foo”] = “bar”;
}

[WebMethod]
public static string Session(string key) {
    return (string)HttpContext.Current.Session[key];
}
</script>script type=”text/javascript”>
function
pageLoad(sender, arg) {
    PageMethods.Session(
“foo”, OnCallComplete, OnCallError);
}
function OnCallComplete(result, userContext, methodName) {
    alert(result);
}
function OnCallError(error, userContext, methodName) {
    if(error !== null) {
        alert(error.get_message());
    }
}
</script>
<
form runat=”server”>
<asp:scriptmanager runat=”server” id=”scriptmanager” />
</
form>

(sursa: http://blogs.msdn.com/mattgi)