-
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.</p>
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 inC:\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
-
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>
-
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:
Youssef also shows how to create a handler using WebAPI, and server-side configuration to enable IIS WebSocket support.