This one is for future-Sam, the next time I spend 20 minutes searching Google for a solution to this problem.

Smart quotes convert neutral quotation marks to typographic quotation marks automagically. They can be a real pain in some applications, when your text is displayed to other users in a different font (mIRC, for example).

Non-smart, neutral, double quotes look like "this."

Smart, typographic, double quotes look like “this.”

Applications that use Microsoft Rich Edit controls allow you to turn smart quotes on or off with CTRL-SHIFT-' (that’s a neutral single quote).

Hopefully I won’t get laughed at in IRC next time I manage to mash the keyboard enough to turn smart quotes on.

posted @ Monday, May 06, 2013 5:47 PM | Feedback (0) | Filed Under [ Microsoft ]

Update

ReSharper 7.1.3 has been released. See JetBrain's release notes for guidance.

After installing Visual Studio 2012 Update 2, the unit test runner in ReSharper fails to run tests – all unit tests display “pending” status and never complete.

This is a known issue with current versions of ReSharper (7.1.2 and 8.0).

Grab the latest “private” 7.1.3 build from the links above, install, and carry on with your unit testing.

There seems to be some issues with the private build, at least according to random comments in the issue tracker. I haven’t found any problems, but contents may be hot etc.

If you’re running a mixed team of developers with different versions of Visual Studio, you’re going to run into problems with solution and project file version compatibility.

Theoretically, Visual Studio 2012 changed that; all solution and project files are backwards compatible! Yay! Problem solved.

Except for our old friend .dbproj from Visual Studio 2010.

Visual Studio 2012 converts .dbproj files into .sqlproj files, which Visual Studio 2010 can’t open. Google tells me that I just have to install SQL Server Data Tools for Visual Studio 2010, and everything will be great!

Except that the current version of the SQL Server Data Tools (December 2012 at the time of writing) is a higher version than that which ships with Visual Studio 2012. Visual Studio 2010 converts your .sqlproj files into the new version, and now Visual Studio 2012 can’t open them.

So, what’s a poor development manager to do? Install the updated SQL Server Data Tools for Visual Studio 2012 as well!

Go get both versions here: http://msdn.microsoft.com/en-us/data/hh297027

They run fine side by side (at least for the limited testing I’ve done), and your Visual Studio 2010 users can now be jealous of your Visual Studio 2012 users while still being able to get work done. It’s the best of both worlds, really.

In summary:

  1. Install the latest version of SQL Server Data Tools from http://msdn.microsoft.com/en-us/data/hh297027
    • Visual Studio 2010 users install the 2010 version of SQL Server Data Tools
    • Visual Studio 2012 users install the 2012 version of SQL Server Data Tools
    • Users with both versions install both versions of SQL Server Data Tools
  2. Open the solution in Visual Studio 2012, convert projects
  3. Open the solution in Visual Studio 2010, profit!

This one’s for my reference, mostly; hopefully I don’t spend hours trying to debug this error next time.

The scenario is that you’re using an EntityDataSource to bind some entities to a ListView. Inside the ListView, you’ve got a nested data-bound control that’s trying to bind to a collection property of the current entity.

For example, you bind a list of CustomerOrder entities to the parent ListView, and then bind the collection of CustomerOrder.CustomerOrderLines to a child ListView to render the products the customer has purchased on each order.

Using the EntityDataSource in its default state gives you this:

DataBinding: 'System.Web.UI.WebControls.EntityDataSourceWrapper' does not contain a property with the name 'CustomerOrderLine'.

…and a nice big stack trace.

The issue is that we’re using the EntityDataSourceWrapper and not our actual entity. The solution? Stop using the wrapper!

Disable flattening, like this:

<asp:EntityDataSource 
    ...
    EnableFlattening="False"
	...
</asp:EntityDataSource>

Easy. Now, don’t forget about this again, future-Sam!

A couple of years ago I posted my solution for the infamous “A potentially dangerous Request.Form value was detected from the client” error when using TinyMCE with ASP.NET 4.0.

The solution worked (mostly) without turning off request validation.

Since then, I’ve changed my approach slightly; I’ve dropped the Moxiecode TinyMCE ASP.NET assembly and have gone with a purely JavaScript solution. I think it works better, and it’s a lot cleaner and more up to date.

