Wednesday, 30 October 2013

How to enable Kerberos Delegation in Google Chrome

* Using Registry Key

Set/Add this string registry key

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
Name: AuthNegotiateDelegateWhitelist
Value: *

* Using Command Line param

--auth-negotiate-delegate-whitelist=*

Delegation can be restricted to servers in the specific domain

*.mydomain.com

I’ve tested it with IIS + SQL Server and double hop delegation works fine.

You can read more about Google Chrome command line params here.

Tuesday, 22 October 2013

Remote debugging IIS Web Application from Visual Studio

Setup your debug environment as described in Remote debugging from Visual Studio post.

When you click ‘Attach’ select w3wp.exe process. If you’re running Application Pools with multiple version of .Net you might see more than one process so make sure you select the correct one.

DelegConfig Kerberos Delegation Configuration Reporting Tool by Brian Murphy-Booth

DelegConfig is an ASP.Net application to test Kerberos/Delegation configuration on your IIS & SQL Server. Useful for testing double hop authentication issues.

IIS Windows Authentication/Delegation issue with C# Parallel Tasks

When you use double-hop authentication (WebBrowser->IIS->SQL Server) code executed on the webserver inside Parallel.Invoke() or Task.Factory.StartNew() is no longer executed as authenticated user (domain\username) but is being changed to (domain\iisservername$). You can see it in Environment.UserName when debuging. So if you're executing any SQL queries as Tasks you might get permission denied errors.

The way to fix it is to pass custom TaskScheduler from CurrentSynchronizationContext

Parallel.Invoke(
  new ParallelOptions()
  {
    TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()
  },
  () => { /*do something here;*/ },
);
 
Task.Factory.StartNew(
  () => { /*do something here;*/ }, 
  CancellationToken.None, 
  TaskCreationOptions.None,
  TaskScheduler.FromCurrentSynchronizationContext()
);

This is a good article about SynchronizationContext It's All About the SynchronizationContext

Thursday, 17 October 2013

SQL Copy data in batches

-- SOURCE TABLE
DECLARE @Table1 TABLE
(
  AsOf DATETIME,
  Company VARCHAR(50),
  Name VARCHAR(50)
)
 
INSERT INTO @Table1
SELECT '20130101','Company1','John'
UNION SELECT '20130102','Company2','Tom'
UNION SELECT '20130101','Company3','Peter'
UNION SELECT '20130102','Company4','Ian'
 
-- DESTINATION TABLE
DECLARE @Table2 TABLE
(
  AsOf DATETIME,
  Company VARCHAR(50),
  Name VARCHAR(50)
)
 
-- BATCH TABLE
DECLARE @Batches TABLE
(
  AsOf DATETIME
)
 
INSERT INTO @Batches
SELECT DISTINCT AsOf FROM @Table1
 
-- COPY IN BATCHES
DECLARE @AsOf DATETIME
WHILE (Exists(SELECT 1 FROM @Batches))
BEGIN TRY  
  BEGIN TRAN   
    SELECT @AsOf = MIN(AsOf) FROM @Batches
    PRINT CONVERT(VARCHAR(20),GETDATE(),20) + ',' + 'Copying data for: '+convert(VARCHAR(8),@AsOf,112)
 
    INSERT INTO @Table2 (
      AsOf,
      Company,
      Name
    )
    SELECT
      AsOf,
      Company,
      Name
    FROM @Table1
    WHERE AsOf = @AsOf
 
    DELETE FROM @Batches WHERE AsOf = @AsOf
  COMMIT TRAN 
END TRY
BEGIN CATCH 
  ROLLBACK
END CATCH
 
-- SHOW RESULTS
SELECT * FROM @Table2

Monday, 14 October 2013

C# Convert double to decimal

This is a workaround to Convert.ToDecimal(Double) limitation of 15 significant digits by using ‘R’ Round-trip Format Specifier.

Convert.ToDecimal Method (Double)
“The
Decimal value returned by this method contains a maximum of 15 significant digits. If the value parameter contains more than 15 significant digits, it is rounded using rounding to nearest. The following example illustrates how the Convert.ToDecimal(Double) method uses rounding to nearest to return a Decimal value with 15 significant digits.”

