Category Archives: .NET

Invalid FORMATETC structure (Exception from HRESULT: 0x80040064 (DV_E_FORMATETC)) on Simple Windows Forms Drag-and-Drop Implementation

When creating a Windows Forms application in Visual Studio and implementing drag-and-drop you may encounter this exception during debugging if you drag outside your own application, even though the drag and drop operations complete successfully inside your application.

This may not be a bug, or even an error!  Things to try:

  1. Run the application executable directly from the debug folder, not in Visual Studio debug mode.
  2. Run in VS debug mode with your application directly over a window that can accept its drag content type.  Perform the drag directly from your application to the valid drop zone on the other application, passing over no other applications (including the desktop) or invalid drop zones.  For example, if you are using DataObject.SetText, place your application directly over the text area of a text editor that accepts dragging, e.g. WordPad.

In those two conditions, you probably won’t see the exception thrown and the drag-and-drop will succeed.

I think what’s happening here is that Visual Studio is being a little too aggressive in watching the Windows event messaging system.  Because of the way dragging works, these “first chance” COM exceptions will occur as the dragging mouse passes over targets that cannot accept the content stored in the DataObject.  If they have any drag-drop awareness, they will attempt a COM native “get” operation on the FORMATETC structure created when you initiated the drag in your application (you used the DataObject wrapper and injected it with DoDragDrop, but this is what you did in effect).  If the format doesn’t match any of the formats the dragged-over applications (including Windows Explorer, a.k.a. the desktop) accept, this exception is thrown.  It is then, typically, handled either by that application or Windows itself, for example by switching to the “um, not so much” cursor (circle with line through it).  Running outside of debug mode, or between two application that agree on format, it “just works” (dropping successfully in places it can, blocking the drop in places it can’t).  In debug mode, VS is telling you, “hey, look, an exception, you could handle this if you wanted to,” but in most cases you’ll just let the OS or other applications handle it.

Bottom line: don’t sweat this one too much if your application runs okay outside the debugger and in the controlled debugging conditions described above.

Here’s an article that is the closest thing I could find to an official explanation.

Testing a .NET .asmx Web Service from LINQPad

Great post here about using the Visual Studio Command Prompt tools to pull the WSDL from a .NET .asmx (traditional, non-WCF) web service and compile a standalone class library which encapsulates the interface.  Basically, run a Visual Studio prompt, switch to a writable directory and run these two commands:

Convert WSDL to service reference .cs classes:

wsdl http://z.com/MyService.asmx

That will create classes in the global namespace and name class file based on the service URL.

Alternately, you can add a namespace and control the name of the output file:

wsdl http://z.com/MyService.asmx /n:MyServiceNamespace /o:MyService.cs

Compile into a class library:

csc /t:library MyService.cs

Then in LINQPad add a reference to the new .dll and the System.Web.Services .NET library.

Then you can write this in LinqPAD:

// create an instance of the service 
var service = new MyService();

// Or namespace version
var service2 = new MyServiceNamespace.MyService();
// invoke a web method and dump the results
service.MyOperation().Dump();

 

Visual Studio 2010 SP1 Slow to Start with “Loading toolbox content” Status

I still install VS2010 on all new machines for a number of reasons.  It seems that inevitably over the course of the life of the install I will eventually run into a problem where Visual Studio becomes slow to start, getting “stuck” for many seconds with this message in the status bar:

Loading toolbox content from package Microsoft.VisualStudio.IDE.Toolbox.ControlInstaller.ToolboxInstallerPackage ‘{2C98B35-07DA-45F1-96A3-BE55D91C8D7A}’

I initially theorized this had something to do with the Telerik control suite updating (via its outside “Control Panel” installer), but even completely uninstalling that didn’t solve it.  Since I keep doing a Google search to remember the real solution, I wanted to permalink the answer.  Basically:

  1. Close all instances of Visual Studio
  2. Back up registry (regedit, File|Export, Export Range: All)
  3. Delete registry key: [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Packages\{2c298b35-07da-45f1-96a3-be55d91c8d7a}] (I also back up the specific key I’m deleting before I do it, just in case I click the wrong one)
  4. Navigate to C:\Users\WindowsUserAccount\AppData\Local\Microsoft\VisualStudio\10.0\
  5. Move toolbox*.tbd (typically four files) out of this folder and to a backup location:
  6. Restart Visual Studio

