All posts by Eric Bartels

SQL Server FILESTREAM and master key

When dealing with RBS and SharePoint all guides provide the statement:

USE [WSS_Content]
IF NOT EXISTS 
(SELECT * FROM sys.symmetric_keys 
WHERE name = N'##MS_DatabaseMasterKey##')
CREATE master KEY encryption BY password = N'Admin Key Password !2#4'

If you ever asked yourself if its possible to leave that statement… The answer is no!

Funny thing is that the installation of the rbs-client states out a successfull installation. But all mssqlrbs_* tables are missing for the specified content database. And running the PS commands for the content db:

$cdb = Get-SPContentDatabase WSS_Content
$rbss = $cdb.RemoteBlobStorageSettings
$rbss.Installed()

simply returns false.

After comparing a successfull installation and an unsuccessfull installation the logfile of the failed installation is missing the create statements for the tables. A simple

Remote Blob Storage on the database has failed with error message: Remote Blob Storage requires a master key to exist in this database

is written somewhere in that logfile. Very easy to overlook.

The only way to fix the “corrupt” content database and (re-)provision the missing tables is to create the master key via the “master-key sql-statement” followed by the following command:

msiexec /qn /i rbs.msi REMOTEBLOBENABLE=1 FILESTREAMPROVIDERENABLE=1 DBNAME=WSS_Content FILESTREAMSTORENAME=FilestreamProvider_1 ADDLOCAL=EnableRBS,FilestreamRunScript DBINSTANCE=CD

This will provision the missing tables and rbs is up and running …

Fixing “Operation is not valid due to the current state of the object” when using SSRS ReportViewer in ASP.Net MVC

So I’ve included the SSRS ReportView control within my ASP.Net MVC application. So far so good. Just displaying the report works fine after struggeling with the dimensions of the iframe and the ReportViewer control itself.

But after a more complex drill-through report was display and then clicking the actions caused the famous error “Operation is not valid due to the current state of the object” (which in this case has nothing to do with resource limits due to security patches). Switching from asynchronous (AJAX) to classic postback did not help either.

It was a long day and the obvious was not that obvious anymore. I used the following code within the Page_Load event to configure the report:

protected void Page_Load(object sender, EventArgs e)
{
  string reportName = Page.RouteData.Values["reportName"] as String;
  string reportPath = Page.RouteData.Values["reportPath"] as String;
  string sizeType = Page.RouteData.Values["sizeType"] as String;
  bool withToolbar = Boolean.Parse(Page.RouteData.Values["withToolbar"] as String);
 
  theReportViewer.ServerReport.ReportServerUrl = new Uri("http://example.org");
  theReportViewer.ServerReport.ReportPath = String.Format("/{1}/{0}", reportName, reportPath);
}

After analysing logfiles and event logs I was nearly giving up when finally realizing that a click within the report causes a postback. But everytime the page loads I resetted the report. *sigh* The “fix” is simple and straightforward and should have been written in the first place.

protected void Page_Load(object sender, EventArgs e)
{
  if (!this.Page.IsPostBack)
  {
    string reportName = Page.RouteData.Values["reportName"] as String;
    string reportPath = Page.RouteData.Values["reportPath"] as String;
    string sizeType = Page.RouteData.Values["sizeType"] as String;
    bool withToolbar = Boolean.Parse(Page.RouteData.Values["withToolbar"] as String);
 
    theReportViewer.ServerReport.ReportServerUrl = new Uri("http://example.org");
    theReportViewer.ServerReport.ReportPath = String.Format("/{1}/{0}", reportName, reportPath);
  }
}

Now drill-through and navigation inside the reports is no problem at all.

Solving connectivity issues with RDP via UAG

From one day to the other in all of my current environments I had trouble connecting with RDP via UAG to remote servers. The error message always was “Your computer can’t connect to the remote computer because an error occurred on the remote computer that you want to connect to. Contact your network administrator for assistance“.

Its not that clear that the issue is on the client side. So troubleshooting on the UAG-side did not help. Further research and testing revealed the culprit. Microsoft!

After a certain Hotfix, KB2592687 to be precise, the connectivity issues started.

So I did a quick

Get-Hotfix -Id KB2592687

to see if I had the patch installed. And yes it was. So another

cmd.exe /c wusa.exe /uninstall /KB:KB2592687 /quiet

and a lot of waiting and restarting finally allowed a connection via RDP via UAG.
A hotfix for the UAG to allow newer RDP clients is still not available!

Using a dictionary to create dynamic elasticsearch-queries in .Net 3.5

In a current project a search based solution is required to allow a research against an existing set of records. Of course the search-backend is the elasticsearch.

This projects requires the use of .Net 3.5 which makes it impossible to use NEST as elasticsearch client.

To at least add a little bit of comfort when writing the queries against the search-cluster I make use of RestSharp for easy connecting and JSON handling. Net 3.5 has no ExpandoObject to create dynamic property names. It took me awhile to find out but a simple Dictionary does the trick.

var innerQueries = new List<object>();
 
// Data is a Dictionar<string, string> where the key is the fieldname used in elasticsearch
// and the value the value to search for (e.g. title => foo; description => baz)
foreach(var token in data.Keys)
{
  dataResult.Add(new
  {
    match_phrase = new Dictionary<string, string>;
    {
      { 
        token,
        data[token]
      }
    }
  });
}
 
var final = new
{
  query = new
  {
    @bool = new
    {
      must = innerQueries
    }
  },
  from = 0,
  size = 250
};

Serializing this into JSON and sending it via RestSharp creates a request with multiple must “clauses” each using a match_prase query.

{
  "query":{
    "bool":{
      "must":[
        {
          "match_phrase":{
            "record.title":"foo"
          }
        },
        {
          "match_phrase":{
            "record.description":"baz"
          }
        }
      ]
    }
  },
  "from":0,
  "size":250
}

Solving issue with SharePoint Workspace 2010 when using Forefront TMG

I came accross an issue when using TMG / UAG with SharePoint Workspace 2010. When connecting to a site I got the error

SharePoint Workspace was unable to interpret the SharePoint location.
Please check and ensure the location contains no typing errors.

Of course this error message is misleading. Solutions found in “the internet” like adding “remote differential compression on the server” were not applicable…

So after further tracing I found the culprit. The ULS logs (verbose mode was configured for logging) showed the exact web service calls SharePoint Workspace 2010 did with its full soap body. One call showed an url which I was pretty sure was not inside the AAM of that specific web application. Other calls always show the correct public url of that web application. Just one specific call … So I added it to the configuration and everything is working and synchronizing as expected.

If you encounter this error check your ULS logs and double check your AAM settings!