decimal.Parse(dbl.ToString("R"))
[Test]
public void ConvertDoubleToDecimal()
{
  Compare(1.00000000000006d,  1.00000000000006M);
  Compare(1.00000000000004d,  1.00000000000004M);
  Compare(1.000000000000066d, 1.000000000000066M);
  Compare(1.000000000000044d, 1.000000000000044M);
}
 
private void Compare(double dbl, decimal dec)
{
  Convert.ToDecimal("0.d0d.");
  var d1 = Convert.ToDecimal(dbl);
  var d2 = new Decimal(dbl);
  var d3 = decimal.Parse(dbl.ToString("R"));
  Console.WriteLine(@"
DOUBLE : {0:R}
CONVERT: {1} {2}
NEW  : {3} {4}
'R'  : {5} {6}", 
      dbl, 
      d1, d1.Equals(dec) ? "OK" : "FAILED",
      d2, d2.Equals(dec) ? "OK" : "FAILED", 
      d3, d3.Equals(dec) ? "OK" : "FAILED");
}
DOUBLE : 1.00000000000006
CONVERT: 1.00000000000006 OK
NEW    : 1.00000000000006 OK
'R'    : 1.00000000000006 OK
 
DOUBLE : 1.00000000000004
CONVERT: 1.00000000000004 OK
NEW    : 1.00000000000004 OK
'R'    : 1.00000000000004 OK
 
DOUBLE : 1.000000000000066
CONVERT: 1.00000000000007 FAILED
NEW    : 1.00000000000007 FAILED
'R'    : 1.000000000000066 OK
 
DOUBLE : 1.000000000000044
CONVERT: 1.00000000000004 FAILED
NEW    : 1.00000000000004 FAILED
'R'    : 1.000000000000044 OK

Friday, 13 September 2013

IComparable<> inheritance in SortedDictionary

[Test]
public void Test()
{
  var dic = new SortedDictionary<BaseClass, string>();
  dic.Add(new BaseClass(){Number = 1}, "");
  dic.Add(new ExtendClass(){Text = "One"}, "");
 
  Assert.True(dic.ContainsKey(new BaseClass() { Number = 1 }));
  Assert.False(dic.ContainsKey(new BaseClass() { Number = 2 }));
  Assert.True(dic.ContainsKey(new ExtendClass() { Text = "One" }));
  Assert.False(dic.ContainsKey(new ExtendClass() { Text = "Two" }));
}
 
public class BaseClass : IComparable<BaseClass>
{
  public int Number { get; set; }
 
  public virtual int CompareTo(BaseClass other)
  {        
    return Number.CompareTo(other.Number);
  }
}
 
public class ExtendClass : BaseClass, IComparable<ExtendClass>
{
  public string Text { get; set; }
 
  public override int CompareTo(BaseClass other)
  {
    var other2 = other as ExtendClass;
    return other2 == null ? base.CompareTo(other) : CompareTo(other2);
  }
 
  public int CompareTo(ExtendClass other)
  {        
    return Text.CompareTo(other.Text);
  }
}

Tuesday, 10 September 2013

Exception handling in multithreaded C#

try
{
  Parallel.Invoke(
    () =>
    {
      Console.WriteLine("Starting Job 1..");
      Thread.Sleep(3*1000);
      Console.WriteLine("Starting Job 1.. SUCCESS");
    },
    () =>
    {
      Console.WriteLine("Starting Job 2..");
      throw new Exception("Job 2 Failed");
    }
  );
}
catch (AggregateException ex)
{
  Console.WriteLine(ex);
  foreach (var innerEx in ex.InnerExceptions)
  {
    Console.WriteLine(innerEx);
  }        
}

How to find PID of Windows Service

sc queryex <servicename>

Friday, 31 May 2013

C# Convert List IEnumerable<T> to 2D multi-dimensional array

//extension method
public static object[,] To2DArray<T>(this IEnumerable<T> lines, params Func<T, object>[] lambdas)
{
  var array = new object[lines.Count(), lambdas.Count()];
  var lineCounter = 0;
  lines.ForEach(line =>
  {
    for (var i = 0; i < lambdas.Length; i++)
    {
      array[lineCounter, i] = lambdas[i](line);
    }
    lineCounter++;
  });
  return array;
}
 
