Tuesday, September 20, 2011

Beware the smart quotes when writing code outside a code editor!

I struggled a few hours today performing a REST query from the IE address bar. I copied the URL from some source to One Note, and changed it a bit. I pasted it back into IE, and just couldn't get it to work.

Eventually, after much pain and suffering, I typed a single quote next to the existing one in notepad to try escaping some text, and noticed a subtle difference between the quotes. See if you can spot it:  ‘ ’ '   While these three characters look similar to you and me, they are in fact very different to text parsers.

My guess is that at some point it must have been inserted by the auto correct feature of a helpful Microsoft Office application. A little further digging exposed that there is a way to turn off the "insert smart quotes" feature in Office applications, explained here.

There are more info available about smart quotes here. A particularly handy tip, is that you can undo the smart quote conversion by pressing ctrl-z immediately after typing the quote character.

Sunday, September 18, 2011

How to Render a partial view in the controller.

I had the need today to render some html using a partial view, and then add that html to a JSON Result in MVC 3. I found a few examples on the internet that does it by extending the Controller class, but I don't particularly like this approach as it seemed hard to test. The reason is that it requires the view to be resolved in the controller itself, using built-in methods that rely on other static methods ("dirty, evil!"). I'm sure you can make it work by mocking some of the funkiness around view engines, but that just seemed like too much hard work.

My solution is to apply a bit of dependency injection by injecting a new class called a PartialViewRenderer as an interface into my controller. This class will abstract the rendering away, thereby removing the dependency on the view engines etc. from the controller. My controller now becomes easily testable again! This also adheres to the default approach of rendering views etc outside of the controller. You can also test the rendering seperately, but I haven't bothered with that.

The code for the renderer is as follows:

public class PartialViewRenderer : IPartialViewRenderer
{
    public string RenderOutput(ControllerContext controllerContext, object model, string partialViewName)
    {
        using (StringWriter writer = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controllerContext, partialViewName);
            ViewContext viewContext = new ViewContext(controllerContext, viewResult.View, new ViewDataDictionary(model), 
                controllerContext.Controller.TempData, writer);
            viewResult.View.Render(viewContext, writer);
            return writer.GetStringBuilder().ToString();
        }
    }
}

It is used in the following action:

public JsonResult LoadUrl(string request)
{
    RestUrlRequest data = new JavaScriptSerializer().Deserialize(request);
    RestSampleUrlModel model = restExamplesProvider.LoadUrl(data);
    model.OutputHtml = outputRenderer.RenderOutput(ControllerContext, model, formatToOuputViewMap[data.Format]);
    return Json(model, JsonRequestBehavior.AllowGet);
}

outputRenderer is an instance of the PartialViewRenderer that we've injected in this controllers' constructor.

A test can be done as such:

[TestMethod]
public void LoadUrlReturnsUrlResultWithOuputFromRendererForFormat()
{
    RestSampleUrlModel model = new RestSampleUrlModelFixture().Build();
    IRestExamplesProvider samplesProvider = new RestExamplesProviderMockFixture { RestSampleUrlModel = model }.Build();
    RestBrowserControllerFixture controllerFixture = new RestBrowserControllerFixture { RestSamplesProvider = samplesProvider };
    RestBrowserController controller = controllerFixture.Build();
    RestUrlRequest request = new RestUrlRequestFixture { Format = "atom" }.Build();

    JsonResult result = controller.LoadUrl(new JavaScriptSerializer().Serialize(request));

    result.Should().NotBeNull();
    RestSampleUrlModel data = (RestSampleUrlModel) result.Data;
    data.OutputHtml.Should().Be("mock render output");
    controllerFixture.RestOutputRenderer.AssertWasCalled(mock => mock.RenderOutput(controller.ControllerContext, model, "atom"));
}


I used a mock for the implementation of the OutputRenderer in this test. The mock itself is setup in a seperate fixture class. The renderer class itself can be extended to be more flexible with different overloads for the method, but that is surplus to my requirements.

Thursday, July 7, 2011

Fun with CRM RetrieveMultiple, ConditionOperator.Contains and sql indexing

