Thursday, 23 April 2015

Sharing common assemblies with aspnet_intern.exe

I’m reviewing the skills measured for exam 70-494 Recertification for MCSD: Web Applications, and came across this item towards the end of the list:

“Prepare the environment for use of assemblies across multiple servers (interning)”

Hmm, that’s something I wasn’t familiar with.

Curiously there’s only a couple of significant places I’ve found it mentioned online: First, Sateesh gives an overview in his post Look at Sharing Common Assemblies in ASP.NET 4.5, and then it gets a mention in the What's New in ASP.NET 4.5 and Visual Studio 2012 notes under the heading Sharing Common Assemblies.

So for situations where you’re hosting a number of ASP.NET web applications on the same server and they share some common assemblies, aspnet_intern can help mitigate the problem that each assembly copy has to be read separately during cold site startup and kept separately in memory.

On a machine with Visual Studio 2013 installed, aspnet_intern.exe can be found in C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\.

Here’s the usage details:

Microsoft (R) ASP.NET Intern version 4.0.30319.33440
Utility to analyze ASP.NET web applications and intern common .NET assemblies found in the Temporary ASP.NET Files directory.
Copyright (C) Microsoft Corporation. All rights reserved.

aspnet_intern [-mode analyze|exec|clean|query] [-sourcedir <input source path>] [-interndir <output target interned path>] 

-?                  Display this help text.
-mode analyze       Analyze source directory for managed assemblies that can be
                    interned for cross application sharing (default)
-mode exec          Perform interning of managed assemblies for cross
                    application sharing
-mode query         Display information about shared assemblies in the intern
                    directory
-mode clean         Deletes the intern directory and all symbolic links in the
                    source directory pointing at files in the intern directory
-sourcedir          Source directory to scan for potential assembly interning
                    candidates.  Use either the Temporary ASP.NET Files
                    directory location, or the location defined in the
                    system.web/compilation/tempDirectory web.config attribute.
-interndir          The location where interned assemblies are stored for
                    sharing across ASP.NET applications.
-v                  Verbose output
-bpc                Bypass platform checks
-minrefcount        The minimum number of times an assembly was found in
                    different locations for the assembly to be considered an
                    interning candidate. (Default: 3)
-whitelist          Only allows interning of managed assemblies that are
                    contained in this file.  Value should be the full file path
                    to a line delimited list of patterns which may contain a
                    trailing asterisk which will turn the pattern into a prefix
                    match.  i.e. MyAssembly-1.*

Examples:

       aspnet_intern -mode analyze -sourcedir "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files"
       aspnet_intern -mode exec -sourcedir "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files" -interndir C:\ASPNETCommonAssemblies
       aspnet_intern -mode clean -sourcedir "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files" -interndir C:\ASPNETCommonAssemblies
       aspnet_intern -mode query -interndir C:\ASPNETCommonAssemblies

Monday, 20 April 2015

Entity Framework 6 connection string names

When you add Entity Framework to a .NET project, it adds the following to the app.config file:

<entityFramework>

  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
    <parameters>
      <parameter value="mssqllocaldb" />
    </parameters>
  </defaultConnectionFactory>
  <providers>
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  </providers>
</entityFramework>

David shows that you can modify the defaultConnectionFactory section to use SQL Server with a connection string.

<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">  
  <parameters>
    <parameter value="Data Source=.\sql2014;Initial Catalog=AdventureWorks2014;Integrated Security=True;" />
  </parameters>
</defaultConnectionFactory>

What might not be immediately obvious is that you can also refer to an existing connectionString by name. So if you already have:

<connectionStrings>
  <add name="AW" connectionString="Data Source=.\sql2014;Initial Catalog=AdventureWorks2014;Integrated Security=True;" providerName="System.Data.SqlClient"/>

</connectionStrings>

Then you can just configure it like this instead:

<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
  <parameters>
    <parameter value="AW" />
  </parameters>
</defaultConnectionFactory>

Sunday, 19 April 2015

ASP.NET WebSockets basics

Back in 2012, ASP.NET 4.5 and IIS 8 shipped with built-in support for WebSockets. If you plan to support using WebSockets on the server today, you’ll most likely use SignalR, which makes this all quite easy, but I thought it would be educational to take a step back and see what’s involved in just using the framework’s basic support.

To try this out I created a new ASP.NET MVC web project.

I then added a new ‘Generic Handler’ item to the project and named it MyHandler.ashx

The contents of this hander are based on the example from What’s New in ASP.NET 4.5. It essentially echoes any content received back to the caller:


using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.WebSockets;

namespace DemoWebSockets
{
    public class MyHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            context.AcceptWebSocketRequest(ProcessWebSocket);
        }

        public bool IsReusable
        {
            get { return false; }
        }

        private async Task ProcessWebSocket(AspNetWebSocketContext context)
        {
            var socket = context.WebSocket;
            while (true)
            {
                var buffer = new ArraySegment(new byte[1024]);

                // Asynchronously wait for a message to arrive from a client
                var result = await socket.ReceiveAsync(buffer, CancellationToken.None);

                // If the socket is still open, echo the message back to the client
                if (socket.State == WebSocketState.Open)
                {
                    var userMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
                    userMessage = string.Format("You sent: {0} at {1}", userMessage, DateTime.Now.ToLongTimeString());
                    buffer = new ArraySegment(Encoding.UTF8.GetBytes(userMessage));

                    // Asynchronously send a message to the client
                    await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                }
                else
                {
                    break;
                }
            }
        }
    }
}

