Friday, September 10, 2010

esri.layers.FeatureLayer is not a constructor

I received this error when using the ArcGIS JavaScript API. After doing some digging, it turned out that esri.layers.FeatureLayer was undefined (because the API was not loaded) when I was calling it.

Al the API examples show that dojo.addOnLoad should be used but I was using Ext.onReady (another JS API). This was causing the problem because when Ext.onReady was executed the AGS JS API was not loaded. I had to use dojo.addOnLoad to make sure that when I call esri.layers.FeatureLayer it is actually loaded.

Monday, September 6, 2010

JavaScript MVC

This article provides a great start to implement the MVC pattern. I would argue, however, that it can be improved because it doesn't match the definition of MVC from Wikipedia.

One of the problems with the article below is that the View knows about the Controller and the Model, when it should only know about the Model. Although there is at least another problem (hint: the controller doesn't know about the View), it is very easy to fix and you get a perfect implementation of JavaScript MVC.

I am doing this with ExtJS, I'll post some code after I get it to work.

Saturday, July 24, 2010

Handling SOAP fault exceptions from a WCF service

I was expecting that using catch (Exception ex) would catch the fault (it actually does) and it would be able to retrieve the fault information (not the case). This article showed me how to do it: use catch(FaultException ex).

Actually, I added catch clauses for both the generic exception and the fault exception. Don't forget the generic exception goes after the fault exception, otherwise the fault exception will never get caught.

Friday, July 23, 2010

ArcGIS Server Context Usage Timeout Interval error

An application that uses ArcObjects was throwing an exception and after some digging, everything was pointing to a problem on ArcGIS Server 9.3.1. The logs showed the error:

"The context has been automatically released because the context usage timeout interval has elapsed"

This KB article indicated that I had to modify the
EngineContextTimeout setting in the server.dat file. For some reason, the value in the file was 5, instead of the default 600. It would certainly be nice if the exceptions thrown by ArcGIS Server contained useful information.

Wednesday, July 14, 2010

Access the content page from the paster page

Have you ever wondered how to make the Content page respond to events in the master page? There is a great article here!

Wednesday, July 7, 2010

AJAX Panel vs. Page Methods

A coworker sent this article to me http://encosia.com/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/. I have used both technologies (check out ajax.net), and personally, I think Page Methods work great. Just keep in mind that if you use Page Methods, it's better to use Dojo or JQuery to access the DOM.

I have to say that my first thought was that Page Methods were kind of a hack, because they work around the Postback model. Maybe they're just the best of two worlds (client/server side). In my case, I prefer to use Page Methods when a website contains a lot of JavaScript code, and UpdatePanels when server side development is heavy.

,

Thursday, July 1, 2010

Converting an object array into a DataTable using LINQ

This is not possible with the current implementation of LINQ, but it is really easy to extend LINQ to support it. I found how to do it here http://blogs.msdn.com/b/aconrad/archive/2007/09/07/science-project.aspx. The method you need is CopyToDataTable, and the code that supports it is (copied from the link above):


public static class DataSetLinqOperators
{
public static DataTable CopyToDataTable(this IEnumerable source)
{
return new ObjectShredder().Shred(source, null, null);
}

public static DataTable CopyToDataTable(this IEnumerable source,
DataTable table, LoadOption? options)
{
return new ObjectShredder().Shred(source, table, options);
}

}

public class ObjectShredder
{
private FieldInfo[] _fi;
private PropertyInfo[] _pi;
private Dictionary _ordinalMap;
private Type _type;

public ObjectShredder()
{
_type = typeof(T);
_fi = _type.GetFields();
_pi = _type.GetProperties();
_ordinalMap = new Dictionary();
}

public DataTable Shred(IEnumerable source, DataTable table, LoadOption? options)
{
if (typeof(T).IsPrimitive)
{
return ShredPrimitive(source, table, options);
}


if (table == null)
{
table = new DataTable(typeof(T).Name);
}

// now see if need to extend datatable base on the type T + build ordinal map
table = ExtendTable(table, typeof(T));

table.BeginLoadData();
using (IEnumerator e = source.GetEnumerator())
{
while (e.MoveNext())
{
if (options != null)
{
table.LoadDataRow(ShredObject(table, e.Current), (LoadOption)options);
}
else
{
table.LoadDataRow(ShredObject(table, e.Current), true);
}
}
}
table.EndLoadData();
return table;
}

public DataTable ShredPrimitive(IEnumerable source, DataTable table, LoadOption? options)
{
if (table == null)
{
table = new DataTable(typeof(T).Name);
}

if (!table.Columns.Contains("Value"))
{
table.Columns.Add("Value", typeof(T));
}

table.BeginLoadData();
using (IEnumerator e = source.GetEnumerator())
{
Object[] values = new object[table.Columns.Count];
while (e.MoveNext())
{
values[table.Columns["Value"].Ordinal] = e.Current;

if (options != null)
{
table.LoadDataRow(values, (LoadOption)options);
}
else
{
table.LoadDataRow(values, true);
}
}
}
table.EndLoadData();
return table;
}

public DataTable ExtendTable(DataTable table, Type type)
{
// value is type derived from T, may need to extend table.
foreach (FieldInfo f in type.GetFields())
{
if (!_ordinalMap.ContainsKey(f.Name))
{
DataColumn dc = table.Columns.Contains(f.Name) ? table.Columns[f.Name]
: table.Columns.Add(f.Name, f.FieldType);
_ordinalMap.Add(f.Name, dc.Ordinal);
}
}
foreach (PropertyInfo p in type.GetProperties())
{
if (!_ordinalMap.ContainsKey(p.Name))
{
DataColumn dc = table.Columns.Contains(p.Name) ? table.Columns[p.Name]
: table.Columns.Add(p.Name, p.PropertyType);
_ordinalMap.Add(p.Name, dc.Ordinal);
}
}
return table;
}

public object[] ShredObject(DataTable table, T instance)
{

FieldInfo[] fi = _fi;
PropertyInfo[] pi = _pi;

if (instance.GetType() != typeof(T))
{
ExtendTable(table, instance.GetType());
fi = instance.GetType().GetFields();
pi = instance.GetType().GetProperties();
}

Object[] values = new object[table.Columns.Count];
foreach (FieldInfo f in fi)
{
values[_ordinalMap[f.Name]] = f.GetValue(instance);
}

foreach (PropertyInfo p in pi)
{
values[_ordinalMap[p.Name]] = p.GetValue(instance, null);
}
return values;
}
}

Thanks a lot to the author of this code!