The toolbox*.tbd files will be immediately recreated on launch, probably at a much smaller size.  After the first launch, during which the toolbox is being rebuilt, Visual Studio should start much more quickly.

 

Invalid Viewstate errors in ScriptResource.axd and WebResource.axd

I’ve done the requisite google searching on this one and can’t find a solution, so I’m posting about it in case anyone has an answer…

The basic problem is, I have an ASP.NET Dynamic Data web site that is experiencing occassional “Invalid viewstate errors” in the ScriptResource.axd or WebResource.axd javascript includes on the page. In almost all cases these are due to the URL of the include being corrupted with HTML or other text from the page. That is, instead of the normal “d” and “t” parameters in the querystring, I see something like this (as reported by my custom error handler in global.asax, which emails me a report for every Application_Error event):

http://domain-omitted/ScriptResource.axd?d=w0PmGeT7CMNAKpp-4k5pBNkf0bD1315QQFyhtn4142pWyyhkp5lhqQR6XcoT1lgNSX5Cdw8Q6uPcgDBOu4CSX-e3-cB38lN5S211HGUect<span class=

Querystring:
d=w0PmGeT7CMNAKpp-4k5pBNkf0bD1315QQFyhtn4142pWyyhkp5lhqQR6XcoT1lgNSX5Cdw8Q6uPcgDBOu4CSX-e3-cB38lN5S211HGUect%3cspan+class%3d

I have not been able to replicate this in testing, but in the field, where we have the application running exclusively on IE8 clients, we are seeing this behavior. I’ve read that this could have something to do with IE8’s parsing engine (Trident/4.0). I’ve validated my page using w3c (document type: XHTML 1.0 Transitional). There are a couple of attribute validations I can’t solve, but they’re for stuff like border=”0″ in something generated by the .NET platform (which isn’t actually sending border=”0″ but rather ‘style=”border-width:0px;”‘ as part of an asp:Button… more weirdness). I’ve made sure that all my local javascript is enclosed in XML data blocks as was suggested by some of the forum posts on this topic.

Server is up to date with Windows Server 2003 Standard x64, .NET Framework 3.5 SP1 with family updates installed.

Anyone have any further suggestions?

Copy a SQL Record with LINQ Using Object Shallow Copy

I wish I had kept my reference material on this, so if anyone recognizes borrowed code here, please let me know…

The basic idea is, I needed to “copy” a SQL record within the same table, avoiding some fields. With SQL this could be accomplished with something like:

INSERT INTO ShippingInfo (Name,Value) SELECT Name,Value FROM ShippingInfo where id=5

But imagine there are 20 fields or so. I couldn’t find a native way to do this with LINQ. What I came up with is an object shallow copy with the ability to punch out (omit) fields by name. Here’s the method:

public static class AnyObject<t> where T : class, new()
{
    public static T ShallowCopy(T item)
    {
        return ShallowCopy(item, "");
    }
    
    public static T ShallowCopy(T item, string OmitPropeties)
    {
        if (item == null)
        {
            return null;
        }
        T newItem = new T();
        foreach (System.Reflection.PropertyInfo prop in item.GetType().GetProperties())
        {
            if ((prop.PropertyType.IsValueType || prop.PropertyType.Name == "String") && 
                !prop.PropertyType.Name.StartsWith("EntitySet") &&
                !("|"+OmitPropeties+"|").ToLower().Contains("|"+prop.Name.ToLower()+"|"))
            {
                System.Reflection.PropertyInfo prop2 = item.GetType().GetProperty(prop.Name);
                prop2.SetValue(newItem, prop.GetValue(item, null), null);
            }
        }
        return newItem;
    }
}

Then you call it like…

// get the source record
ShippingInfo TempShipping;
TempShipping = (from s in db.ShippingInfos 
          where s.Id == tempShippingId select s).FirstOrDefault();

// shallow copy the object
ShippingInfo NewShipping = Helpers.AnyObject<shippinginfo>.ShallowCopy(TempShipping, 
                                              "Id|ModifiedBy|ModifiedTime");

// override some copied fields
NewShipping.CreatedBy = PageContext.UserId;
NewShipping.CreatedTime = DateTime.Now;

// insert it
db.ShippingInfos.InsertOnSubmit(NewShipping);
db.SubmitChanges();

