Aspose words for .Net doesn’t support word field skipif to skip some merge fields between tablestart and tableend i,e skipping rows based on some condition.

Here, I’ll explain how to include skipif common functionality  with custom merge field in the word document.
The custom skipif merge field syntax should be as below

skipif:tablename:condition  

where condition must be a valid t-sql where clause and use ~ for spaces if any. Skipif can be used at any position and for any table. If you use multiple skipif’s for the same table, the last skipif will be considered ignoring all the previous skipif’s.

Ex:

if the table name is productstable (provided with tablestart: and tableend:)

skipif:productstable:price>0   (or in alt f9 view, { MERGEFIELD skipif:productstable:price>0 } )

skipif:productstable:price~in~(100,200,300,400)

1) Define a method ApplyFilters that takes two parameters, data set and aspose document.


DataSet ApplyFilters(DataSet ds, Document doc)
        {
            var fieldNames = doc.MailMerge.GetFieldNames().ToList();
            var newDs = ds.Clone();
            var skipIfs = fieldNames.Where(x => x.ToLower().StartsWith("skipif"));
            if (skipIfs.Any())
            {
                foreach (DataTable table in ds.Tables)
                {
                    foreach (var s in skipIfs)
                    {
                        var sp = s.Split(":".ToCharArray());
                        if (sp.Length > 2)
                        {
                            var where = sp[2];
                            if (!String.IsNullOrWhiteSpace(where))
                            {
                                DataTable newTable;
                                where = where.Replace("~", " ");
                                var skipRows = table.Select(where);
                                var rows = table.AsEnumerable().Except(skipRows);
                                var dataRows = rows as List ?? rows.ToList();
                                if (dataRows.Any())
                                {
                                    newTable = dataRows.CopyToDataTable();
                                }
                                else
                                {
                                    table.Clear();
                                    newTable = table;
                                }
                                newTable.TableName = table.TableName;
                                newDs.Tables.Remove(newTable.TableName);
                                newDs.Tables.Add(newTable);
                            }
                        }
                    }
                }
            }
            return newDs;
        }

2) Define a class that inherits IFieldMergingCallback and implement FieldMerging method


public class HandleSkipIfField : IFieldMergingCallback
    {
        void IFieldMergingCallback.FieldMerging(FieldMergingArgs args)
        {
            if (!String.IsNullOrWhiteSpace(args.TableName))
            {
                var fieldName = args.FieldName;
                if(fieldName.ToLower().StartsWith("skipif"))
                {
                    args.Text = "";
                }
            }
        }

        void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
        {
            // Do Nothing
        }
    }

3) Add below code before firing executewithregions


//Add below 2 lines before executewithregions
doc.MailMerge.FieldMergingCallback = new HandleSkipIfField();
var dataSource = ApplyFilters(ds, doc);


doc.MailMerge.ExecuteWithRegions(dataSource);

Using async and await in windows 8 store apps bit tricky sometimes. Here I’m listing below some of the do’s and don’ts when working with async and await.

1) Always use void type for  top level async method. Don’t use return type Task for top level async method i,e. the method called by some app handler  for example click, onnavigatedfrom, onloaded etc.  This may not be same for console apps, where the top level method should always return Task in order to put wait instruction from Main method. Using same Task.Wait() in store apps blocks the UI thread and enters into deadlock.

   void Page_Loaded(object sender, RoutedEventArgs e)
        {
              TopLevelMethod();
	}
  
public static async void TopLevelMethod()
{
     var response = await PostAsync(url, content);
}

Without any top level async method

 async void Button1_Click( object sender, RoutedEventArgs e)
{
 var response = await PostAsync(url, content);
}

2) To update UI before and/or after async operation, include update code in the async method but not in its caller for example showing/hiding progress ring or some alert after receiving response etc.

3) If your top level async method is called by timer event or some other scheduler  event and it is accessing any UI related stuff, then use Dispatcher.RunAsync to run that method uses same thread context.

Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, TopLevelMethod);

4)  Utilize features of newly introduced simplified HttpClient class for all asynchronous get and post methods. You can use httpwebrequest async methods but same can be achieved with lesser code using HttpClient.

HttpClient

Example using httpclient post async (fewer lines )

    
public static async Task PostAsync(string url, string postContent)
        {
            using (var httpClient = new HttpClient())
            {
                var httpContent = new StringContent(postContent, Encoding.UTF8, "text/xml");

                using (var response = await httpClient.PostAsync(url, httpContent))
                {
                    response.EnsureSuccessStatusCode();

                    string content = await response.Content.ReadAsStringAsync();

                    return content;
                }
            }
        }

5)  Use always async and await for all anything that reads/writes from/to media(disk i/o etc.).

Example:

 
var file = await Package.Current.InstalledLocation.GetFileAsync("Data\\Groups.txt");
var result = await  FileIO.ReadTextAsync(file);
var xml = await reader.ReadToEndAsync()