I then modified the index.cshtml page

<div class="row">    
<div class="col-md-12">
        <label for="msgText">Text to send:</label>
        <input id="msgText" type="text" /><br />
<input id="Trigger" type="button" onclick="CallWebSocket(); return false;" value="Send" />
        <hr />
        <div id="serverData">
</div>

<script type="text/javascript">
     var socket = new WebSocket("ws://localhost:51057/MyHandler.ashx");

     // Receive a string message from the server.
     socket.onmessage = function (msg) {
          document.getElementById("serverData").innerHTML = msg.data;
     };

     function CallWebSocket() {
         if (socket.OPEN) {
             // Send a string message from the browser.
             socket.send(document.getElementById("msgText").value);
         }
     } </script>

And here’s the finished product:

Screenshot showing example of web page

Youssef also shows how to create a handler using WebAPI, and server-side configuration to enable IIS WebSocket support.

Wednesday, 1 April 2015

Jon Galloway on new things in ASP.NET 5 and ASP.NET MVC 6

We’ve got another “big name international speaker” for ADNUG this month!

Photo of Jon GallowayNext week, we’re joined by Jon Galloway, a Microsoft Technical Evangelist based in San Diego, California. Jon will be speaking about the new features coming in both ASP.NET 5 and ASP.NET MVC 6. I assume we’ll see the final versions of these around the same time that Visual Studio 2015 ships.

I first came across Jon through his being one of the presenters of the Herding Code podcast (I’ve been listening since 2009). More recently, I’ve watched some of his courses on Microsoft Virtual Academy, seen him appear weekly in the ASP.NET 5 Community Standups and been following him on Twitter. He’s an engaging, knowledgeable, down-to-earth presenter and I’m anticipating it will be a great meeting.

If you’re in Adelaide, then please register and come along on Thursday 9th April at 12 noon, Microsoft Adelaide, Level 12, 147 Pirie St, Adelaide. Register via http://www.meetup.com/Adelaide-dotNET/events/221073867/

If you’re out of town or just can’t make it in person, then we’ll be running the session via a Google Hangout – so you can still participate in the live session or watch the recording after the event on YouTube.

Look forward to seeing you there in person or online Smile.

Tuesday, 10 March 2015

ALTER AUTHORIZATION

(For my own reference)

To resolve this issue in Microsoft SQL Server (often observed when you restore a database that came from another server):

SQL Server Management Studio information dialog

Run this:

alter authorization on database::[MyDbName] to sa;

Thursday, 19 February 2015

MVA Figurines

In September last year I took part in the MVA ‘Become a hero’ promotion. By signing up, I got a free t-shirt (and if you know me well, you’ll know that makes perfect sense). In addition by completing a number of online courses from the MVA site, you could then get a novelty figurine (or maybe up to 6 if you did more courses).

I received my t-shirt, but my figurine never arrived. It appeared the super powers of “DevOps Captain Code” also included the ability to get lost in the mail. “Oh well, at least I’ve got a t-shirt”, I thought.

But then yesterday I got home to discover two packages from Microsoft. One was another t-shirt (yay), and the other was the full set of 6 figurines.

MVC Hero Figurines

So now we have (left to right)

  • SQL Server Query Controller
  • Azure Cloud Ninja
  • Device Management Dr Device
  • Windows Server Solid Server
  • DevOps Captain Code
  • Virtualisation Hypervisor

They’re now gracing my desk at work, much to the bemusement of my colleagues Smile

Figurines and t-shirts aside, if you’re after some quality free online training then there’s some excellent resources at the Microsoft Virtual Academy site. Most courses are run as a live event and then are made available on-demand a few weeks later (useful if the live event clashes with your preferred time to be asleep!)

Saturday, 7 February 2015

In the garden–February 2015

It’s summer time. We’ve had a bit of hot weather, including today (and more to come in the next week), but also some cooler patches too, which I think the garden has appreciated.

On hot days when it gets into the high 30’s and 40’s, I’ve taken to putting out shade for some of the smaller fruit trees. Bits of shade cloth and old sheets. The garden probably looks a bit like a weird art installation, but I think the trees appreciate a bit of help surviving the blistering heat.

I’ve harvested some cabbages (there’s still a few growing), and got some tomatoes just starting to fruit. I was a bit late planting these – my dad is already eating the fruit from his. I had planted some cucumbers and pumpkins but only two plants survived and they’re not really flourishing. I think I should try and get things started earlier next season.

There’s some corn that’s getting ready to flower, so hopefully we’ll have some corn cobs down the track.

Gala applesWe’ve got two apple trees that were planted almost 5 years ago. The ‘pink lady’ has fruited for the last couple of years, but this season is the first that we’ve had fruit set on the ‘gala’. Not sure if it just took a while to get ready, or if I pruned the wrong bits in winter previously.


Unripe QuinceNarelle planted a Quince tree behind our back fence a just over a year ago. It’s got some fruit growing on it, which hopefully will ripen as we approach winter