Showing posts with label Exception. Show all posts
Showing posts with label Exception. Show all posts

Thursday, November 8, 2012

VS2010: “The project type is not supported by this installation.”

This post was moved to my real blog: VS2010: “The project type is not supported by this installation.”

Tuesday, April 12, 2011

LINQ and WCF

I am sure that for most of you this will be back to the basics but I had this exception yesterday:

Type 'System.Linq.Enumerable+WhereSelectEnumerableIterator`2[ClassA,ServiceClassA]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.  See the Microsoft .NET Framework documentation for other supported types.

That I couldn’t find a solution for in Google, though I solved it fairly easily.

 

The situation was this I had a service lets just call it ClassService with this method:

  1. [ServiceContract]
  2. public interface IClassService
  3. {
  4.     void SomeMethod(ServiceEntity entity);
  5. }

ServiceEntity was defined as:

  1. [DataContract]
  2. public class ServiceEntity
  3. {
  4.     [DataMember]
  5.     public IEnumerable<ServiceClassA> As { get; set; }
  6. }
  7.  
  8. [DataContract]
  9. public class ServiceClassA { }

 

Now the client looked something like:

  1. public IClassService ClassService { get; set; }
  2.  
  3. public void CallService(IEnumerable<ClassA> list)
  4. {
  5.     ClassService.SomeMethod(new ServiceEntity{As = list.Select(Convert)});
  6. }
  7.  
  8. private ServiceClassA Convert(ClassA a)
  9. {
  10.     return new ServiceClassA();
  11. }

(just imagine the constructor initializing the ClassService)

Do you see the mistake?

The problem comes from the line:

  1. ClassService.SomeMethod(new ServiceEntity{As = list.Select(Convert)});

Or most specifically:

  1. new ServiceEntity{As = list.Select(Convert)}

The problem is that LINQ doesn’t actually executes this query. It wait until you try to do something with it like converting it to a list or try using one of the entities. The IEnumrable actually has the type of 'System.Linq.Enumerable+WhereSelectEnumerableIterator`2[ClassA,ServiceClassA]' which is not a WCF DataCotract.

 

The solution is fairly easy:

  1. ClassService.SomeMethod(new ServiceEntity{As = list.Select(Convert).ToList()});

Just use the LINQ query by creating a List out of it is enough.

 

Keywords: LINQ, WCF, Exception

IceRocket Tags: ,,

Wednesday, March 16, 2011

File GeoDatabase: Getting the Workspace

I have created FileWorkspaceUtils that inherits from WorkspaceUtils, it adds the functions GetRows and GetFeatures that return the raw IRow and IFeature data. In WorkspaceUtils I preferred that the low level programmer won’t even know he has something called IRow or IFeature.

  1. public class FileWorkspaceUtils:WorkspaceUtils
  2. {
  3.     public FileWorkspaceUtils(IFeatureWorkspace workspace) : base(workspace)
  4.     {
  5.     }
  6.  
  7.     public List<IRow> GetRows(string tableName)
  8.     {
  9.         var result = new List<IRow>();
  10.         DoActionOnSelectRows(tableName, null, row => result.Add(row.Clone()));
  11.         return result;
  12.     }
  13.  
  14.     public List<IFeature> GetFeatures(string layerName)
  15.     {
  16.         var result = new List<IFeature>();
  17.         DoActionOnSelectFeatures(layerName, null, feature => result.Add(feature.Clone()));
  18.         return result;
  19.     }
  20. }

//TODO: Post on the wonder of Extension Methods (row.Clone())

