If anyone else is struggling trying to get XDR working on IE8 Beta 2 (as I have been) note that the server no longer has to respond with the header:
XDomainRequestAllowed: 1
but instead should add the following header:
Access-Control-Allow-Origin: *
You can do this in ASP.NET with the following line of code:
context.Response.AppendHeader("Access-Control-Allow-Origin", "*" );
More details on the IE blog here.
Thanks to Will Thompson, a Business Intelligence Technical Specialist at Microsoft UK, for pointing out that my Geospatial Data Generator has had a bit of a fatal flaw since RC0 when they switched the Lat / Lon order in queries. I'm disappointed in you, dear reader, that you lacked the courage to bring this to my attention. Either that or you're not using it. Either way, I'm disappointed.
Anyway, I've fixed it. Not that you care. I use the word "fix" loosely as I noticed the Visualiser doesn't work with FireFox and I'm afraid the reasons why eluded me (seems to be throwing an exception in one of the VE functions). Fixing that will have to wait for another day - I have sessions to prepare!
Technorati Tags:
sql,
spatial
I'll be at FOWA tomorrow and Friday delivering (short) sessions on Silverlight and IE8. If you're there do pop by and say hello. One tip though - it really freaks me out when people walk up to me and say "Hello Mike" and I don't know them from Adam. Maybe "Hello Mike, I'm [Insert Name Here] and you don't know me yet" would be better? Otherwise I go into overdrive trying to figure out [a] if I *do* know them [b] where I met them [c] what their name is. I'm terrible with names....
Just a warning in case I look terribly pained when you say hello :-).
Technorati Tags:
fowa,
ie8,
silverlight
Eric and I have published the full set of resources links from yesterday's event on What's New in Visual Studio 2008 Sp1.
http://blogs.msdn.com/ukdevevents/archive/2008/10/02/2008-10-02-whats-new-in-visual-studio-2008-sp1.aspx
I spent many frustrating hours yesterday trying to get 2 demos to work for today's Visual Studio 2008 Sp1 event at TVP. What was very odd was that both demos (or similar) worked fine on MikeT's machine but neither worked on mine and in both cases the solution was very simple but not so obvious...
-
- Run it up and just get a set of axes with some "moving" shapes. Same executable works perfectly on MikeT's machines. A bit of debugging showed a System.DllNotFoundException on my machines which Mike wasn't seeing. Eventually (after checking all the DLLs that should be there were there) this triggered a thought. I'm running 64-bit. Mike runs 32-bit. MMm, what if the managed WPF application is trying to load an unmanaged 32-bit DLL? Corflags /32BIT+ set the 32-bit flag in the header and got me up and running. Phew.
-
Issue 2. Virtual PC cannot connect to host
- This was a killer. I've done this before. Many times. Why was it not working today of all days? Compared all my network settings, firewall rules etc with Mike. No differences yet his worked, mine didn't. After trying everything I could think of, checking log files (I'd never seen the Windows Firewall with Advanced Security app before - below) and essentially resorting to every desperate measure I could think of, I stopped the "Base Filtering Engine" (BFE) service temporarily (not recommended) and suddenly it worked. Hmm - the mention of IPsec in the description of BFE got me to thinking about corporate policies imposed on our boxes and the range of allowed IP addresses. I'd been using an address of 192.168.10.1 for the Loopback adapter on the host (binding to an adapter with an IP of 192.168.10.2 on the VPC). Changing this to 192.168.1.1 / 192.168.1.2 got me connectivity. Nothing to that point had even given me a clue what was blocking the traffic...
- [Update - I should clarify that I could ping the host with the IP address 192.168.10.1 but couldn't get any http traffic]
Well that was just me getting that off my chest. What a lot of wasted effort for very little return.
I posted a little while back about how much I liked jQuery so I was excited (not to mention surprised) to read that we're going to be shipping jQuery with Visual Studio in the near future. Not only that but we'll have a special annotated version of the library to get the best possible Intellisense support. How cool is that? There are a number of posts and demos floating around:
Scott's demo also uses the client templates work that's in the ASP.NET AJAX 4.0 CodePlex Preview 1 release.
Lots of great stuff for web developers in the pipeline!
We've released RC0 of Silverlight 2. This is intended as a developer only release - neither the Silverlight 1 nor Silverlight 2 Beta 2 plug-in will auto-update to this release. This is an opportunity to test your Silverlight 2 applications against RC0 to ensure they will be ready for final release. There is also a preview of SP1 for Expression Blend which targets Silverlight 2 RC0.
There is a full list of breaking changes between B2 and RC0, I've pulled out the contents list below as a summary:
- Important! Migrating Older Code to the Newer Release
- ContentPresenter now derives from FrameworkElement instead of Control
- Layout Rendering Slightly Changed
- Cross domain hosts of Silverlight must set the right MIME type for XAP (application/x-silverlight-app)
- Exceptions now thrown in HttpWebRequest.EndGetResponse()
- Font URI is Restricted to Assembly Resource
- Browser.HtmlElementCollection replaced with by Browser.ScriptObjectCollection
- Exceptions When Changing Some Properties on an Active Animation
- System.Windows.Controls.Extended.dll renamed to System.Windows.Controls.dll
- VisualStateManager Changes
- KeyDown Sent Synchronously
- MeasureOverride/ArrangeOverride on Canvas Now Sealed
- UriTypeConverter moved to System.dll
- HtmlPage.UnregisterScriptableObject Removed
- RenderingEventArgs Changes
- ContentPresenter and ContentControl Changes
- Removal of FileDialogFileInfo Type and OpenFileDialog.SelectedFile(s) Properties
- Removal of FullAccess Option on the ExternalCallersFromCrossDomain attribute in the Silverlight 2 application manifest
- KeyFrameCollection Changes
- Request stream must be closed before calling HttpWebRequest.BeginGetResponse()
- HtmlWindow references on Safari/Mac will no longer evaluate to true
- Address property removed from all WebClient EventArg classes
- Constructors Made Internal
- Exception type change for System.Xml exception type
- Cannot create classes in XAML that do not have accessible constructors
- Get AG_E_UNKNOWN_ERROR in Silverlight 2 but not in Silverlight 1
- Platform looks for generic.xaml as a resource at themes/generic.xaml
- HTTP Polling Duplex OM Changes and Reengineering
- Breaking change to Silverlight native hosting IXcpControl COM interface
- Content-Type is allowed on cross domain request by default
- Enforcing delegate type check when two delegate objects are combined
- Miscellaneous API Changes
All the relevant links and downloads are available on Silverlight.Net.
I've been wrestling with this for a little while now and wanted to try and get down some thoughts so at least I can refer to them in future. Others will hopefully find them useful as well. I'm not going to pre-amble with all the reasons for why we've had to do this in IE8 - there are plenty of other places to go for that background. I'm going to focus on the current state of play in IE8 Beta 2, what happens when you pull certain levers or the user pulls certain levers.
As I see it, there are a few inputs into this equation:
- Page Developer / Site Owner
- Valid DOCTYPE (or not)
- Meta tag in header (or not)
- HTTP Header (or not)
- User (ie the person using the browser)
- Compatibility View enabled (or not)
Let's tackle those one at a time (and because of the dependencies between these things it can be difficult to talk about them in isolation so cut me a bit of slack here):
- DOCTYPE
- All other things being equal the presence of a valid DOCTYPE switches the browser into "standards" mode. No DOCTYPE typically means "quirks" mode
- Meta tag in header
- Format: <meta http-equiv="X-UA-Compatible" content="IE=......."/>
- Allows the page developer to specify a particular layout mode (5, 7, EmulateIE7, 8, EmulateIE8, Edge)
- Affects a single page and trumps the HTTP header
- HTTP Header
- Format: X-UA-Compatible: IE=........
- Allows the site owner to specify a particular layout mode as per the Meta tag
- Affects all pages in the site and can be overridden by the Meta tag
- Compatibility View
- The user has the ability to enable "Compatibility View" for a domain (either by pressing the compatibility view button on a particular page or by enabling it through Compatibility View Settings")
- All other things being equal, this will switch the browser from IE8 Standards rendering mode to IE7 Standards rendering mode
- By default, all internet sites display in IE8 Standards Mode (Compatibility View off) while all intranet sites display in IE7 Standards Mode (Compatibility View on). This can be changed from the Tools -> Compatibility View Settings menu.
And clearly, there are a few outputs as well:
For a given set of inputs, IE8 Beta 2 will generate a specific set of outputs. I've collated a table which may help us understand what's going on. The vertical axis represents different Meta tag / HTTP header settings while the horizontal axis represents normal vs compatibility view for both valid and invalid / no DOCTYPEs:
What conclusions did I draw from this:
- Document / Layout Mode
- No Meta tag / Header
- If there is a valid DOCTYPE you will get the highest level of standards layout mode "available"
- ie either 8 in "normal" mode or 7 in "Compatibility View"
- Otherwise you get 5 (quirks mode)
- Meta tag / HTTP header
- Setting to 5/7/8 - that is guaranteed to be the layout mode IE8 will use
- Setting to EmulateIEx - you will get layout mode x for a valid DOCTYPE and quirks for invalid / no DOCTYPE
- ie the same behaviour as IEx
- User Agent String
- "Normal" mode - MSIE 8.0 always reported
- "Compatibility View" - MSIE 7.0 always reported
- Trident/4.0 always reported irrespective of "Compatibility View" setting
- Version Vector
- "Normal" mode - IE8 unless Meta tag / HTTP header overrides with 7 or EmulateIE7
- "Compatibility View" - IE7 unless Meta tag / HTTP header overrides with 8 or EmulateIE8
All the above was derived empirically using the following HTML page deployed to IIS7. I then simply changed the meta tag, HTTP headers or Compatibility View in the browser to create the matrix:
<!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>
<!-- <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" /> -->
<script type="text/javascript">
function ShowInfo() {
var docMode = document.documentMode;
var uaString = navigator.userAgent;
document.getElementById("info").innerHTML =
"Document Mode: " + docMode + "<br />" + "UA String: " + uaString;
}
</script>
</head>
<body onload="ShowInfo();">
<div id="info">
</div>
<div>
<!--[if IE]><p>You are using Internet Explorer.</p><![endif]-->
<![if !IE]><p>
You are not using an uplevel Internet Explorer version.</p>
<![endif]>
<!--[if IE 8]><p>Welcome to Internet Explorer 8!</p><![endif]-->
<!--[if !(IE 8)]><p>You are not using Internet Explorer8.</p><![endif]-->
<!--[if gte IE 7]><p>You are using IE 7 or greater.</p><![endif]-->
<!--[if (IE 5)]><p>You are using IE 5 (any version).</p><![endif]-->
<!--[if (gte IE 5.5)&(lt IE 7)]><p>You are using IE 5.5 or IE 6.</p><![endif]-->
<!--[if lt IE 5.5]><p>Please upgrade your version of Internet Explorer.</p><![endif]-->
<!--[if true]>You are using an <em>uplevel</em> browser.<![endif]-->
<!--[if false]>You are using a <em>downlevel</em> browser.<![endif]-->
<!--[if true]><![if IE 7]><p>This nested comment is displayed in IE 7.</p><![endif]><![endif]-->
</div>
</body>
</html>
There's some interesting support for browser and layout modes in the IE8 Developer Tools but I'll write a separate blog post on that. I've probably missed something out, over-simplified something or in some other way mis-represented what happens. In which case, let me know.
Mike's already blogged about this one so I'll simply highlight his post. I was building a simple music jukebox app to demo OpenFileDialog and IsolatedStorage. You can select some tracks to play and add them to a queue. The queue is maintained in isolated storage so queued tracks persist through a re-start. The app also uses a bit of WCF to resolve the URIs for the album cover image and the wma file.
All was well until I came to databind the images. This had worked when I'd set the image sources from code but when I started databinding them, no images appeared. Set the URI in XAML, all works fine. Via databinding, no image. The crux of the matter is that I was binding to a URI and there being no default converter for Uri to ImageSource (there is for String to ImageSource so setting in XAML works), it fails.
Read all about it in Mike's post.
It's been a bit quiet around here recently. I picked up some sort of chest infection, was confined to bed for a few days and still have the nasty cough to prove I'm not well. I thought I'd throw up a few posts about stuff I'd stumbled across in my incoherent state.
Firstly, Eric phoned me to ask a few questions about Dynamic Data and was having problems using it with Entity Framework. Specifically, he was running into issues with certain tables in the Northwind database (this reminds me of an issue with Linq to Sql and ADO.NET Data Services, we'll come back to that one). It turns out that the RTM release of Dynamic Data has trouble with certain types of relationship in EF data models so you might see something like this when you navigate to, for example, the Order_Details table:
System.Web.HttpException was unhandled by user code
Message="DataBinding: 'System.Web.UI.WebControls.EntityDataSourceWrapper' does not contain a property with the name 'Orders.OrderID'."
Source="System.Web"
ErrorCode=-2147467259
StackTrace:
at System.Web.UI.DataBinder.GetPropertyValue(Object container, String propName)
at System.Web.DynamicData.ModelProviders.TableProvider.EvaluateForeignKey(Object row, String foreignKeyName)
at System.Web.DynamicData.MetaForeignKeyColumn.GetForeignKeyValues(Object row)
at System.Web.DynamicData.MetaForeignKeyColumn.GetForeignKeyPath(String action, Object row, String path)
at System.Web.DynamicData.FieldTemplateUserControl.get_ForeignKeyPath()
at ForeignKeyField.GetNavigateUrl() in c:\Users\mormond\Desktop\WebSite1\DynamicData\FieldTemplates\ForeignKey.ascx.cs:line 48
at ASP.dynamicdata_fieldtemplates_foreignkey_ascx.__DataBindingHyperLink1(Object sender, EventArgs e) in c:\Users\mormond\Desktop\WebSite1\DynamicData\FieldTemplates\ForeignKey.ascx:line 3
at System.Web.UI.Control.OnDataBinding(EventArgs e)
at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
at System.Web.UI.Control.DataBind()
at System.Web.UI.Control.DataBindChildren()
Or something like this if you navigate the Product -> Order_Details relationship:
[InvalidOperationException: A property with name 'Products.ProductID' does not exist in metadata for entity type 'NorthwindModel.Order_Details'.]
System.Web.UI.WebControls.EntityDataSourceView.GenerateWhereClause(String& whereClause, ObjectParameter[]& whereParameters) +919
System.Web.UI.WebControls.EntityDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments, Creator qbConstructor) +306
System.Web.UI.WebControls.EntityDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +154
System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback) +19
System.Web.UI.WebControls.DataBoundControl.PerformSelect() +142
System.Web.UI.WebControls.BaseDataBoundControl.DataBind() +73
System.Web.UI.WebControls.GridView.DataBind() +4
System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound() +82
System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls() +72
System.Web.UI.Control.EnsureChildControls() +87
System.Web.UI.Control.PreRenderRecursiveInternal() +44
System.Web.UI.Control.PreRenderRecursiveInternal() +171
System.Web.UI.Control.PreRenderRecursiveInternal() +171
System.Web.UI.Control.PreRenderRecursiveInternal() +171
System.Web.UI.Control.PreRenderRecursiveInternal() +171
System.Web.UI.Control.PreRenderRecursiveInternal() +171
System.Web.UI.Control.PreRenderRecursiveInternal() +171
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +842
There's a fix posted on the CodePlex site which involves replacing the EF Data Model provider with a new version to workaround the problem. Full instructions are on the site but it boils down to including the new DLL in your bin folder (or adding a reference for a Web Application) and updating the call to model.RegisterContext() in global.asax.
Just gathering these together in one place before I go ahead and install myself...
There is also an update for WS2008 / Vista SP1 related to RealPlayer with IE8 Beta.
I've published the demo source for my Deep Zoom, MultiScaleTileSource and the Mandelbrot Set post to my site at http://mikeo.co.uk/cs/files/8/silverlight/entry43.aspx. I also made some changes to the colouring algorithm.
Instead of using the simple "Escape Time" algorithm it now uses a refinement knows as the "Normalized Iteration Count" algorithm which reduces the banding artifacts. The calculation is more expensive though so the zoom / pan responsiveness has dropped off a bit. However, it does look nice.
The image on the left is the result of zooming in on the tiny area highlighted by the arrow on the right.
I got quite a few comments on my post on Dynamically Loading ListView Templates so rather than trying to paste code into a comment in reply, I thought I'd paste an update here. Specific issues raised were problems when databinding without a DataSource control and problems on postback. Here's a new version that addresses both those issues:
<%@ Page Language="C#" CodeFile="Default.aspx.cs" Inherits="Default" %>
<!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 id="Head1" runat="server"></head>
<body>
<form id="form1" runat="server">
<asp:ListView ID="ListView1"
runat="server"
ItemPlaceholderID="MyLayout$itemPlaceholder"
OnLayoutCreated="ListView1_LayoutCreated">
</asp:ListView>
<asp:Button ID="Button1" runat="server" Text="I Do Postbacks" />
</form>
</body>
</html>
using System;
using System.Linq;
using System.Web.UI;
using System.Xml.Linq;
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
XDocument xdoc = XDocument.Load(Server.MapPath("~/XmlFile.xml"));
var query = from x in xdoc.Descendants("book")
select new { id = (string)x.Attribute("id") };
ListView1.DataSource = query;
ListView1.DataBind();
}
protected void ListView1_LayoutCreated(object sender, EventArgs e)
{
ListView1.LayoutTemplate = LoadTemplate("WebUserControl.ascx");
ListView1.ItemTemplate = LoadTemplate("WebUserControl2.ascx");
Control newLayoutContainer = new Control();
ListView1.LayoutTemplate.InstantiateIn(newLayoutContainer);
var userControl = newLayoutContainer.Controls[0];
userControl.ID = "MyLayout";
ListView1.Controls.Add(newLayoutContainer);
}
}
Hope that's useful.
Technorati Tags:
asp.net,
listview
There are some changes to Deep Zoom in Silverlight 2 Beta 2 including a new XML based file format and the ability to dynamically generate Deep Zoom images by creating your own MultiScaleTileSource. MultiScaleTileSource is an abstract class with one method to override - GetTileLayers().
protected abstract void GetTileLayers(
int tileLevel,
int tilePositionX,
int tilePositionY,
IList<Object> tileImageLayerSources
)
In other words Deep Zoom (or more accurately, a MultiScaleImage control) will come to me and say I want tile x,y at tile level z, what should it look like? And I need to respond with an image. How this actually works is not well documented and not very intuitive so I'm going to do my best to explain it here as I eventually figured it out with help from MikeT who has already written a blog post on this which provides a lot of good info. I'm going to try and explain it in simple terms that even I can understand.
Rather than setting the MultiScaleImage.Source property in XAML, if you want to use your own MultiScaleTileSource you need to set the Source property on the MultiScaleImage control like this:
this.msi.Source =
new DynamicDeepZoom.DynamicTileSource((int)Math.Pow(2,20), (int)Math.Pow(2,20),128,128);
Which says, I have an image of dimensions 2^20 x 2^20 and I can supply you with tiles of dimensions 128x128. ie up front I have to specify the dimension of my image (even though I don't *really* have an image as such, I'm going to be generating it on the fly and in my case, as I'm really generating a fractal, in theory I have infinite resolution but Deep Zoom doesn't work like that and I guess mine is something of a special case :-)). We'll come back and talk about tile dimensions at length in a moment.
My DynamicTileSource class is very similar to Mike's implementation:
public class DynamicTileSource : MultiScaleTileSource
{
public int tileWidth { get; set; }
public int tileHeight { get; set; }
public DynamicTileSource(int imageWidth, int imageHeight, int tileWidth, int tileHeight)
: base(imageWidth, imageHeight, tileWidth, tileHeight, 0)
{
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
}
protected override void GetTileLayers(int tileLevel, int tilePositionX, int tilePositionY,
System.Collections.Generic.IList<object> tileImageLayerSources)
{
string source =
string.Format(
"http://localhost:61753/DynamicDeepZoomWeb/handler.ashx?" +
"tileLevel={0}&tilePositionX={1}&tilePositionY={2}" +
"&tileWidth={3}&tileHeight={4}",
tileLevel,
tilePositionX, tilePositionY,
tileWidth, tileHeight);
Uri uri = new Uri(source, UriKind.Absolute);
tileImageLayerSources.Add(uri);
}
}
Mike, in his post, refers to "remoting requests" to serv