There are a few parts to this:

  1. Implementing TinyMCE JavaScript version
  2. Decoding HTML server-side on POST
  3. Handling TinyMCE re-encoding HTML on Postback

Implementing TinyMCE JavaScript version

Download TinyMCE (just grab the main package, which “contains all you need for production usage”), extract and copy the files into your solution.

Any page that has a TinyMCE text editor will need to include the base js file and a chunk of initialization script to set up all our options.

<script type="text/javascript" src="/_assets/tiny_mce/tiny_mce.js"></script>

<script type="text/javascript" >
    tinyMCE.init({
        mode: "specific_textareas",
        editor_selector: "tinymce",
        encoding: "xml",
        convert_urls: false,
        theme: "advanced",
        plugins: "spellchecker,pagebreak,style,layer,table,advhr,advimage,advlink,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,paste,directionality,fullscreen,visualchars,nonbreaking,xhtmlxtras",
        extended_valid_elements: "iframe[src|width|height|name|align]",
        theme_advanced_buttons1: "spellchecker,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect,|,print,fullscreen",
        theme_advanced_buttons2: "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
        theme_advanced_buttons3: "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,media,advhr,|",
        theme_advanced_toolbar_location: "top",
        theme_advanced_toolbar_align: "left",
        theme_advanced_path_location: "bottom",
        theme_advanced_resizing: true,
        theme_advanced_resize_horizontal: false,
        theme_advanced_styles: "Link to Image: lightbox;Image Right Border: rightbordered;Image Left Border: leftbordered;Darker Text: darker",
        setup: function (ed) {
            ed.onSaveContent.add(function (i, o) {
                o.content = o.content.replace(/&#39/g, "&apos");
            });
        }
    });
</script>

I’ve got all my site-specific configuration in the plugins and themes options; you’ll probably want to change those for your implementation.

There are three key areas here you want to pay attention to.

mode: "specific_textareas",
editor_selector: "tinymce",

These two tell TinyMCE to only initialize textareas with a class attribute containing “tinymce”. That means we won’t accidentally create TinyMCE instances if we’re using other textareas on the page.

encoding: "xml",

The encoding option (off by default) tells TinyMCE to XML-encode all HTML in our textarea on POST. This is critical for ASP.NET.

setup: function (ed) {
    ed.onSaveContent.add(function (i, o) {
        o.content = o.content.replace(/&#39/g, "&apos");
    });
}

Apostrophes will give you a lot of grief unless you explicitly add this onSaveContent() handler to convert them to a safe, encoded string. This is critical for ASP.NET.

Now all we have to do is include a textarea with the right class, and the init() function will take care of setting up TinyMCE for us.

<textarea
    id="htmlBody"
    runat="server"
    class="tinymce"
    rows="40"
    cols="120" />

Easy!

Decode HTML server-side on POST

Because TinyMCE is encoding HTML, we might choose to decode it server-side before storing it in the database. If you don’t decode TinyMCE output now, you’ll need to decode it before rendering anywhere.

public String SystemText
{
    get
    {
        return HttpUtility.HtmlDecode(bodyHtml.Value);
    }
    set
    {
        bodyHtml.Value = value;
    }
}

In codebehind (or wherever else you’re referring to your textarea in code), use HttpUtility to decode TinyMCE’s output when retrieving the value of the textarea for storage.

Handling TinyMCE re-encoding HTML on Postback

TinyMCE is set to encoding=xml, which encodes everything in the textarea on POST. That leads to a bunch of nasty &amp; &gt; etc. instead of real HTML when the page reloads after a Postback.

So, on Postback, we decode the textbox so TinyMCE is starting "clean". Here’s what sample codebehind could look like to do this:

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack)
    {
        if (bodyHtml != null && !string.IsNullOrWhiteSpace(bodyHtml.Value))
        {
            bodyHtml.Value = HttpUtility.HtmlDecode(bodyHtml.Value);
        }
    }
}

I’m very happy with this method; it works great using ASP.NET 4.0 and its more robust page validation model.

More importantly, I don’t have that nasty feeling I’m doing something terrible by setting ValidateRequest="false” in the page declaration!

Search

Site Sections

Recent Posts

Archives

Post Categories

WHS Add-In Tutorial

WHS Blogs

WHS Development