Pages

Wednesday 6 October 2010

Auditing entity changes in Silverlight 4

Well after some time searching around google to find details of how to audit changes made to my entities sets within Silverlight 4. I found myself going down various paths. Most of the examples show how to track these back at the server. However if you do not switch on ConcurrencyMode to Fixed within each entity field then you cannot compare the original values as these are reported as null. If you switch on the ConcurrencyMode then when the data is saved you will have a massive WHERE clause on updates [SQL profile and you will see].

However within the Silverlight client the original values were present, thus I wanted to try and compare these values on a save and then make the various audit changes. First draft of the code, simply wire up your SubmittingChanges event and use the code below. Comments welcome, as I'm sure there is a much better way of doing this.

void DataSource_SubmittingChanges(object sender, SubmittingChangesEventArgs e)

{
DataSource.SubmittingChanges -= DataSource_SubmittingChanges;
var changes = e.ChangeSet.ModifiedEntities;


foreach (var change in changes)
{

system_AUDIT audit = trackModifications(change);
// check if we have any audit detail
if (audit.system_AUDITDETAIL.Count != 0)
{
//add the audits
(DataSource.DomainContext as AppDomainContext).system_AUDITs.Add(audit);
}
}
}






public system_AUDIT trackModifications(System.ServiceModel.DomainServices.Client.Entity modifiedentity)
{
//get the entity name
var entityname = modifiedentity.GetType().Name.ToString();


//get the entity key [in this case its always the field rowguid]
System.Guid objectid = (System.Guid)modifiedentity.GetType().GetProperty("rowguid").GetValue(modifiedentity, null);


//get the original values
var originalentity = modifiedentity.GetOriginal();


// make sure we only bring back the properties defined for the entity
var properties = modifiedentity.GetType().GetProperties().Where(o => o.DeclaringType.Name == entityname);

//create a new audit guid
System.Guid g = System.Guid.NewGuid();


//setup the audit header
system_AUDIT audit = new system_AUDIT()
{
datecreated = DateTime.Now,
rowguid = g,
tablename = entityname,
objectid = objectid
};


//loop each property
foreach (System.Reflection.PropertyInfo property in properties)
{
var oldvalue = property.GetValue(originalentity, null);
var newvalue = property.GetValue(modifiedentity, null);

//if its a relationship should bring back null
if (oldvalue != null)
{
//normal property so compare the old and new values
if (oldvalue.ToString() != newvalue.ToString())
{
//change made so setup the audit detail
system_AUDITDETAIL detail = new system_AUDITDETAIL()
{
rowguid = System.Guid.NewGuid(),
fieldname = property.Name,
originalvalue = oldvalue.ToString(),
newvalue = newvalue.ToString(),
auditguid = g,
};
//add the detail to the audit heade record
audit.system_AUDITDETAIL.Add(detail);
}
}
}
//return the audit entity
return audit;
}

Friday 23 July 2010

Could not load file or assembly 'App_Web_, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

After recieving the error message "Could not load file or assembly 'App_Web_, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified." I found an article [link below] which simply states to clear down your temporary .net files. This worked a treat. I beleive the problem was from previous compilations that had not cleared down properly and the files had become locked. If you are unable to remove the files run an "iisreset" and try again.

Blog link

Silverlight 4 and WCF/RIA Services under IIS 7.5 and .NET v4.0

Whilst migrating a Silverlight 4 application into a Windows Server 2008 environment with IIS 7.5 [what could be easier] I found the sudden thrills of getting the application to run correctly with the .NET v4 framework and WCF/RIA services.

So I fired up the application only to receive a "404 not found error message" when trying to browse the .svc service files. Okay what about the silverlight application? fire up the application and receive an error message stating "load operation failed trying to retreive the query...". Some days passed 'googling' the various errors only to be pointed to articles that related to v3 of the framework, surely it cant be that complicated to get the application functioning correctly.

Well atlast I found the solution so I thought I would share it to avoid machines being thrown out of the window!

Firstly I found that if I hosted my application under the default web site, under IIS the various script handlers were not created. If you ran the "aspnet_regiis -i" command from the v4.0.30319 framework folder, the entries are still not created. Hmmm very strange. Their are various articles about running "ServiceModelReg -i" from the v3 folder, dont do this or you break the current v4 bindings.

Resolution; simple, create a new web site [to host your application] and then run the "aspnet_regiis -i" from the framework folder [Framework for 32bit or Framework64 for 64bit applications].

When viewing the HTTP Handlers section under the new website and you will see the various mappings for the .svc files have been created [look back at the default website and these havent been upgraded!]. This then resolved the 404 errors and Fiddler was also confirming that the svc files were being accessed correctly. 

As a last configuration make sure the application pool is set to the ASP.NET 4 Integrated mode pool and enable the allow 32bit applications.

Hope this helps :-)