I have added code to WorkspaceProvider so that it will return the FileWorkspaceUtils (independent of File/Personal GeoDatabase):

  1. private const string PersonalGeoDatabaseFileExtension = ".MDB";
  2. private const string FileGeoDatabaseFileExtension = ".GDB";
  3.  
  4. /// <summary>
  5. /// Get a File WorkspaceUtils for Personal and File GeoDatabase
  6. /// </summary>
  7. /// <param name="filePath"></param>
  8. /// <returns></returns>
  9. public FileWorkspaceUtils GetFileWorkspace(string filePath)
  10. {
  11.     var extension = (Path.GetExtension(filePath) ?? String.Empty).ToUpper();
  12.     if (extension.CompareTo(PersonalGeoDatabaseFileExtension) == 0)
  13.         return CreatePersonalGeoDatabaseWorkspace(filePath);
  14.     if (extension.CompareTo(FileGeoDatabaseFileExtension) == 0)
  15.         return CreateFileGeoDatabaseWorkspace(filePath);
  16.  
  17.     throw new NotImplementedException("The only supported file types are mdb and gdb. Not: " + extension);
  18. }
  19.  
  20. private FileWorkspaceUtils CreatePersonalGeoDatabaseWorkspace(string filePath)
  21. {
  22.     AccessWorkspaceFactory workspaceFactory = new AccessWorkspaceFactoryClass();
  23.  
  24.     var workspace = workspaceFactory.OpenFromFile(filePath, 0);
  25.     return new FileWorkspaceUtils((IFeatureWorkspace)workspace);
  26. }
  27.  
  28. private FileWorkspaceUtils CreateFileGeoDatabaseWorkspace(string filePath)
  29. {
  30.     FileGDBWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactoryClass();
  31.  
  32.     var workspace = workspaceFactory.OpenFromFile(filePath, 0);
  33.     return new FileWorkspaceUtils((IFeatureWorkspace)workspace);
  34. }

The only problem is it doesn’t work, my unit tests that just check GetFileWorkspace throws a COMException:

Test method CompanyName.GIS.Core.Esri.Tests.WorkspaceProviderTests.GetWorkspace_ValidPersonalGeoDB_GetFileWorkspaceUtils threw exception:
System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80040228
at ESRI.ArcGIS.DataSourcesGDB.AccessWorkspaceFactoryClass.OpenFromFile(String fileName, Int32 hWnd)
at Core.Esri.WorkspaceProvider.CreatePersonalGeoDatabaseWorkspace(String filePath) in WorkspaceProvider.cs: line 200
at Core.Esri.WorkspaceProvider.GetFileWorkspace(String filePath) in WorkspaceProvider.cs: line 189
at Core.Esri.Tests.WorkspaceProviderTests.GetWorkspace_ValidPersonalGeoDB_GetFileWorkspaceUtils() in WorkspaceProviderTests.cs: line 55

The problem was caused by Licensing, I changed EsriInitilization to contained the old style licensing as well (the one with IAoInitialize, the new stuff is using RuntimeManager):

All my unit tests (427 tests) pass, so it works…

  1. public class EsriInitilization
  2. {
  3.     private static bool _isStarted = false;
  4.  
  5.     public static void Start()
  6.     {
  7.         if (_isStarted)
  8.             return;
  9.  
  10.         if (!Initialize(ProductCode.Server, esriLicenseProductCode.esriLicenseProductCodeArcServer))
  11.         {
  12.             if(!Initialize(ProductCode.Engine, esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB))
  13.             {
  14.                 throw new ApplicationException(
  15.                     "Unable to bind to ArcGIS license Server nor to Engine. Please check your licenses.");
  16.             }
  17.         }
  18.         _isStarted = true;
  19.     }
  20.  
  21.     private static bool Initialize(ProductCode product, esriLicenseProductCode esriLicenseProduct)
  22.     {
  23.         if (RuntimeManager.Bind(product))
  24.         {
  25.             IAoInitialize aoInit = new AoInitializeClass();
  26.             aoInit.Initialize(esriLicenseProduct);
  27.             return true;
  28.         }
  29.         return false;
  30.     }
  31. }

That still throw an exception, this time simply because IFeature refused to be cloned – though it implemented ESRI’s IClone interface. The error I got was:

//TODO: Write error and new code

//TODO: Post after writing about Extension Method (TODO above)

Resources:

Esri Forum: COM Exception 0x80040228 When Opening a Personal Geodatabase

 

Keywords: License, COM, exception, IWorkspace, engine, Server, ArcGis, ESRI, Unit tests, MDB, GDB

Monday, January 10, 2011

Calling ArcGIS Server service model

Our application manages the process of installing a site that has CAD drawings that usually don't fit in the place that it is supposed to be. For the longest time someone in our organization used to go through the process of uploading the file to a file GeoDatabase => moving, rotating the lines till they fit in the map => dissolve the line to polyline => save the polyline in the DB. She doesn't want to do that anymore because of all the trouble in the location of the CAD.

For that reason we had to make the process a part of our application.

Uploading the CAD data to lines was relatively easy and is in the post - Working with CAD files in ArcObjects.

The next step was dissolving the polylines to one polyline, and that’s where the troubles started – there are no dissolve methods in ArcObjects (I even posted a question about that in their forums but got no answers).

So after some discussion in our team we decided to go with a Geoprocessor task. We added a model to the ArcGIS server that dissolves one table to another table.

The code is fairly simple (the base for it was taken from the interactive samples for ESRI's Silverlight API):

  1. private void LoadRawCadCompleted()
  2. {
  3.     var dissolveTask = new Geoprocessor(MapApplicationConfigWrapper.Instance.DissolveCadServiceUrl);
  4.     dissolveTask.CancelAsync();
  5.     dissolveTask.JobCompleted += DissolveTask_ExecuteCompleted;
  6.     dissolveTask.Failed += DissolveTask_Failed;
  7.     dissolveTask.SubmitJobAsync(new List<GPParameter>());
  8. }

 

But I got this error back:

{ESRI.ArcGIS.Client.Tasks.ServiceException: Execute operation is not allowed on this service.}

I have tried making the service synchronic – like this guy:

image

I even called did the clear cache thing – see "Clearing ArcGIS Server REST API Cache" Post.

This (of course) didn't work!

 

The problem was:

image

The model didn't run…

(It didn’t work because it used a connection file that was on the Model’s Designer computer but not on the ArcGis Server)

 

 

Well after the problem was solved (and I changed the Execution type back to asynchronous):

image

 

I used that code and got back:

-        jobInfoEventArgs    {ESRI.ArcGIS.Client.Tasks.JobInfoEventArgs}    ESRI.ArcGIS.Client.Tasks.JobInfoEventArgs
-        base    {ESRI.ArcGIS.Client.Tasks.JobInfoEventArgs}    ESRI.ArcGIS.Client.Tasks.TaskEventArgs {ESRI.ArcGIS.Client.Tasks.JobInfoEventArgs}
+        base    {ESRI.ArcGIS.Client.Tasks.JobInfoEventArgs}    System.EventArgs {ESRI.ArcGIS.Client.Tasks.JobInfoEventArgs}
        UserState    "j5fac49ec349241759b248eb20d9a716d"    object {string}
-        JobInfo    {ESRI.ArcGIS.Client.Tasks.JobInfo}    ESRI.ArcGIS.Client.Tasks.JobInfo
        JobId    "j5fac49ec349241759b248eb20d9a716d"    string
       JobStatus    esriJobSucceeded    ESRI.ArcGIS.Client.Tasks.esriJobStatus
-        Messages    Count = 3    System.Collections.Generic.List<ESRI.ArcGIS.Client.Tasks.GPMessage>
        Capacity    4    int
        Count    3    int
-        Static members       
+        Non-Public members       
+        Non-Public members   

               

Resources:

Interactive samples for ESRI's Silverlight API

ESRI forum - Error executing Geoprocessing Service in Silverlight

 

Keywords: ESRI, ArcGIS Server, ArcGIS Manager, Job, Dissolve, Silverlight

Silverlight ESRI App - IIS is dead–Error 5011

On the start of this week (2/1/20) our application in production started having troubles. And we didn’t know why but the IIS process from time to time just decided to quit.

In the EventViewer’s Application log we found:

An unhandled exception occurred and the process was terminated.

Application ID: /LM/W3SVC/1/ROOT/AppPool

Process ID: 1340

Exception: System.OutOfMemoryException

Message: Exception of type 'System.OutOfMemoryException' was thrown.

In the EventViewer’s System log we found:

A process serving application pool 'XAppPool' suffered a fatal communication error with the Windows Process Activation Service. The process id was '1976'. The data field contains the error number.

Something about the system message in TechNet.

Googled the system message and found on StackOverFlow, the advice there was to use IIS Debug Diagnostics tools but we have IIS 7 and this link doesn’t apply to it.

I and my team leader started studying how to read the trace and how to debug the failure.

We thought we found the solution because we found that an unknown someone changed a config value (at the start of the week) that is used in our Silverlight feature layer to check the layer for updates ( see post TODO) was far too low meaning that every second the server got 12*number of users requests that queried the layer status. And even though the server uses caching it was too much.

The WCF trace log has shown the Exception: System.ServiceModel.ProtocolException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 The number of bytes available is inconsistent with the HTTP Content-Length header.  There may have been a network error or the client may be sending invalid requests.

Googled and found this post. Hope it is the Anti Virus but we shall see tomorrow!

Well No AntiVirus was installed, bummer!

 

Went over the ArcGIS Server logs and found these lines (in C:\Program Files (x86)\ArcGIS\server\user\log):

<Msg time='2011-01-07T22:27:00' type='ERROR' code='10837' target='BaseLayers.MapServer' methodName='MapServer.QueryFeatureData2' machine='liveil-gtm' process='4048' thread='3564'>GeoDatabase Error :FDO error: -2147024890 [ScratchRecordSet].  The table was not found. [GDB_ReleaseInfo].  The table was not found. [GDB_Release].  The table was not found. [GDB_ReleaseInfo].  The table was not found. [GDB_Release].  The table was not found. [GDB_DBTune].  The table was not found. [GDB_ReleaseInfo].  The table was not found. [GDB_Release].  The table was not found. [GDB_ReleaseInfo].  The table was not found. [GDB_Release].  The table was not found. [GDB_DBTune].</Msg>
<Msg time='2011-01-07T22:27:00' type='ERROR' code='100005' target='BaseLayers.MapServer' methodName='MapServer.QueryFeatureData2' machine='liveil-gtm' process='4048' thread='3564' elapsed='0.95282'>Method failed.HRESULT = 0x80004005 : Unspecified error  .</Msg>


And this Error in the EventLog:

[15:01:38.201 GisModule] System.Runtime.InteropServices.COMException (0x80041538): Underlying DBMS error[Microsoft OLE DB Provider for SQL Server: Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.][DATABASE.GIS.LAYER]
   at ESRI.ArcGIS.Geodatabase.IFeature.Store()
   at Namespace.OnPeriodicUpdateRequest(PeriodicUpdateRequest request) in c:\Folder\App Module GIS\Source\Namespace\Module.OnPeriodicUpdateRequest.cs:line 51


Another thing we found was that the AppPool for our ArcGis server thread was using a lot of CPU (by simply looking at the Task Manager). And that the ArcSoc processes were also very high in CPU usage - ~30%.


At the end my team leader found the problem one of the IFeature.Store failed but an empty row was added to the DB (and since there was no primary key set on the table the next time it happened it again added an empty row). That table grew to a very large number of rows but almost all of them were empty so that in every request to the Server for the Layer (from our Silverlight application) the AppPool for the ArcGis Server worked and it made the ArcSoc processes work as well KILLING the server.

 

//TODO: post about our implementation of ESRI Silverlight API’s FeatureLayer

//TODO: write about enabling WCF trace log

//TODO: study how to troubleshot this kind of errors and post it here

//TODO: Reformat this post – it’s just erratic

Resources:

TechNet Error Event Id 5011

Silverlight Forums: HttpRequestTimedOutWithoutDetail

Keywords: fatal communication error, Windows Process Activation Service, IIS, Error, Event Id 5011, WAS, ProtocolException, Anti Virus, IFeature, Store, ArcSoc, AppPool, CPU, COMException

Tuesday, January 4, 2011

Simplify and the ArcEngine license

 

So I have tried to make my code simplify the IPolyline result I had by:

        public static IPolyline CreatePolyline(params MapPoint[] points)

        {

            IPolyline polyline = new PolylineClass() { SpatialReference = CreateWgsSpatialReference() };

 

            foreach (var point in points)

            {

                polyline.AddPoint(CreatePoint(point));

            }

            ((ITopologicalOperator)polyline).Simplify();

 

            return polyline;

        }

 

 

The Unit Test that test this part of code won't pass, a pop up pops up:

image

---------------------------

Initialization Error

---------------------------

The runtime application type must be specified before license initialization.

---------------------------

OK  

---------------------------

 

And the different frameworks for unit tests show the same kind of error:

Resharper shows that test as Aborted:

image

VSTS shows that test as Error:

image

image

I think this means that Simplify won't work with ArcEngine license but tell me what you think.

 

Rename Polyline layer

 

Why does it work?

You know that question?

For a long long time I had one test in DeploymentWorkspaceUtils that just didn't want to pass, it was called:

Deployment_RenameLayer_GeometryPolylineOldLayerHasData_GetData

 

The test was simple:

1.       Create a layer of type polyline

2.       Put a feature in the layer

3.       Rename the layer

4.       Get the data back from the renamed layer

I had two more tests identical to this test but with point and polygon data.

But in the part of renaming the layer I got the following error:

System.Runtime.InteropServices.COMException: The number of points is less than required for feature

 

Today I had some time and got back to this test, I thought to myself that since the error is of the number of points I figured the trouble was with reading the data.

My second thought was that I didn't clone the geometry returned into my entity, I placed a breakpoint in my entity and waited and waited some more…

Then I tried to slam my head to the wall – I didn't use entity in rename since I didn't have any entity.

I looked again and in the rename I simply used a List<IFeature>, than I thought about the most annoying Boolean in IWorkspace – IsRecycling mine was of course set to true.

Now the real question is why didn't the Polygon fail as well???

 

Then I thought to myself maybe the geometry in the DB for the polyline is not simplified lets try to simplify it! The result was the same old error => The number of points is less than required for feature

 

So I changed my test to be with two features in step 2 and added an assert that the geometry length (for IPolygon and IPolyline) is greater than zero. For the point I added an  assert on the X and Y of the point.

And still the point and the polygon tests pass, the polygon's length was ~40 which is to say greater than zero, WHY???

 

I decided to add a test that verifies that the 2 entities are different and now the point and polygon tests fail and the polyline test (still) throws an exception.

 

 

In the end I decided to just fix the damn test and try not to think logically with ESRI…

 

 

Stuck Database – the JOY!

I was playing with extending Fluent Migrator and wanted to check what was left in my DB after the last try.

Trying to open the tables sub folder gave me this error:

 

So I tried taking the DB offline and got stuck with:

image

Closing that window and trying to open the DB again got me:

image

So I have decided to go brutal, I opened Computer Management->Services and Applications->Services and stopped the SQL Server (MSSQLSERVER) service:

image

And then started it again (I like to give it a few second to relax then doing the restart).

Now reconnecting to the DB works.

 

But what about the bug that caused all of this?

I tried the test again, but this time tried to open the Tables folder at the same time:

image

The test is stuck on:

image

 

What I found out?

The test is stuck when trying to open a workspace to the SDE. But (this time) I don't blame ESRI because it seems the current connection to SQL doesn't allow any other connection – I can't even open SQL Server Management.

What I found in the code?

Fluent Migrator opens a connection and then begins a transaction – and closes it only when all the "StepUp"s are complete. While I want to open a SDE connection in the middle of that transaction – and get stuck doing it.