[Test]
public void Test()
{
  var lines = new List<Line>();
  lines.Add(new Line() { Id=1, Name="One", Age=25 });
  lines.Add(new Line() { Id = 2, Name = "Two", Age = 35 });
  lines.Add(new Line() { Id = 3, Name = "Three", Age = 45 });
 
  //Convert to 2d array
  //[1,One,25]
  //[2,Two,35]
  //[3,Three,45]
  var range = lines.To2DArray(x => x.Id, x => x.Name, x=> x.Age);
 
  //test the result
  for(var i=0;i<lines.Count;i++)
  {
    for(var j=0;j<3;j++)//3 lambdas passed to function
    {
      Console.Write(range[i,j]+",");
    }
    Console.WriteLine();
  }
}
 
class Line
{
  public int Id { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }
}

Thursday, 9 May 2013

MVC4 auto refresh partial view

* Create new MVC4 application and make sure you configure unobtrusive-ajax as described in How to use MVC3 with AJAX

* Create Controller /Controllers/HomeController.cs

public class HomeController : Controller
{
  public ActionResult Index()
  {
    var model = new ViewModel();
    model.Now = DateTime.Now.ToString();
    return View(model);
  }
 
  public ActionResult Refresh()
  {
    var model = new ViewModel();
    model.Now = DateTime.Now.ToString();
    return PartialView("IndexPartial", model);
  }
}
 
public class ViewModel
{
  public string Now { get; set; }
}

* Create view /Views/Home/Index.cshtml

@using MVCTest.Controllers
@{
  ViewBag.Title = "Index";
}
<h2>Index</h2>
<a id="button" title="Refresh now">Refresh Now</a>
<a id="toggleButton" title="Auto refresh every 5 seconds">Auto Refresh</a>
 
<div id="PartialDiv">
  @Html.Partial("IndexPartial", (ViewModel)Model)  
</div>
 
<script type="text/javascript">
 
  var autoRefresh = false;
  var autoRefreshInterval = 1000 * 5;   //mili seconds (set to 5 seconds)
 
  $(document).ready(function () {
    $('a#button').click(function () {
      $('#PartialDiv').load('@Url.Action("Refresh", "Home")');
    });
 
    $('a#toggleButton').click(function () {
      $('#PartialDiv').load('@Url.Action("Refresh", "Home")');
      $(this).toggleClass("down");
      if ($(this).is('.down')) {
        autoRefresh = true;
      } else {
        autoRefresh = false;
      }
    });
 
    var refresh = function () {
      if (autoRefresh) {
        $('#PartialDiv').load('@Url.Action("Refresh", "Home")');
      }
      setTimeout(refresh, autoRefreshInterval);
    };
 
    refresh();
  });
</script>

* Create partial view /Views/Home/IndexPartial.cshtml

<h2>@Model.Now</h2>

* Add these css classes to your Site.css file

#button {
  cursor: pointer;
  font-weight: bold;
}
 
#toggleButton {
  color: darkred;
  font-weight: bold;
  cursor: pointer;
}
 
#toggleButton.down {
  color: green;
  font-weight: bold;
  cursor: pointer;
}

* The webpage should look like this with manual Refresh Now button and Auto Refresh toggle button

mvc4-autorefresh

Wednesday, 8 May 2013

Remote debugging from Visual Studio

Copy RemoteDebugger to remote machine from your local Visual Studio directory

(This is path for VS2010)

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Remote Debugger

Start remote debugging monitor on the server ‘msvsmon.exe’

Go to Tools/Options and select ‘No Authentication (native only)’ and ‘Allow any user to debug’

remote-debugging

In your Visual Studio select ‘Debug/Attach to Process’, specify Transport as ‘Remote (Native only with no authentication)’ and put your server name as Qualifier, click Refresh and you should see the list of processes on the remote machine.

Select the process you want to debug and click ‘Attach’

Using NuGet without committing packages to source control

Using NuGet without committing packages to source control

Thursday, 4 April 2013

C# ConcurrentQueue with limited number of items

public class LimitedConcurrentQueue<T> : ConcurrentQueue<T>
{
  public int Size { get; private set; }
 
