Update: Sam Saffron has fixed this issue in the latest version of Mvc-Mini-Profiler.
It took days to figure out why Firefox was aborting all requests after my login screen. So, I will make the conclusion of my search bold and underlined:
If you are using Mvc-mini-profiler and only logging to the database, you will eventually come to a time when the number of GUIDs that Mvc-mini-profiler inserts into your HTTP responses (X-MiniProfiler-Id headers) will grow to the point where Firefox will silently drop any requests to your website. Firefox will show GET requests with undefined response codes and refuse to load any further pages from your site until the Mvc-Mini-Profiler is turned off.
The fix for this is to create a custom SqlStorage provider for Mvc-mini-profiler and override the HasUserViewed field. Here is my attempt at this:
public class MvcMiniProfilerStorage : SqlServerStorage
{
public MvcMiniProfilerStorage(string connectionString)
: base(connectionString)
{
}
/// <summary>
/// Stores to dbo.MiniProfilers under its ;
/// stores all child Timings and SqlTimings to their respective tables.
/// </summary>
public override void Save(MiniProfiler profiler)
{
const string sql =
@"insert into MiniProfilers
(Id,
Name,
Started,
MachineName,
[User],
Level,
RootTimingId,
DurationMilliseconds,
DurationMillisecondsInSql,
HasSqlTimings,
HasDuplicateSqlTimings,
HasTrivialTimings,
HasAllTrivialTimings,
TrivialDurationThresholdMilliseconds,
HasUserViewed)
select @Id,
@Name,
@Started,
@MachineName,
@User,
@Level,
@RootTimingId,
@DurationMilliseconds,
@DurationMillisecondsInSql,
@HasSqlTimings,
@HasDuplicateSqlTimings,
@HasTrivialTimings,
@HasAllTrivialTimings,
@TrivialDurationThresholdMilliseconds,
@HasUserViewed
where not exists (select 1 from MiniProfilers where Id = @Id)";
// this syntax works on both mssql and sqlite
using (DbConnection conn = GetOpenConnection())
{
int insertCount = conn.Execute(sql,
new
{
profiler.Id,
Name = Truncate(profiler.Name, 200),
profiler.Started,
MachineName = Truncate(profiler.MachineName, 100),
User = Truncate(profiler.User, 100),
profiler.Level,
RootTimingId = profiler.Root.Id,
profiler.DurationMilliseconds,
profiler.DurationMillisecondsInSql,
profiler.HasSqlTimings,
profiler.HasDuplicateSqlTimings,
profiler.HasTrivialTimings,
profiler.HasAllTrivialTimings,
profiler.TrivialDurationThresholdMilliseconds,
// BUG: Too many X-MiniProfiler-Id headers cause
// Firefox to stop all requests
//
// This hack marks all entries as read so that
// they do not end up part of that header.
HasUserViewed = true
});
if (insertCount > 0)
{
SaveTiming(conn, profiler, profiler.Root);
}
}
}
private static string Truncate(string s, int maxLength)
{
return s != null && s.Length >
maxLength ? s.Substring(0, maxLength) : s;
}
}
Then it’s a simple matter of making sure that the Mvc-mini-profiler uses your version of this class rather than it’s own SqlServerStorage class.
MiniProfiler.Settings.Storage = new MvcMiniProfilerStorage("connStr");
This should take care of your Mvc-Mini-Profiler headaches.


