Tuesday 25 November 2008

Aspose.Words Ignores Protection Exclusion for Selected Areas when Generating Word Documents

As per the following thread, http://www.aspose.com/community/forums/showthread.aspx?PostID=153354&Subj=document-protection#153354, Aspose.Words will completely ignore your selection-based exclusions when you are trying to lock/protect parts of a document - and there is no fix expected for the next 3-6 months. This is unfortunate as it is a very powerful feature when generating MS Word documents that should only be partially editable.

It is not a viable option to use Form fields and section-based security as it only allows data entry without the ability to change any formatting (this was the workaround suggested by Aspose for now). My client has reluctantly accepted that this is an inherent limitation of the document generation section in our ASP.NET application.

One interesting element in Aspose.Word's implementation is their use of tags to delimit repeating data within table. You pass in a DataSet and it will use the field names (presumably via reflection) to render the fields of your list into a Word table.

See below for an example of the table-binding syntax of Aspose.Word. Note the «TableStart:TableName»«Field1»«Field2»«TableEnd:TableName» syntax.


Saturday 22 November 2008

Dell D630 Problem - Cannot enable LAN Card - Fixed

I normally connect my laptop to my home network via wireless on a Belkin Router (F1PI241EGau) from iiNet. Tonight, however, I tried to connect via a LAN port because it appears my router's wireless capability has been freezing every day with Smurf attacks - and I wanted to see the log before hard rebooting it. Rebooting has the unwanted effect of clearing out any diagnostic messages I might get right before the failure of wireless.

Problem was - I just couldn't enable the LAN adapter on my laptop - even through device manager. When I tried to enable it it would respond with a shocked "Connection Failed!" or "Windows could not enable your device" - and would show "Device is disabled (Code 22)". Nothing at all was showing up in the event log under Application/System categories - so the event log was about as useful as a screen door on a submarine in this situation.

I tried to disable some the Dell Quickset (f)utility and disabled power management to try to fix the problem. Dell has a lovely (for some) service that disables the network card when you are not on mains power called "NICCONFIGSVC" (C:\Program Files\Dell\QuickSet\NICCONFIGSVC.exe) - but still could not enable my laptop LAN card.

The simple fix was to uninstall the problematic network card and restarted. I now have a brand spanking new Local Area Network Adapter 3 which is fully functional and I can now proceed to diagnose the nasty Smurf DoS attacks.

Tuesday 4 November 2008

List of Alternative Options for Deploying or Hosting Applications to SharePoint 2007 or WSS 3.0

There are several different ways you can deploy an application to MOSS:
  1. Create Custom built Web Parts and deploy them as features
  2. Drop an ASP.NET application in c:\program files\common files\microsoft shared\web server extensions\12\template\layouts that gets virtualized to every site on your server
    e.g. to http://servername/sites/sitename/_layouts/MyApp/SomePage.aspx
  3. Use User Controls and the Son of SmartPart (See http://www.smartpart.info/default.aspx)
  4. Using ASPX pages added to SharePoint Site (this involves deploying to the bin folder of your SharePoint site such as C:\Inetpub\wwwroot\wss\VirtualDirectories\moss.litwareinc.com80\bin, Adding SafeControls Web.Config entries to allow your assemblies to load, and deploying your aspx to the relevant site.

For more info see

http://blogs.msdn.com/cjohnson/archive/2006/09/05/application-development-on-moss-2007-amp-wss-v3.aspx. It also has a very handy decision matrix when you are having trouble deciding which deployment model/architecture you should use.

There is also a list of 2 other options described here:

http://sharenotes.wordpress.com/2008/02/21/add-custom-aspx-pages-or-asp-net-pages-in-sharepoint/

  1. Using features and WSP package: Following some steps as recommended by Andrew Connell (MOSS MVP). Here is the blog. I believe this is the standard approach users are using in the SharePoint developer community.
  2. Using VSeWSS (Visual Studio extensions for WSS): This is yet another and latest solution. Microsoft recently released the VSeWSS 1.1 RTM. Using this, we can deploy all the asp .net pages into SharePoint by setting up a new project in Visual Studio. VSeWSS creates a solution package using features. Setup the project and hit ‘Deploy’ and it is done.

Monday 3 November 2008

Using Attributes, Reflection and GetCustomAttributes() to support field mappings between systems

My task today was to generate MS word documents using Aspose.Word and merge fields. The problem was, the names of the merge fields did not match exactly with the names of the properties of my objects - and I didn't want to map all fields in my objects to the external components in a separate method call. I approached this with a mechanism I have used several times before - using CustomAttributes and Reflection to drive the property mappings between application entities and external components such as Documents or Emails. See below for details on this. Note the use of the GetCustomAttributes() for retrieving custom attributes on your properties.

The attribute class:



/// <summary>
/// Supports the mapping between Aspose.Word Merge fields and the Fields
/// in the Data Transfer Object
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class DocumentMergeFieldMappingAttribute : System.Attribute
{
public string MergeFieldName { get; set; }

public DocumentMergeFieldMappingAttribute(string mergeFieldName)
{
MergeFieldName = mergeFieldName;
}
}


The mapping class which builds up a Dictionary (name, value pairs)


/// <summary>
/// Gets dictionary of field values for merge into documents - uses the
/// DocumentMergeFieldMappingAttribute to determine which dto properties
/// should render to the Document itself.
/// </summary>
/// <param name="inputDto"></param>
/// <returns></returns>
private IDictionary<string, IFieldValueDto> GetDtoFieldValues(object inputDto)
{
Dictionary<string, IFieldValueDto> dictionary = new Dictionary<string, IFieldValueDto>();

Type objectType = inputDto.GetType();
PropertyInfo[] properties = objectType.GetProperties();

foreach(PropertyInfo property in properties)
{
foreach (Attribute attribute in property.GetCustomAttributes(true))
{
if (attribute is DocumentMergeFieldMappingAttribute)
{
string fieldValue = property.GetValue(inputDto, null) as string ?? string.Empty;
//Set property value and the mapped document field name
dictionary.Add(((DocumentMergeFieldMappingAttribute)attribute)
.MergeFieldName, new FieldValueDto<string>(fieldValue));
}
}
}
return dictionary;
}