  public LimitedConcurrentQueue(int size)
  {
    Size = size;
  }
 
  public new void Enqueue(T obj)
  {
    base.Enqueue(obj);
    lock (this)
    {
      while (base.Count > Size)
      {
        T outObj;
        base.TryDequeue(out outObj);
      }
    }
  }
}
 
[Test]
public void TestLimitedConcurrentQueue()
{
  var queue = new LimitedConcurrentQueue<int>(3);
  queue.Enqueue(1);
  queue.Enqueue(2);
  queue.Enqueue(3);
 
  Console.WriteLine(string.Join(",", queue.ToArray()));
  //gives 1,2,3
 
  queue.Enqueue(4);
 
  Console.WriteLine(string.Join(",", queue.ToArray()));
  //gives 2,3,4
}

Tuesday, 2 April 2013

C# LINQ inner and left outer join

Left outer join extension method is based on How to: Perform Left Outer Joins article.

[Test]
public void Test()
{
  var list1 = new List<int>() { 1, 2, 3, 4, 5}.Select(x=>new {a=x, b=x*x});
  var list2 = new List<int>() { 1, 2, 3, 4 }.Select(x => new { a = x, b = x * x * x });
 
  var innerJoin = list1.Join(list2, x => x.a, y => y.a, (x, y) => new {a = x.a, b = x.b, c = y.b});
 
  innerJoin.ForEach(Console.WriteLine);
 
  var leftOuterJoin = list1.LeftOuterJoin(list2, x => x.a, y => y.a, (x, y) => new { a = x.a, b = x.b, c = (y != null) ? y.b : (int?)null });
 
  leftOuterJoin.ForEach(Console.WriteLine);
}
public static class Extensions
{
  public static IEnumerable<TResult> LeftOuterJoin<TOuter, TInner, TKey, TResult>(
    this IEnumerable<TOuter> outer, 
    IEnumerable<TInner> inner, 
    Func<TOuter, TKey> outerKeySelector, 
    Func<TInner, TKey> innerKeySelector, 
    Func<TOuter, TInner, TResult> resultSelector)
  {
    return 
      from outerItem in outer
      join innerItem in inner on outerKeySelector(outerItem) equals innerKeySelector(innerItem) into gj
      from sub in gj.DefaultIfEmpty()
      select resultSelector(outerItem, sub);
  }
}

Wednesday, 27 March 2013

Run 32bit .Net application with >2GB RAM on 64bit machine

To allow your 32bit application use more than 2GB of RAM you need to modify the *.exe file with editbin utility. (open ‘Visual Studio Command Prompt’ and it will be on the path)

editbin /LARGEADDRESSAWARE <your-app.exe>

or just add these 2 lines to your Post-build event in Visual Studio

call "$(DevEnvDir)..\tools\vsvars32.bat"
editbin /LARGEADDRESSAWARE "$(TargetPath)"

or these if you are building your project with msbuild outside of Visual Studio

call "%VS100COMNTOOLS%\vsvars32.bat"
editbin /LARGEADDRESSAWARE "$(TargetPath)"

To check if all ok run dumpbin utility as below and check if the output has ‘Application can handle large (>2GB) addresses’ text in FILE HEADER VALUES.

dumpbin /headers <your-app.exe>

Tuesday, 5 March 2013

C# Extension to split IEnumerable into batches of n items

This code splits a list into a batches on n items. If list = (1,2,3,4,5,6,7,8,9,10) and n = 3 then the result is ((1,2,3),(4,5,6),(7,8,9),(10))
public static class Extensions
{
  public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> list, int batchSize)
  {
    int i = 0;
    return list.GroupBy(x => (i++ / batchSize)).ToList();
  }
}
[TestFixture]
public class TestExtensions
{
  [Test]
  public void TestBatch()
  {
    var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    var result = list.Batch(3).ToList();
    Assert.AreEqual(4, result.Count());
    Assert.AreEqual(3, result[0].Count());
    Assert.AreEqual(3, result[1].Count());
    Assert.AreEqual(3, result[2].Count());
    Assert.AreEqual(1, result[3].Count());
    result.ForEach(x=>Console.WriteLine(string.Join(",",x)));
  }
}