Returning a Strongly-Type IEnumerable from a SQL Stored Procedure Using LINQ to SQL

This is surprisingly difficult, but there’s a relatively robust way to do it:

Create your stored procedure
Create a view that mimics the return signature of the stored procedure
In the model (.dbml), import both the stored procedure and view
Set the “Return Type” property of the stored procedure Data Function to the view type
In code, use the .ToList() method of the stored procedure function of the model and cast it to an IEnumerable of the view type, for example:

DBDataContext db = new DBDataContext();
IEnumerable<vwUspEventCalendarResultSet> CalendarResults = db.uspEventCalendar(CustomerId, StartDate, EndDate, DataStartDate, DataEndDate).ToList();

One thing to be careful of is if your stored procedure might return null values in integer key columns you may have to ISNULL them to 0 or some other meaningful value (in the stored procedure) since LINQ to SQL does not pick up a nullable int type from the view signature.

Here are the code bits to back this up…

View:

SELECT     dbo.AllDates.TheDate, dbo.Events.Id, dbo.Events.Name, dbo.Events.Description, dbo.Events.Url, dbo.Events.CustomerId, dbo.Events.TeamId, 
                      dbo.Events.ShowCityId, dbo.Events.EventStartDate, dbo.Events.EventEndDate, dbo.Events.EventMoveInDate, dbo.Events.EventMoveOutDate, 
                      dbo.Events.EventAddressId, dbo.Events.InventoryPullDate, dbo.Events.InventoryShipDate, dbo.Events.InventoryReturnDate, 
                      dbo.Events.InventoryAvailableDate, dbo.Events.EventShippingInfoId, dbo.Events.EventReturnAddressId, dbo.Events.EventAttendance, 
                      dbo.Events.BoothNumber, dbo.Events.BoothSize, dbo.Events.CeilingHeight, dbo.Events.BoothAttendance, dbo.Events.LeadsCaptured, 
                      dbo.Events.CreatedBy, dbo.Events.CreatedTime, dbo.Events.ModifiedBy, dbo.Events.ModifiedTime, dbo.Events.Deleted, dbo.Events.Active, 
                      dbo.Events.Notes
FROM         dbo.Events INNER JOIN
                      dbo.AllDates ON dbo.Events.EventStartDate = dbo.AllDates.TheDate

Stored Procedure:

ALTER PROCEDURE [dbo].[uspEventCalendar] 
	-- Add the parameters for the stored procedure here
	@CustomerId int = 0, 
	@StartDate datetime = null,
	@EndDate datetime = null,
	@DataStartDate datetime = null,
	@DataEndDate datetime = null
