Friday 30 May 2008

Linq + Failed to set one or more properties on type

So I have had quite an interesting hour or so tracking down the following Linq error:


Failed to set one or more properties on type [namespace].EntityContexts.project. Ensure that the input values are valid and can be converted to the corresponding property types.


This was occurring whilst performing an update in a formview. Previously the form had been behaving properly, but this morning I added a new field to the database and updated the LinqtoSQL file. I also added a new databound field to my formview, however since this every time i tried to update the form it crashed out.


A few people have suggested to delete your LinqtoSQL file and readd, this didn't work for me, I even created a new page with just the datasource and formview for testing purposes.


The datasource was configured to select all from a table and had auto insert, update delete set. The formview was just generated.


It was at this point that I noticed the foreign key relationships I had setup were child entities in my entitycontext. This meant that my formview was generating databound controls for my lookup table etc. In my original page these didn't exist as I had manually removed them in sourceview.
So I again removed these controls within my new page and tried again, still no joy, I then wondered if removing them in Design view instead of Source had any impact, and it did. What was happening was my designer code file was not being updated upon rebuilding from the pages source view.


I then thought further on how to avoid this, my initial thoughts were upon inserting a LinqDataSource only select the columns you need, thus skipping the child entities, this would work for read only select data sources however to use auto generate insert and update you can't use select. If you try to do this then you get the following error:


LinqDataSource 'LinqDataSource1' does not support the Select property when the Delete, Insert or Update operations are enabled


There is a way around this though, although its not pretty and i think its a massive bodge but, insert your datasource and manually select the columns you need, create your formview. Then update the datasource, you are now able to turn on auto gen insert, update and delete. However the manual select still exists on your datasource so switch to source view and remove that.


You should then finds it all works...... Total bodge, I'd sooner just ensure i switch to Design mode to remove my extra fields, but hey everyone has there own way...

Tuesday 27 May 2008

JavaScript Library and File Loader

OK so tonight I was going to blog about adding paging to a repeater using Linq, however Google today announced that they are now hosting JS Libraries and I couldnt resist whipping together a webcontrol for use in my projects. So I have postponed that post until tomorrow or later on in the week.

JSLoader 2.0

A few months ago I released a fairly basic webcontrol that you could use to import JavaScript files into your .Net pages, it had fairly configurable options and ensured that the file was only loaded once. This worked great, but at the time I thought wouldn't it be great to load JS Libraries from a shared location. At the time the libraries were all over the place and I couldn't decide on the best way to load the files so shelved the project. Today Google announced they are now hosting AJAX libraries, I immediately thought back to upgrading the JSLoader and tonight after a few bits and pieces I fired up Visual Studio 2008 and hacked together JSLoader 2.0

Using JSLoader 2.0

The basic principles remain the same as JSLoader. You reference the control and then create a new webcontrol when you want to load some JavaScript. The difference now is you can use the old way of specifying a directory, file, version type etc, see my JSLoader post on using the old technique, but you can now load up Libraries from Google. Google currently hosts dojo, prototype, jQuery, script.aculo.us and MooTools and as such these are the only libraries that JSLoader 2.0 supports. In time I'll add YUI but for now these will do. JSloader now includes an extra attribute on the control, JSLibrary, here you can specify the AJAX library to load.
<mjjames:jsLoader ID="jsLoader2" runat="server" JSLibrary="dojo"  />
This would then add the following code to your page:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load("dojo" , "1");
</script>
You can also tell the loader to get Google to render the uncompressed version of the library, this is done by setting the type attribute to uncompressed
<mjjames:jsLoader ID="jsLoader1" runat="server" JSLibrary="mootools" Type="uncompressed" />
Thus:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load("mootools" , "1" , {uncompressed:true});
</script>
Note: only jQuery, MooTools and Dojo have uncompressed versions, if you specify uncompressed for the other libraries the compressed versions are still served up. Finally you specify a version number, by default JSLoader 2.0 tries to load the latest 1.x release of each library however if you want the 1.2.3 release of jQuery simply set the Version Attribute to 1.2.3
<mjjames:jsLoader ID="jsLoader3" runat="server" JSLibrary="jquery" Version="1.2.3" />
Giving you:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load("jquery" , "1.2.3");
</script>
It really is simple, it ensures only one version of each library is loaded and its quick and simple to use. Get the latest JSLoader 2.0, add a reference to it in your code, add the control to your site's web.config or register it on the page, and you are away.
<add tagPrefix="mjjames" namespace="mjjames.WebControls" assembly="jsLoader"/>
Hope you like it, any questions or issues let me know.

Side Note

Script.aculo.us depends on Prototype, however JSLoader 2.0 doesn't currently enforce this dependancy, would you like to see JSLoader 2.0 enforce this dependancy and load Prototype before Script.aculo.us or should it load it anyway and let the developer ensure Prototype is loaded? Would be good to see arguements for and against, then I can make a final decision some point this week.