Had an interesting problem today, trying to search a CRM entity.
I had the following code:
QueryExpression query = new QueryExpression("fpis_jobsite")
{ 
    ColumnSet = new ColumnSet { AllColumns = true } 
};
query.Criteria = new FilterExpression();
query.Criteria.AddCondition("fpis_name", ConditionOperator.Contains, siteName);
EntityCollection entities = organizationService.RetrieveMultiple(query);
return entities.Entities.Select(BuildJobSite).ToList();

Running it in a test gave me a Generic SQL Error.

After much fuss, I followed the instructions
here to run a SQL trace.

I found the following error:
"Cannot use a CONTAINS or FREETEXT predicate on table or indexed view 'fpis_JobSite' because it is not full-text indexed."
Once I changed the ConditionOperator.Contains operator in my condition to ConditionOperator.Like, the call executed without any further problems.
On a side note, it is not possible to populate child entities by calling RetrieveMultiple with a QueryExpression. You have to make seperate web service calls. In most cases though, you'd be able to craft your QueryExpression to retrieve all the child entities in a single call.

Wednesday, November 17, 2010

Using a filtered index for a unique constraint

I needed to apply a unique constraint on a combination of columns, but only for rows that had not been marked as deleted. After scouring the web, I came to the conclusion that there were two worthwhile ways to achive this.

  1. Set up a view that only exposes the rows on which the constraint should act. This needs to be a persisted view.
  2. Instead of a constraint, set up a filtered index.

Discussions on Stack Overflow also suggested using triggers to do some magic in the system, but I have a longstanding hatred for triggers and cursors. One could also opt to enforce your uniqueness constraint in all your inserting and updating stored predures, but this is tiresome and error prone.

I opted to do the filtered index, as that seems to be the cleanest way of achieving my goal. Note that filtered indices are only available on SQL 2008. If you have 2005, you'll need to use a different mechanism, like the constraint on the view.

You can find a comparison of unique indices and unique constraints here http://msdn.microsoft.com/en-us/library/aa224827(SQL.80).aspx The writer comes to the conclusion that they're pretty much the same, with the index having a few more creation options.

Sample Code

This is the table we will use to illustrate the effect of the index:

CREATE TABLE dbo.SerialisedStock (
SerialisedStockId INT IDENTITY(1,1) NOT NULL,
StockId INT NOT NULL,
StockCode VARCHAR(50) NOT NULL,
IsDeleted BIT NOT NULL
CONSTRAINT PK_SerialisedStock PRIMARY KEY CLUSTERED
(
SerialisedStockId
)

The code to create our index on the table:

CREATE UNIQUE INDEX UK_SerialisedStock_StockNumber ON SerialisedStock(StockId, StockCode ) WHERE IsDeleted = 0

This insert statement will fail if done more than once:

INSERT INTO SerialisedStock
(StockId, StockCode, IsDeleted)
VALUES(1, 'aa',0)

This insert statement can be done multiple times:

INSERT INTO SerialisedStock
(StockId, StockCode, IsDeleted)
VALUES(1, 'aa',1)

Thursday, October 14, 2010

Cool Visual Studio 2010 Extensions

Came across the PowerCommands extension for VS2010. Does some cool stuff, like


  • giving you a shortcut to reopen recently closed documents (and an optional windows displaying a list of recently closed documents).

  • adds a command on the context menu of the solution explorer that will open up a command prompt with the working directory set to the path of the item you clicked on.

  • Adds a command to open the containing folder of an item clicked on in the solution explorer.

  • copy and paste references.

  • email a code snippet.


http://visualstudiogallery.msdn.microsoft.com/en-us/e5f41ad9-4edc-4912-bca3-91147db95b99


For those of us used to scroll in any direction by dragging with the middle mouse button in almost any Microsoft product, this AutoScroll extension will re-add that functionality to Visual Studio 2010. (This is not an invitation for a debate on class sizes!)

http://vs2010autoscroller.codeplex.com/

There are a couple of other add-ons and extensions that I also use (and won't go without) such as Resharper, Ankh (for svn), TestDriven.Net (though Resharper can do the same stuff) and GhostDoc.