AS
BEGIN
	-- default to "this month"
	if @StartDate is null 
		SET @StartDate = cast(cast(DatePart(month,getdate()) as varchar) + '/1/' + cast (DatePart(year,getdate()) as varchar) as datetime)
	if @EndDate is null 
		SET @EndDate = dateadd(day,-1,dateadd(month,1,@StartDate))
	if @DataStartDate is null 
		SET @DataStartDate = @StartDate
	if @DataEndDate is null 
		SET @DataEndDate = @StartDate

	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	--SET NOCOUNT ON;
	--SELECT @StartDate,@EndDate
    -- Insert statements for procedure here
	
	SELECT CalendarDates.TheDate,
					ISNULL(EventCalendarEntries.Id,0) as Id, EventCalendarEntries.Name, EventCalendarEntries.Description, EventCalendarEntries.Url, EventCalendarEntries.CustomerId, 
                      EventCalendarEntries.TeamId, EventCalendarEntries.ShowCityId, EventCalendarEntries.EventStartDate, EventCalendarEntries.EventEndDate, EventCalendarEntries.EventMoveInDate, 
                      EventCalendarEntries.EventMoveOutDate, EventCalendarEntries.EventAddressId, EventCalendarEntries.InventoryPullDate, EventCalendarEntries.InventoryShipDate, 
                      EventCalendarEntries.InventoryReturnDate, EventCalendarEntries.InventoryAvailableDate, EventCalendarEntries.EventShippingInfoId, 
                      EventCalendarEntries.EventReturnAddressId, EventCalendarEntries.EventAttendance, EventCalendarEntries.BoothNumber, EventCalendarEntries.BoothSize, 
                      EventCalendarEntries.CeilingHeight, EventCalendarEntries.BoothAttendance, EventCalendarEntries.LeadsCaptured, EventCalendarEntries.CreatedBy, 
                      EventCalendarEntries.CreatedTime, EventCalendarEntries.ModifiedBy, EventCalendarEntries.ModifiedTime, EventCalendarEntries.Deleted, EventCalendarEntries.Active, 
                      EventCalendarEntries.Notes
		 FROM 
		(SELECT thedate from alldates where thedate BETWEEN @StartDate AND @EndDate) as CalendarDates LEFT OUTER JOIN
		(SELECT     EventDates.TheDate, EventsInRange.Id, EventsInRange.Name, EventsInRange.Description, EventsInRange.Url, EventsInRange.CustomerId, 
                      EventsInRange.TeamId, EventsInRange.ShowCityId, EventsInRange.EventStartDate, EventsInRange.EventEndDate, EventsInRange.EventMoveInDate, 
                      EventsInRange.EventMoveOutDate, EventsInRange.EventAddressId, EventsInRange.InventoryPullDate, EventsInRange.InventoryShipDate, 
                      EventsInRange.InventoryReturnDate, EventsInRange.InventoryAvailableDate, EventsInRange.EventShippingInfoId, 
                      EventsInRange.EventReturnAddressId, EventsInRange.EventAttendance, EventsInRange.BoothNumber, EventsInRange.BoothSize, 
                      EventsInRange.CeilingHeight, EventsInRange.BoothAttendance, EventsInRange.LeadsCaptured, EventsInRange.CreatedBy, 
                      EventsInRange.CreatedTime, EventsInRange.ModifiedBy, EventsInRange.ModifiedTime, EventsInRange.Deleted, EventsInRange.Active, 
                      EventsInRange.Notes
FROM         (SELECT     Id, Name, Description, Url, CustomerId, TeamId, ShowCityId, EventStartDate, EventEndDate, EventMoveInDate, EventMoveOutDate, 
                                              EventAddressId, InventoryPullDate, InventoryShipDate, InventoryReturnDate, InventoryAvailableDate, EventShippingInfoId, 
                                              EventReturnAddressId, EventAttendance, BoothNumber, BoothSize, CeilingHeight, BoothAttendance, LeadsCaptured, CreatedBy, 
                                              CreatedTime, ModifiedBy, ModifiedTime, Deleted, Active, Notes
                       FROM          Events
                       WHERE      (EventStartDate < = @DataEndDate) AND (EventEndDate >= @DataStartDate)) AS EventsInRange CROSS JOIN
                          (SELECT     TheDate
                            FROM          AllDates
                            WHERE      (TheDate BETWEEN @StartDate AND @EndDate)) AS EventDates
WHERE     (EventDates.TheDate BETWEEN EventsInRange.EventStartDate AND EventsInRange.EventEndDate)) EventCalendarEntries ON EventCalendarEntries.thedate = CalendarDates.thedate
END

Cast an ArrayList as IEnumerable (and Even IQueryable)

Again, not really sure why this works. Based on the original from here.

ArrayList students = GetStudents();
var query =
  from student in students.Cast()
  where student.Score > 80
  select new { student.ID, student.Name };

This is what I ended up with:

IQueryable dcs = 
(IQueryable)getChildControlsByType(ContactDetailsView, "System.Web.DynamicData.DynamicControl").Cast().AsQueryable();

Where the method getChildControlsByType is returning a generic ArrayList (but always of some kind of control). I guess the “Cast,” being an extension method, returns a typed IEnumerable, which can be turned into an IQueryable. Without the Cast, this code throws an exception.

LINQ Left Join with Where on Both Tables

I struggled with this one for a bit, but here’s how you do a LINQ “LEFT JOIN” equivalent while applying WHERE to both tables and maintaining an “all” relationship on the first table:

var TeamAllocations = from team in db.Teams
where team.CustomerId == PageContext.CustomerId
join a in
(from x in db.TeamAssetAllocations where x.AssetId == _AssetId select x) on team.Id equals a.TeamId into ta
from a in ta.DefaultIfEmpty()
select new { team.Id, team.Name, a.QuantityAllowed };

Personally, I don’t really get it, especially the “from a in ta.DefaultIfEmpty()” part, but whatever.