You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by fo...@apache.org on 2019/01/12 10:32:55 UTC

[avro] branch master updated: AVRO-2112: Target .NET Standard/Core in C# (#307)

This is an automated email from the ASF dual-hosted git repository.

fokko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a05375  AVRO-2112: Target .NET Standard/Core in C# (#307)
9a05375 is described below

commit 9a05375436385b7fce75d32cfdcd359e279e0628
Author: Brian Lachniet <bl...@gmail.com>
AuthorDate: Sat Jan 12 00:32:50 2019 -1000

    AVRO-2112: Target .NET Standard/Core in C# (#307)
    
    * AVRO-2161: Upgrade C# unit tests to NUnit 3
    
    * AVRO-2112: Update C# projects to target .NET Standard/Core and .NET Framework 4.0
    
    * AVRO-2112: Move C# IPC tests to a Avro.ipc.test
    
    * AVRO-2112: Ignore C# tests that use System.CodeDom compilation when targeting .NET Core
    
    See https://github.com/dotnet/corefx/issues/12180
    
    * AVRO-2112: Replace usage of JToken.ToString() in C# projects
    
    In Newtonsoft.Json v3.5, JToken.ToString() returned the raw JSON
    representation of the token. In later versions of
    Newtonsoft.Json, JToken.ToString() returns a simple string
    representation of the value. See the examples below:
    - v3.5: "\"Hello World\""
    - Later versions: "Hello World"
    
    In this commit, I've updated the project to work with later versions
    of Newtonsoft.Json as well as v3.5. I've replaced some usages of
    JToken.ToString(). When we need the raw JSON representation, we use
    JsonConvert.Serialize(). When we need the string value of a string
    JToken, we use JToken.Value<string>().
    
    * AVRO-2112: Update C# README
    
    * Update pom.xml with new C# paths to ignore for license check
    
    * csharp: Cut support for net35, update Dockerfile and csharp build.sh
    
    * Add mono-complete to Dockerfile for build
    
    * csharp: Remove unnecessary ProjectGuid elements from projects
    
    * Revert to only running tests for Avro.test.dll
    
    This is what we were doing on master. I was trying to run the IPC tests,
    but that has not seemed to work well in our automated builds.
    
    * List all tests as they are run
    
    * Add build.ps1 and update README
    
    * Update Target Frameworks table in README
    
    * Try disabling tests that take a long time to run
---
 lang/csharp/.gitignore                             |   3 +
 lang/csharp/Avro.nunit                             |  35 ----
 lang/csharp/Avro.sln                               |  47 +++--
 lang/csharp/README                                 |  40 ----
 lang/csharp/README.md                              |  42 ++++
 lang/csharp/build.ps1                              |  59 ++++++
 lang/csharp/build.sh                               |  13 +-
 lang/csharp/lib/main/Castle.Core.dll               | Bin 430592 -> 0 bytes
 lang/csharp/lib/main/Newtonsoft.Json.dll           | Bin 319488 -> 0 bytes
 lang/csharp/lib/main/log4net.dll                   | Bin 270336 -> 0 bytes
 lang/csharp/lib/test/nunit.framework.dll           | Bin 135168 -> 0 bytes
 lang/csharp/src/apache/codegen/Avro.codegen.csproj | 196 ++++--------------
 .../src/apache/ipc.test/Avro.ipc.test.csproj       |  61 ++++++
 .../GeneratedFiles/org/apache/avro/test/All.cs     |   0
 .../org/apache/avro/test/AllCallback.cs            |   0
 .../GeneratedFiles/org/apache/avro/test/AllEnum.cs |   0
 .../org/apache/avro/test/AllTestRecord.cs          |   0
 .../org/apache/avro/test/AllTestRecordPartial.cs   |   0
 .../org/apache/avro/test/FixedTest.cs              |   0
 .../GeneratedFiles/org/apache/avro/test/Kind.cs    |   0
 .../GeneratedFiles/org/apache/avro/test/MD5.cs     |   0
 .../GeneratedFiles/org/apache/avro/test/Mail.cs    |   0
 .../org/apache/avro/test/MailCallback.cs           |   0
 .../GeneratedFiles/org/apache/avro/test/Message.cs |   0
 .../GeneratedFiles/org/apache/avro/test/Simple.cs  |   0
 .../org/apache/avro/test/SimpleCallback.cs         |   0
 .../org/apache/avro/test/TestError.cs              |   0
 .../org/apache/avro/test/TestRecord.cs             |   0
 .../org/apache/avro/test/TestRecordExtensions.cs   |   0
 .../org/apache/avro/test/TestRecordWithUnion.cs    |   0
 .../{test/Ipc => ipc.test}/HttpClientServerTest.cs |   6 +-
 .../{test/Ipc => ipc.test}/LocalTransceiverTest.cs |   0
 .../apache/{test/Ipc => ipc.test}/MailResponder.cs |   6 +-
 .../src/apache/ipc.test/Properties/AssemblyInfo.cs |  33 +++
 .../{test/Ipc => ipc.test}/SerializationTest.cs    |   8 +-
 .../SocketServerConcurrentExecutionTest.cs         |   0
 .../{test/Ipc => ipc.test}/SocketServerTest.cs     |   8 +-
 .../SocketServerWithCallbacksTest.cs               |  42 ++--
 .../SocketTransceiverWhenServerStopsTest.cs        |   0
 lang/csharp/src/apache/ipc/Avro.ipc.csproj         | 145 ++++----------
 lang/csharp/src/apache/main/Avro.main.csproj       | 173 ++--------------
 .../apache/main/Properties/Settings.Designer.cs    |  44 ----
 lang/csharp/src/apache/main/Schema/JsonHelper.cs   |   3 +-
 lang/csharp/src/apache/main/Schema/Property.cs     |   2 +-
 lang/csharp/src/apache/msbuild/Avro.msbuild.csproj |  69 ++-----
 lang/csharp/src/apache/perf/Avro.perf.csproj       | 130 +-----------
 lang/csharp/src/apache/test/Avro.test.csproj       | 222 +++++----------------
 lang/csharp/src/apache/test/CodGen/CodeGenTest.cs  |  10 +-
 lang/csharp/src/apache/test/File/FileTests.cs      |  22 +-
 .../csharp/src/apache/test/Generic/GenericTests.cs | 140 ++++++++-----
 .../src/apache/test/Protocol/ProtocolTest.cs       |  20 +-
 lang/csharp/src/apache/test/Schema/AliasTest.cs    |  26 +--
 .../apache/test/Schema/SchemaNormalizationTests.cs |  10 +-
 lang/csharp/src/apache/test/Schema/SchemaTests.cs  |  37 ++--
 .../src/apache/test/Specific/SpecificTests.cs      |   7 +-
 .../src/apache/test/Utils/CaseFinderTests.cs       |   5 +-
 pom.xml                                            |   4 +-
 share/docker/Dockerfile                            |  17 +-
 58 files changed, 619 insertions(+), 1066 deletions(-)

diff --git a/lang/csharp/.gitignore b/lang/csharp/.gitignore
index b8e088c..944e701 100644
--- a/lang/csharp/.gitignore
+++ b/lang/csharp/.gitignore
@@ -17,6 +17,9 @@
 /*.user
 /*.suo
 /_ReSharper.Avro
+/.vs
+obj/
+
 ## Ignore Visual Studio temporary files, build results, and
 ## files generated by popular Visual Studio add-ons.
 
diff --git a/lang/csharp/Avro.nunit b/lang/csharp/Avro.nunit
deleted file mode 100644
index 7cbd799..0000000
--- a/lang/csharp/Avro.nunit
+++ /dev/null
@@ -1,35 +0,0 @@
-<!--
-  - Licensed to the Apache Software Foundation (ASF) under one
-  - or more contributor license agreements.  See the NOTICE file
-  - distributed with this work for additional information
-  - regarding copyright ownership.  The ASF licenses this file
-  - to you under the Apache License, Version 2.0 (the
-  - "License"); you may not use this file except in compliance
-  - with the License.  You may obtain a copy of the License at
-  -
-  -   http://www.apache.org/licenses/LICENSE-2.0
-  -
-  - Unless required by applicable law or agreed to in writing,
-  - software distributed under the License is distributed on an
-  - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  - KIND, either express or implied.  See the License for the
-  - specific language governing permissions and limitations
-  - under the License.
-  -->
-<NUnitProject>
-  <Settings activeconfig="Release" />
-  <Config name="Debug" binpathtype="Auto">
-    <assembly path="build/test/Debug/Avro.test.dll" />
-    <assembly path="build/test/Debug/Avro.dll" />
-	<assembly path="lib/main/Castle.Core.dll" />
-    <assembly path="lib/main/Newtonsoft.Json.dll" />
-    <assembly path="lib/test/nunit.framework.dll" />
-  </Config>
-  <Config name="Release" binpathtype="Auto">
-    <assembly path="build/test/Release/Avro.test.dll" />
-    <assembly path="build/test/Release/Avro.dll" />
-	<assembly path="lib/main/Castle.Core.dll" />
-    <assembly path="lib/main/Newtonsoft.Json.dll" />
-    <assembly path="lib/test/nunit.framework.dll" />
-  </Config>
-</NUnitProject>
diff --git a/lang/csharp/Avro.sln b/lang/csharp/Avro.sln
index 58687b2..6a88459 100644
--- a/lang/csharp/Avro.sln
+++ b/lang/csharp/Avro.sln
@@ -1,20 +1,24 @@
 
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avro.main", "src\apache\main\Avro.main.csproj", "{A0A5CA3C-F58C-4D07-98B0-2C7B62AB20F0}"
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27428.2027
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avro.main", "src\apache\main\Avro.main.csproj", "{A0A5CA3C-F58C-4D07-98B0-2C7B62AB20F0}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avro.test", "src\apache\test\Avro.test.csproj", "{911D56AB-587B-4E5F-B5EA-D47D8A46F1FA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avro.test", "src\apache\test\Avro.test.csproj", "{911D56AB-587B-4E5F-B5EA-D47D8A46F1FA}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avro.codegen", "src\apache\codegen\Avro.codegen.csproj", "{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avro.codegen", "src\apache\codegen\Avro.codegen.csproj", "{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avro.ipc", "src\apache\ipc\Avro.ipc.csproj", "{3B05043A-DC6C-49B6-85BF-9AB055D0B414}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avro.ipc", "src\apache\ipc\Avro.ipc.csproj", "{3B05043A-DC6C-49B6-85BF-9AB055D0B414}"
 	ProjectSection(ProjectDependencies) = postProject
 		{AEB22F94-4ECF-4008-B159-389B3F05D54B} = {AEB22F94-4ECF-4008-B159-389B3F05D54B}
 	EndProjectSection
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avro.msbuild", "src\apache\msbuild\Avro.msbuild.csproj", "{AEB22F94-4ECF-4008-B159-389B3F05D54B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avro.msbuild", "src\apache\msbuild\Avro.msbuild.csproj", "{AEB22F94-4ECF-4008-B159-389B3F05D54B}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avro.perf", "src\apache\perf\Avro.perf.csproj", "{AC4E1909-2594-4D01-9B2B-B832C07BAFE5}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avro.perf", "src\apache\perf\Avro.perf.csproj", "{AC4E1909-2594-4D01-9B2B-B832C07BAFE5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avro.ipc.test", "src\apache\ipc.test\Avro.ipc.test.csproj", "{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -50,14 +54,14 @@ Global
 		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
 		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
-		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Debug|x86.ActiveCfg = Debug|x86
-		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Debug|x86.Build.0 = Debug|x86
+		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Debug|x86.Build.0 = Debug|Any CPU
 		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|Any CPU.Build.0 = Release|Any CPU
-		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|Mixed Platforms.ActiveCfg = Release|x86
-		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|Mixed Platforms.Build.0 = Release|x86
-		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|x86.ActiveCfg = Release|x86
-		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|x86.Build.0 = Release|x86
+		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|x86.ActiveCfg = Release|Any CPU
+		{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}.Release|x86.Build.0 = Release|Any CPU
 		{3B05043A-DC6C-49B6-85BF-9AB055D0B414}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{3B05043A-DC6C-49B6-85BF-9AB055D0B414}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{3B05043A-DC6C-49B6-85BF-9AB055D0B414}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -88,8 +92,23 @@ Global
 		{AC4E1909-2594-4D01-9B2B-B832C07BAFE5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
 		{AC4E1909-2594-4D01-9B2B-B832C07BAFE5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 		{AC4E1909-2594-4D01-9B2B-B832C07BAFE5}.Release|x86.ActiveCfg = Release|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Debug|x86.Build.0 = Debug|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Release|x86.ActiveCfg = Release|Any CPU
+		{A5C8B22C-BC43-4763-8B92-EB0CEA739ED1}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {ACE75CE8-16B2-4C6E-A5BE-B6F6DB5FE095}
+	EndGlobalSection
 EndGlobal
diff --git a/lang/csharp/README b/lang/csharp/README
deleted file mode 100644
index 34909dd..0000000
--- a/lang/csharp/README
+++ /dev/null
@@ -1,40 +0,0 @@
-1. Building Avro for .NET
-
-a. Windows
-
-Prerequisites
-    Microsoft Visual C# Express 2010
-
-To build open Avro.sln solution in VC# Express 2010 and build from there.
-
-b. Linux
-
-Prerequisites
-    Mono 2.6 or above.
-    
-For Ubuntu Lucid Lynx, mono that comes with it is 2.4. To install mono 2.6
-follow the procedure described at http://badgerports.org/
-
-To build issue the command:
-$ cd lang/csharp
-
-then
-
-$ CONFIGURATION=Release TARGETFRAMEWORKVERSION=3.5 xbuild Avro.sln
-
-or 
-
-$ CONFIGURATION=Debug TARGETFRAMEWORKVERSION=3.5 xbuild Avro.sln
-
-Note: In Ubuntu 12.04 (Precise Pangolin), please omit TARGETFRAMEWORKVERSION argument and leave it to the default.
-
-2. Unit tests
-
-This is a common procedure for both Windows and Linux.
-
-To run unit-tests, please install NUnit 2.5 or above. From within the NUnit
-GUI, open the project Avro.nunit and run the tests.
-
-3. Notes
-
-a. The LICENSE and NOTICE files in the lang/csharp source directory are used to build the binary distribution. The LICENSE and NOTICE information for the Avro C# source distribution is in the root directory.
diff --git a/lang/csharp/README.md b/lang/csharp/README.md
new file mode 100644
index 0000000..35d1976
--- /dev/null
+++ b/lang/csharp/README.md
@@ -0,0 +1,42 @@
+# Avro C#
+
+## Build & Test
+
+### Windows
+
+1. Install [Microsoft Visual Studio Community 2017](https://www.visualstudio.com/downloads/)
+2. `./build.ps1 Test`
+
+### Linux with Mono
+
+1. Install [Mono v5.18+](https://www.mono-project.com/download/stable/). Install the **mono-devel**
+   and **mono-complete** packages.
+2. `./build.sh test`
+
+### Linux with .NET Core SDK
+
+1. Install [.NET Core SDK 2.1+](https://www.microsoft.com/net/download/linux)
+2. Build and run unit tests:
+    ```
+    cd src/apache/test
+    dotnet test --framework netcoreapp2.0
+    ```
+
+## Target Frameworks
+
+The table below shows the frameworks that the various projects target.
+
+Project       | Type         | .NET Standard 2.0  | .NET Core 2.0      | .NET Framework 4.0
+------------  | ------------ |:------------------:|:------------------:|:------------------:
+Avro.codegen  | Exe          |                    | :heavy_check_mark: | :heavy_check_mark:
+Avro.ipc      | Library      |                    |                    | :heavy_check_mark:
+Avro.ipc.test | Unit Tests   |                    |                    | :heavy_check_mark:
+Avro.main     | Exe          | :heavy_check_mark: |                    | :heavy_check_mark:
+Avro.msbuild  | Library      | :heavy_check_mark: |                    | :heavy_check_mark:
+Avro.perf     | Exe          |                    | :heavy_check_mark: | :heavy_check_mark:
+Avro.test     | Unit Tests   |                    | :heavy_check_mark: | :heavy_check_mark:
+
+
+## Notes
+
+The [LICENSE](./LICENSE) and [NOTICE](./NOTICE) files in the lang/csharp source directory are used to build the binary distribution. The [LICENSE.txt](../../LICENSE.txt) and [NOTICE.txt](../../NOTICE.txt) information for the Avro C# source distribution is in the root directory.
diff --git a/lang/csharp/build.ps1 b/lang/csharp/build.ps1
new file mode 100644
index 0000000..edb8411
--- /dev/null
+++ b/lang/csharp/build.ps1
@@ -0,0 +1,59 @@
+#!/usr/bin/env pwsh
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+param(
+    [Parameter(Position=0)]
+    [ValidateSet('Test')]
+    [string]
+    $Target = 'Test',
+
+    [Parameter()]
+    [ValidateSet('Release', 'Debug')]
+    [string]
+    $Configuration = 'Release'
+)
+
+# Catch any PowerShell errors and exit with a non-zero exit code.
+$ErrorActionPreference = 'Stop'
+trap {
+    $ErrorActionPreference = 'Continue'
+    Write-Error $_
+    exit 1
+}
+
+# Checks the LASTEXITCODE. If it is non-zero, exits with that code.
+function checkExitCode {
+    if ($LASTEXITCODE) {
+        exit $LASTEXITCODE
+    }
+}
+
+try {
+    Push-Location $PSScriptRoot
+
+    switch ($Target) {
+        "Test" {
+            dotnet build --configuration $Configuration
+            checkExitCode
+
+            dotnet test --configuration $Configuration --no-build ./src/apache/test/Avro.test.csproj
+            checkExitCode
+        }
+    }
+} finally {
+    Pop-Location
+}
diff --git a/lang/csharp/build.sh b/lang/csharp/build.sh
index cb9f7fc..b84d3ad 100755
--- a/lang/csharp/build.sh
+++ b/lang/csharp/build.sh
@@ -23,24 +23,23 @@ cd `dirname "$0"`                  # connect to root
 ROOT=../..
 VERSION=`cat $ROOT/share/VERSION.txt`
 
-export CONFIGURATION=Release
-export TARGETFRAMEWORKVERSION=v3.5
-
 case "$1" in
 
   test)
-    xbuild
-    nunit-console Avro.nunit
+    msbuild /t:"restore;build" /p:"Configuration=Release"
+    mono ${HOME}/.nuget/packages/nunit.consolerunner/3.9.0/tools/nunit3-console.exe \
+      --noheader --labels=All \
+      src/apache/test/bin/Release/net40/Avro.test.dll
     ;;
 
   perf)
-    xbuild
+    msbuild /t:"restore;build" /p:"Configuration=Release"
     mono build/perf/Release/Avro.perf.exe
     ;;
 
   dist)
     # build binary tarball
-    xbuild
+    msbuild /t:"restore;build" /p:"Configuration=Release"
     # add the binary LICENSE and NOTICE to the tarball
     cp LICENSE NOTICE build/
     mkdir -p $ROOT/dist/csharp
diff --git a/lang/csharp/lib/main/Castle.Core.dll b/lang/csharp/lib/main/Castle.Core.dll
deleted file mode 100644
index ccc7d5f..0000000
Binary files a/lang/csharp/lib/main/Castle.Core.dll and /dev/null differ
diff --git a/lang/csharp/lib/main/Newtonsoft.Json.dll b/lang/csharp/lib/main/Newtonsoft.Json.dll
deleted file mode 100644
index 4703b89..0000000
Binary files a/lang/csharp/lib/main/Newtonsoft.Json.dll and /dev/null differ
diff --git a/lang/csharp/lib/main/log4net.dll b/lang/csharp/lib/main/log4net.dll
deleted file mode 100644
index ffc57e1..0000000
Binary files a/lang/csharp/lib/main/log4net.dll and /dev/null differ
diff --git a/lang/csharp/lib/test/nunit.framework.dll b/lang/csharp/lib/test/nunit.framework.dll
deleted file mode 100644
index 639dbb0..0000000
Binary files a/lang/csharp/lib/test/nunit.framework.dll and /dev/null differ
diff --git a/lang/csharp/src/apache/codegen/Avro.codegen.csproj b/lang/csharp/src/apache/codegen/Avro.codegen.csproj
index 695929e..9a716c5 100644
--- a/lang/csharp/src/apache/codegen/Avro.codegen.csproj
+++ b/lang/csharp/src/apache/codegen/Avro.codegen.csproj
@@ -1,162 +1,34 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{BF0D313C-1AA3-4900-B277-B0F5F9DDCDA8}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avro.codegen</RootNamespace>
-    <AssemblyName>avrogen</AssemblyName>
-    <TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v3.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>3.5</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\..\build\codegen\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugType>none</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\..\build\codegen\Release\</OutputPath>
-    <DefineConstants>
-    </DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
-    <DebugSymbols>true</DebugSymbols>
-    <OutputPath>..\..\..\build\codegen\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <CodeAnalysisLogFile>..\..\..\build\codegen\Debug\avrogen.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
-    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
-    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
-    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
-    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
-    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
-    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
-    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
-    <OutputPath>..\..\..\build\codegen\Release\</OutputPath>
-    <DefineConstants>
-    </DefineConstants>
-    <Optimize>true</Optimize>
-    <DebugType>none</DebugType>
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <CodeAnalysisLogFile>..\..\..\build\codegen\Release\avrogen.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
-    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
-    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
-    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
-    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
-    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
-    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
-    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
-    <OutputPath>..\..\..\build\codegen\Release\</OutputPath>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SignAssembly>true</SignAssembly>
-  </PropertyGroup>
-  <PropertyGroup>
-    <AssemblyOriginatorKeyFile>..\..\..\Avro.snk</AssemblyOriginatorKeyFile>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="AvroGen.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\main\Avro.main.csproj">
-      <Project>{A0A5CA3C-F58C-4D07-98B0-2C7B62AB20F0}</Project>
-      <Name>Avro.main</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <BootstrapperPackage Include=".NETFramework,Version=v3.5">
-      <Visible>False</Visible>
-      <ProductName>Microsoft .NET Framework 3.5 %28x86 and x64%29</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
-      <Visible>False</Visible>
-      <ProductName>Windows Installer 3.1</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="app.config" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFrameworks>net40;netcoreapp2.0</TargetFrameworks>
+    <AssemblyName>avrogen</AssemblyName>
+    <RootNamespace>Avro.codegen</RootNamespace>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>..\..\..\Avro.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\main\Avro.main.csproj" />
+  </ItemGroup>
+
+</Project>
+
diff --git a/lang/csharp/src/apache/ipc.test/Avro.ipc.test.csproj b/lang/csharp/src/apache/ipc.test/Avro.ipc.test.csproj
new file mode 100644
index 0000000..1627241
--- /dev/null
+++ b/lang/csharp/src/apache/ipc.test/Avro.ipc.test.csproj
@@ -0,0 +1,61 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFrameworks>net40</TargetFrameworks>
+    <RootNamespace>Avro.ipc.test</RootNamespace>
+    <AssemblyName>Avro.ipc.test</AssemblyName>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Include="..\..\..\..\..\share\test\schemas\mail.avpr">
+      <Link>mail.avpr</Link>
+    </EmbeddedResource>
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="nunit">
+      <Version>3.10.1</Version>
+    </PackageReference>
+    <PackageReference Include="nunit3testadapter">
+      <Version>3.10.0</Version>
+    </PackageReference>
+    <PackageReference Include="NUnit.ConsoleRunner">
+      <Version>3.9.0</Version>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup Condition="'$(TargetFramework)'!='netcoreapp2.0'">
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.1" />
+  </ItemGroup>
+
+  <ItemGroup Condition="'$(TargetFramework)'=='netcoreapp2.0'">
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\ipc\Avro.ipc.csproj" />
+    <ProjectReference Include="..\main\Avro.main.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+  </ItemGroup>
+
+</Project>
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/All.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/All.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/All.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/All.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/AllCallback.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/AllCallback.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/AllCallback.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/AllCallback.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/AllEnum.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/AllEnum.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/AllEnum.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/AllEnum.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/AllTestRecord.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/AllTestRecord.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/AllTestRecord.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/AllTestRecord.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/AllTestRecordPartial.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/AllTestRecordPartial.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/AllTestRecordPartial.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/AllTestRecordPartial.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/FixedTest.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/FixedTest.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/FixedTest.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/FixedTest.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/Kind.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/Kind.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/Kind.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/Kind.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/MD5.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/MD5.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/MD5.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/MD5.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/Mail.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/Mail.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/Mail.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/Mail.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/MailCallback.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/MailCallback.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/MailCallback.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/MailCallback.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/Message.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/Message.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/Message.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/Message.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/Simple.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/Simple.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/Simple.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/Simple.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/SimpleCallback.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/SimpleCallback.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/SimpleCallback.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/SimpleCallback.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/TestError.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/TestError.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/TestError.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/TestError.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/TestRecord.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/TestRecord.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/TestRecord.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/TestRecord.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/TestRecordExtensions.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/TestRecordExtensions.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/TestRecordExtensions.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/TestRecordExtensions.cs
diff --git a/lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/TestRecordWithUnion.cs b/lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/TestRecordWithUnion.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/GeneratedFiles/org/apache/avro/test/TestRecordWithUnion.cs
rename to lang/csharp/src/apache/ipc.test/GeneratedFiles/org/apache/avro/test/TestRecordWithUnion.cs
diff --git a/lang/csharp/src/apache/test/Ipc/HttpClientServerTest.cs b/lang/csharp/src/apache/ipc.test/HttpClientServerTest.cs
similarity index 97%
rename from lang/csharp/src/apache/test/Ipc/HttpClientServerTest.cs
rename to lang/csharp/src/apache/ipc.test/HttpClientServerTest.cs
index 5c2ddf6..3697900 100644
--- a/lang/csharp/src/apache/test/Ipc/HttpClientServerTest.cs
+++ b/lang/csharp/src/apache/ipc.test/HttpClientServerTest.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -42,7 +42,7 @@ namespace Avro.Test.Ipc
 
         const string URL = @"http://localhost:18080/avro/test/ipc/mailResponder/";
 
-        [TestFixtureSetUp]
+        [OneTimeSetUp]
         //[TestInitialize]
         public void Init()
         {
@@ -58,7 +58,7 @@ namespace Avro.Test.Ipc
             proxy = new GenericRequestor(transceiver, MailResponder.Protocol);
         }
 
-        [TestFixtureTearDown]
+        [OneTimeTearDown]
         //[TestCleanup]
         public void Cleanup()
         {
diff --git a/lang/csharp/src/apache/test/Ipc/LocalTransceiverTest.cs b/lang/csharp/src/apache/ipc.test/LocalTransceiverTest.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/LocalTransceiverTest.cs
rename to lang/csharp/src/apache/ipc.test/LocalTransceiverTest.cs
diff --git a/lang/csharp/src/apache/test/Ipc/MailResponder.cs b/lang/csharp/src/apache/ipc.test/MailResponder.cs
similarity index 98%
rename from lang/csharp/src/apache/test/Ipc/MailResponder.cs
rename to lang/csharp/src/apache/ipc.test/MailResponder.cs
index b6502c5..73212f7 100644
--- a/lang/csharp/src/apache/test/Ipc/MailResponder.cs
+++ b/lang/csharp/src/apache/ipc.test/MailResponder.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -46,7 +46,7 @@ namespace Avro.Test.Ipc
                     string readAllLines;
                     using (
                         Stream stream =
-                            Assembly.GetExecutingAssembly().GetManifestResourceStream("Avro.test.Ipc.mail.avpr"))
+                            Assembly.GetExecutingAssembly().GetManifestResourceStream("Avro.ipc.test.mail.avpr"))
                     using (var reader = new StreamReader(stream))
                     {
                         readAllLines = reader.ReadToEnd();
@@ -99,4 +99,4 @@ namespace Avro.Test.Ipc
             Assert.Fail(error.ToString());
         }
     }
-}
\ No newline at end of file
+}
diff --git a/lang/csharp/src/apache/ipc.test/Properties/AssemblyInfo.cs b/lang/csharp/src/apache/ipc.test/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a19b7f1
--- /dev/null
+++ b/lang/csharp/src/apache/ipc.test/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Avro.ipc.test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache")]
+[assembly: AssemblyProduct("Avro.ipc.test")]
+[assembly: AssemblyCopyright("Copyright © Apache 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+[assembly: Guid("442785CE-3633-4A04-A103-434104F63D55")]
+[assembly: AssemblyVersion("0.9.0.0")]
+[assembly: AssemblyFileVersion("0.9.0.0")]
\ No newline at end of file
diff --git a/lang/csharp/src/apache/test/Ipc/SerializationTest.cs b/lang/csharp/src/apache/ipc.test/SerializationTest.cs
similarity index 98%
rename from lang/csharp/src/apache/test/Ipc/SerializationTest.cs
rename to lang/csharp/src/apache/ipc.test/SerializationTest.cs
index 84104a0..5819802 100644
--- a/lang/csharp/src/apache/test/Ipc/SerializationTest.cs
+++ b/lang/csharp/src/apache/ipc.test/SerializationTest.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -60,7 +60,7 @@ namespace Avro.Test.Ipc
         private SocketTransceiver transceiver;
         private All simpleClient;
 
-        [TestFixtureSetUp]
+        [OneTimeSetUp]
         public void Init()
         {
             var mailResponder = new SpecificResponder<All>(new AllImpl());
@@ -73,7 +73,7 @@ namespace Avro.Test.Ipc
             simpleClient = SpecificRequestor.CreateClient<All>(transceiver);
         }
 
-        [TestFixtureTearDown]
+        [OneTimeTearDown]
         public void Cleanup()
         {
             server.Stop();
@@ -150,4 +150,4 @@ namespace Avro.Test.Ipc
             };
         }
     }
-}
\ No newline at end of file
+}
diff --git a/lang/csharp/src/apache/test/Ipc/SocketServerConcurrentExecutionTest.cs b/lang/csharp/src/apache/ipc.test/SocketServerConcurrentExecutionTest.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/SocketServerConcurrentExecutionTest.cs
rename to lang/csharp/src/apache/ipc.test/SocketServerConcurrentExecutionTest.cs
diff --git a/lang/csharp/src/apache/test/Ipc/SocketServerTest.cs b/lang/csharp/src/apache/ipc.test/SocketServerTest.cs
similarity index 98%
rename from lang/csharp/src/apache/test/Ipc/SocketServerTest.cs
rename to lang/csharp/src/apache/ipc.test/SocketServerTest.cs
index 1a1747b..9d091ae 100644
--- a/lang/csharp/src/apache/test/Ipc/SocketServerTest.cs
+++ b/lang/csharp/src/apache/ipc.test/SocketServerTest.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -33,7 +33,7 @@ namespace Avro.Test.Ipc
         private SocketTransceiver transceiver;
         private GenericRequestor proxy;
 
-        [TestFixtureSetUp]
+        [OneTimeSetUp]
         public void Init()
         {
             mailResponder = new MailResponder();
@@ -45,7 +45,7 @@ namespace Avro.Test.Ipc
             proxy = new GenericRequestor(transceiver, MailResponder.Protocol);
         }
 
-        [TestFixtureTearDown]
+        [OneTimeTearDown]
         public void Cleanup()
         {
             server.Stop();
@@ -184,4 +184,4 @@ namespace Avro.Test.Ipc
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/lang/csharp/src/apache/test/Ipc/SocketServerWithCallbacksTest.cs b/lang/csharp/src/apache/ipc.test/SocketServerWithCallbacksTest.cs
similarity index 99%
rename from lang/csharp/src/apache/test/Ipc/SocketServerWithCallbacksTest.cs
rename to lang/csharp/src/apache/ipc.test/SocketServerWithCallbacksTest.cs
index c625e63..3cd9176 100644
--- a/lang/csharp/src/apache/test/Ipc/SocketServerWithCallbacksTest.cs
+++ b/lang/csharp/src/apache/ipc.test/SocketServerWithCallbacksTest.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -37,7 +37,7 @@ namespace Avro.Test.Ipc
         private SocketTransceiver transceiver;
         private SimpleCallback simpleClient;
 
-        [TestFixtureSetUp]
+        [OneTimeSetUp]
         public void Init()
         {
             var responder = new SpecificResponder<Simple>(new SimpleImpl());
@@ -48,7 +48,7 @@ namespace Avro.Test.Ipc
             simpleClient = SpecificRequestor.CreateClient<SimpleCallback>(transceiver);
         }
 
-        [TestFixtureTearDown]
+        [OneTimeTearDown]
         public void TearDown()
         {
             try
@@ -557,28 +557,28 @@ namespace Avro.Test.Ipc
 
             Assert.AreEqual(byteBuffer, future2.WaitForResult(2000));
             Assert.IsNull(future2.Error);
-        }
-
-        [Test, TestCase(false, TestName = "Specific error"), TestCase(true, TestName = "System error")]
+        }
+
+        [Test, TestCase(false, TestName = "Specific error"), TestCase(true, TestName = "System error")]
         public void Error(bool systemError)
-        {
+        {
             Type expected;
 
             if(systemError)
             {
                 expected = typeof(Exception);
                 SimpleImpl.throwSystemError = true;
-            }
-            else
-            {
-                expected = typeof(TestError);
-                SimpleImpl.throwSystemError = false;
+            }
+            else
+            {
+                expected = typeof(TestError);
+                SimpleImpl.throwSystemError = false;
             }
 
             // Test synchronous RPC:
             try
             {
-                simpleClient.error();
+                simpleClient.error();
                 Assert.Fail("Expected " + expected.Name + " to be thrown");
             }
             catch (Exception e)
@@ -593,10 +593,10 @@ namespace Avro.Test.Ipc
             {
                 future.WaitForResult(2000);
                 Assert.Fail("Expected " + expected.Name + " to be thrown");
-            }
-            catch (Exception e)
-            {
-                Assert.AreEqual(expected, e.GetType());
+            }
+            catch (Exception e)
+            {
+                Assert.AreEqual(expected, e.GetType());
             }
 
             Assert.IsNotNull(future.Error);
@@ -617,8 +617,8 @@ namespace Avro.Test.Ipc
             Assert.IsTrue(latch.Wait(2000), "Timed out waiting for error");
             Assert.IsNotNull(errorRef);
             Assert.AreEqual(expected, errorRef.GetType());
-        }
-
+        }
+
         [Test]
         public void Greeting()
         {
@@ -764,7 +764,7 @@ namespace Avro.Test.Ipc
         }
 
         private class SimpleImpl : Simple
-        {
+        {
             public static bool throwSystemError = false;
 
             public override string hello(string greeting)
@@ -803,4 +803,4 @@ namespace Avro.Test.Ipc
         }
 
     }
-}
\ No newline at end of file
+}
diff --git a/lang/csharp/src/apache/test/Ipc/SocketTransceiverWhenServerStopsTest.cs b/lang/csharp/src/apache/ipc.test/SocketTransceiverWhenServerStopsTest.cs
similarity index 100%
rename from lang/csharp/src/apache/test/Ipc/SocketTransceiverWhenServerStopsTest.cs
rename to lang/csharp/src/apache/ipc.test/SocketTransceiverWhenServerStopsTest.cs
diff --git a/lang/csharp/src/apache/ipc/Avro.ipc.csproj b/lang/csharp/src/apache/ipc/Avro.ipc.csproj
index 9d738c9..6b67936 100644
--- a/lang/csharp/src/apache/ipc/Avro.ipc.csproj
+++ b/lang/csharp/src/apache/ipc/Avro.ipc.csproj
@@ -1,108 +1,37 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{3B05043A-DC6C-49B6-85BF-9AB055D0B414}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avro.ipc</RootNamespace>
-    <AssemblyName>Avro.ipc</AssemblyName>
-    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\..\build\ipc\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\..\build\ipc\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SignAssembly>true</SignAssembly>
-  </PropertyGroup>
-  <PropertyGroup>
-    <AssemblyOriginatorKeyFile>..\..\..\Avro.snk</AssemblyOriginatorKeyFile>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Castle.Core">
-      <HintPath>..\..\..\lib\main\Castle.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="log4net">
-      <HintPath>..\..\..\lib\main\log4net.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CallFuture.cs" />
-    <Compile Include="CountdownLatch.cs" />
-    <Compile Include="Generic\GenericRequestor.cs" />
-    <Compile Include="Generic\GenericResponder.cs" />
-    <Compile Include="HttpListenerServer.cs" />
-    <Compile Include="HttpTransceiver.cs" />
-    <Compile Include="OutputStream.cs" />
-    <Compile Include="RpcRequest.cs" />
-    <Compile Include="SocketServer.cs" />
-    <Compile Include="Specific\SpecificResponder.cs" />
-    <Compile Include="Specific\SpecificRequestor.cs" />
-    <Compile Include="Transceiver.cs" />
-    <Compile Include="LocalTransceiver.cs" />
-    <Compile Include="org\apache\avro\ipc\HandshakeMatch.cs" />
-    <Compile Include="org\apache\avro\ipc\HandshakeRequest.cs" />
-    <Compile Include="org\apache\avro\ipc\HandshakeResponse.cs" />
-    <Compile Include="org\apache\avro\ipc\MD5.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Requestor.cs" />
-    <Compile Include="Responder.cs" />
-    <Compile Include="RpcContext.cs" />
-    <Compile Include="SocketTransceiver.cs" />
-  </ItemGroup>
-  <ItemGroup />
-  <ItemGroup>
-    <ProjectReference Include="..\main\Avro.main.csproj">
-      <Project>{a0a5ca3c-f58c-4d07-98b0-2c7b62ab20f0}</Project>
-      <Name>Avro.main</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!--<UsingTask AssemblyFile="..\..\..\build\msbuild\$(Configuration)\Avro.msbuild.dll" TaskName="Avro.msbuild.AvroBuildTask" />-->
-  <Target Name="BeforeBuild">
-    <!--<AvroBuildTask OutDir="..\ipc\" SchemaFiles="..\..\..\..\..\share\schemas\org\apache\avro\ipc\HandshakeRequest.avsc;..\..\..\..\..\share\schemas\org\apache\avro\ipc\HandshakeResponse.avsc">
-    </AvroBuildTask>-->
-  </Target>
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFrameworks>net40</TargetFrameworks>
+    <AssemblyName>Avro.ipc</AssemblyName>
+    <RootNamespace>Avro.ipc</RootNamespace>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>..\..\..\Avro.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="castle.core" Version="4.2.1" />
+    <PackageReference Include="log4net" Version="2.0.8" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\main\Avro.main.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/lang/csharp/src/apache/main/Avro.main.csproj b/lang/csharp/src/apache/main/Avro.main.csproj
index 7f41e3f..91c551d 100644
--- a/lang/csharp/src/apache/main/Avro.main.csproj
+++ b/lang/csharp/src/apache/main/Avro.main.csproj
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -15,166 +14,28 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{A0A5CA3C-F58C-4D07-98B0-2C7B62AB20F0}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avro</RootNamespace>
+    <TargetFrameworks>net40;netstandard2.0</TargetFrameworks>
     <AssemblyName>Avro</AssemblyName>
-    <TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v3.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>3.5</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\..\build\main\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\..\build\main\Release\</OutputPath>
-    <DefineConstants>
-    </DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
-  </PropertyGroup>
-  <PropertyGroup>
+    <RootNamespace>Avro</RootNamespace>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <SignAssembly>true</SignAssembly>
-  </PropertyGroup>
-  <PropertyGroup>
     <AssemblyOriginatorKeyFile>..\..\..\Avro.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="log4net">
-      <HintPath>..\..\..\lib\main\log4net.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json">
-      <HintPath>..\..\..\lib\main\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CodeGen\AvroRuntimeException.cs" />
-    <Compile Include="CodeGen\CodeGen.cs" />
-    <Compile Include="CodeGen\CodeGenException.cs" />
-    <Compile Include="CodeGen\CodeGenUtil.cs" />
-    <Compile Include="File\Codec.cs" />
-    <Compile Include="File\DataBlock.cs" />
-    <Compile Include="File\DataFileConstants.cs" />
-    <Compile Include="File\DataFileReader.cs" />
-    <Compile Include="File\DataFileWriter.cs" />
-    <Compile Include="File\DeflateCodec.cs" />
-    <Compile Include="File\Header.cs" />
-    <Compile Include="File\IFileReader.cs" />
-    <Compile Include="File\IFileWriter.cs" />
-    <Compile Include="File\NullCodec.cs" />
-    <Compile Include="Generic\DatumReader.cs" />
-    <Compile Include="Generic\DatumWriter.cs" />
-    <Compile Include="Generic\GenericDatumReader.cs" />
-    <Compile Include="Generic\GenericDatumWriter.cs" />
-    <Compile Include="Generic\GenericEnum.cs" />
-    <Compile Include="Generic\GenericFixed.cs" />
-    <Compile Include="Generic\GenericReader.cs" />
-    <Compile Include="Generic\GenericRecord.cs" />
-    <Compile Include="Generic\GenericWriter.cs" />
-    <Compile Include="Generic\PreresolvingDatumReader.cs" />
-    <Compile Include="Generic\PreresolvingDatumWriter.cs" />
-    <Compile Include="IO\BinaryDecoder.cs" />
-    <Compile Include="IO\BinaryEncoder.cs" />
-    <Compile Include="IO\ByteBufferInputStream.cs" />
-    <Compile Include="IO\ByteBufferOutputStream.cs" />
-    <Compile Include="IO\Decoder.cs" />
-    <Compile Include="IO\Encoder.cs" />
-    <Compile Include="IO\ICallback.cs" />
-    <Compile Include="IO\InputStream.cs" />
-    <Compile Include="IO\OutputStream.cs" />
-    <Compile Include="IO\Resolver.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Protocol\Message.cs" />
-    <Compile Include="Protocol\Protocol.cs" />
-    <Compile Include="Protocol\ProtocolParseException.cs" />
-    <Compile Include="Schema\ArraySchema.cs" />
-    <Compile Include="Schema\AvroException.cs" />
-    <Compile Include="Schema\AvroTypeException.cs" />
-    <Compile Include="Schema\EnumSchema.cs" />
-    <Compile Include="Schema\Field.cs" />
-    <Compile Include="Schema\FixedSchema.cs" />
-    <Compile Include="Schema\JsonHelper.cs" />
-    <Compile Include="Schema\MapSchema.cs" />
-    <Compile Include="Schema\NamedSchema.cs" />
-    <Compile Include="Schema\PrimitiveSchema.cs" />
-    <Compile Include="Schema\Property.cs" />
-    <Compile Include="Schema\RecordSchema.cs" />
-    <Compile Include="Schema\Schema.cs" />
-    <Compile Include="Schema\SchemaName.cs" />
-    <Compile Include="Schema\SchemaNormalization.cs" />
-    <Compile Include="Schema\SchemaParseException.cs" />
-    <Compile Include="Schema\UnionSchema.cs" />
-    <Compile Include="Schema\UnnamedSchema.cs" />
-    <Compile Include="Specific\SpecificDatumWriter.cs" />
-    <Compile Include="Specific\SpecificException.cs" />
-    <Compile Include="Specific\SpecificProtocol.cs" />
-    <Compile Include="Specific\ObjectCreator.cs" />
-    <Compile Include="Specific\SpecificDatumReader.cs" />
-    <Compile Include="Specific\SpecificFixed.cs" />
-    <Compile Include="Specific\SpecificReader.cs" />
-    <Compile Include="Specific\SpecificWriter.cs" />
-    <Compile Include="Specific\SpecificRecord.cs" />
+
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <PackageReference Include="System.CodeDom" Version="4.4.0" />
+    <PackageReference Include="System.Reflection" Version="4.3.0" />
+    <PackageReference Include="System.Reflection.Emit.ILGeneration" Version="4.3.0" />
+    <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
   </ItemGroup>
+
   <ItemGroup>
-    <BootstrapperPackage Include=".NETFramework,Version=v3.5">
-      <Visible>False</Visible>
-      <ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
-      <Visible>False</Visible>
-      <ProductName>Windows Installer 3.1</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
+    <PackageReference Include="Newtonsoft.Json" Version="3.5.8">
+      <NoWarn>NU1701</NoWarn>
+    </PackageReference>
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/lang/csharp/src/apache/main/Properties/Settings.Designer.cs b/lang/csharp/src/apache/main/Properties/Settings.Designer.cs
deleted file mode 100644
index dc7cb6d..0000000
--- a/lang/csharp/src/apache/main/Properties/Settings.Designer.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.1
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Avro.Properties {
-
-
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
-    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
-
-        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
-        public static Settings Default {
-            get {
-                return defaultInstance;
-            }
-        }
-    }
-}
diff --git a/lang/csharp/src/apache/main/Schema/JsonHelper.cs b/lang/csharp/src/apache/main/Schema/JsonHelper.cs
index 13db058..4b75765 100644
--- a/lang/csharp/src/apache/main/Schema/JsonHelper.cs
+++ b/lang/csharp/src/apache/main/Schema/JsonHelper.cs
@@ -42,8 +42,7 @@ namespace Avro
 
             if (child.Type == JTokenType.String)
             {
-                string value = child.ToString();
-                return value.Trim('\"');
+                return child.Value<string>();
             }
             throw new SchemaParseException("Field " + field + " is not a string");
         }
diff --git a/lang/csharp/src/apache/main/Schema/Property.cs b/lang/csharp/src/apache/main/Schema/Property.cs
index 521cfd1..de08c17 100644
--- a/lang/csharp/src/apache/main/Schema/Property.cs
+++ b/lang/csharp/src/apache/main/Schema/Property.cs
@@ -44,7 +44,7 @@ namespace Avro
                 if (ReservedProps.Contains(prop.Name))
                     continue;
                 if (!ContainsKey(prop.Name))
-                    Add(prop.Name, prop.Value.ToString());
+                    Add(prop.Name, JsonConvert.SerializeObject(prop.Value));
             }
         }
 
diff --git a/lang/csharp/src/apache/msbuild/Avro.msbuild.csproj b/lang/csharp/src/apache/msbuild/Avro.msbuild.csproj
index f1dd6f8..096caf8 100644
--- a/lang/csharp/src/apache/msbuild/Avro.msbuild.csproj
+++ b/lang/csharp/src/apache/msbuild/Avro.msbuild.csproj
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -15,60 +14,28 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{AEB22F94-4ECF-4008-B159-389B3F05D54B}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avro.msbuild</RootNamespace>
+    <TargetFrameworks>net40;netstandard2.0</TargetFrameworks>
     <AssemblyName>Avro.msbuild</AssemblyName>
-    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\..\build\msbuild\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\..\build\msbuild\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+    <RootNamespace>Avro.msbuild</RootNamespace>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Microsoft.Build.Framework" />
-    <Reference Include="Microsoft.Build.Tasks.v3.5" />
-    <Reference Include="Microsoft.Build.Utilities.v3.5" />
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
+
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <PackageReference Include="Microsoft.Build.Framework" Version="15.6.82" />
+    <PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.6.82" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="AvroBuilldTask.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
+
+  <ItemGroup Condition="'$(TargetFramework)' == 'net40'">
+    <Reference Include="Microsoft.Build.Framework" />
+    <Reference Include="Microsoft.Build.Tasks.v4.0" />
+    <Reference Include="Microsoft.Build.Utilities.v4.0" />
   </ItemGroup>
+
   <ItemGroup>
-    <ProjectReference Include="..\main\Avro.main.csproj">
-      <Project>{A0A5CA3C-F58C-4D07-98B0-2C7B62AB20F0}</Project>
-      <Name>Avro.main</Name>
-    </ProjectReference>
+    <ProjectReference Include="..\main\Avro.main.csproj" />
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/lang/csharp/src/apache/perf/Avro.perf.csproj b/lang/csharp/src/apache/perf/Avro.perf.csproj
index 7235c99..6fb706c 100644
--- a/lang/csharp/src/apache/perf/Avro.perf.csproj
+++ b/lang/csharp/src/apache/perf/Avro.perf.csproj
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -15,129 +14,18 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{AC4E1909-2594-4D01-9B2B-B832C07BAFE5}</ProjectGuid>
     <OutputType>Exe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avro.perf</RootNamespace>
+    <TargetFrameworks>net40;netcoreapp2.0</TargetFrameworks>
     <AssemblyName>Avro.perf</AssemblyName>
-    <TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v3.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>3.5</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\..\build\perf\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\..\build\perf\Release\</OutputPath>
-    <DefineConstants>
-    </DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
-  </PropertyGroup>
-  <PropertyGroup>
-    <StartupObject />
+    <RootNamespace>Avro.perf</RootNamespace>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="Castle.Core, Version=3.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\..\lang\csharp\lib\main\Castle.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="nunit.framework, Version=2.5.7.10213, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\lib\test\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\ipc\Avro.ipc.csproj">
-      <Project>{3b05043a-dc6c-49b6-85bf-9ab055d0b414}</Project>
-      <Name>Avro.ipc</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\main\Avro.main.csproj">
-      <Project>{A0A5CA3C-F58C-4D07-98B0-2C7B62AB20F0}</Project>
-      <Name>Avro.main</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <BootstrapperPackage Include=".NETFramework,Version=v3.5">
-      <Visible>False</Visible>
-      <ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
-      <Visible>False</Visible>
-      <ProductName>Windows Installer 3.1</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="com\foo\A.cs" />
-    <Compile Include="com\foo\Complex.cs" />
-    <Compile Include="com\foo\MyEnum.cs" />
-    <Compile Include="com\foo\MyFixed.cs" />
-    <Compile Include="com\foo\Narrow.cs" />
-    <Compile Include="com\foo\newRec.cs" />
-    <Compile Include="com\foo\Simple.cs" />
-    <Compile Include="com\foo\Wide.cs" />
-    <Compile Include="PerfTest.cs">
-      <SubType>Code</SubType>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="app.config" />
-    <None Include="schema.avsc" />
+    <ProjectReference Include="..\main\Avro.main.csproj" />
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+
+</Project>
diff --git a/lang/csharp/src/apache/test/Avro.test.csproj b/lang/csharp/src/apache/test/Avro.test.csproj
index 841f4f2..6f0d73c 100644
--- a/lang/csharp/src/apache/test/Avro.test.csproj
+++ b/lang/csharp/src/apache/test/Avro.test.csproj
@@ -1,168 +1,54 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{911D56AB-587B-4E5F-B5EA-D47D8A46F1FA}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avro.test</RootNamespace>
-    <AssemblyName>Avro.test</AssemblyName>
-    <TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v3.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>3.5</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\..\build\test\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\..\build\test\Release\</OutputPath>
-    <DefineConstants>
-    </DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Castle.Core, Version=3.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\..\lang\csharp\lib\main\Castle.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="nunit.framework, Version=2.5.7.10213, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\lib\test\nunit.framework.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CodGen\CodeGenTest.cs" />
-    <Compile Include="File\FileTests.cs" />
-    <Compile Include="Generic\GenericTests.cs" />
-    <Compile Include="IO\BinaryCodecTests.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\All.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\AllCallback.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\AllEnum.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\AllTestRecord.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\AllTestRecordPartial.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\FixedTest.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\Kind.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\Mail.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\MailCallback.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\MD5.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\Message.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\Simple.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\SimpleCallback.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\TestError.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\TestRecord.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\TestRecordExtensions.cs" />
-    <Compile Include="Ipc\GeneratedFiles\org\apache\avro\test\TestRecordWithUnion.cs" />
-    <Compile Include="Ipc\HttpClientServerTest.cs" />
-    <Compile Include="Ipc\LocalTransceiverTest.cs" />
-    <Compile Include="Ipc\MailResponder.cs" />
-    <Compile Include="Ipc\SerializationTest.cs" />
-    <Compile Include="Ipc\SocketServerConcurrentExecutionTest.cs" />
-    <Compile Include="Ipc\SocketServerTest.cs" />
-    <Compile Include="Ipc\SocketServerWithCallbacksTest.cs" />
-    <Compile Include="Ipc\SocketTransceiverWhenServerStopsTest.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Protocol\ProtocolTest.cs" />
-    <Compile Include="Schema\AliasTest.cs" />
-    <Compile Include="Schema\SchemaNormalizationTests.cs" />
-    <Compile Include="Schema\SchemaTests.cs" />
-    <Compile Include="Specific\SpecificTests.cs" />
-    <Compile Include="Utils\CaseFinder.cs" />
-    <Compile Include="Utils\CaseFinderTests.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\ipc\Avro.ipc.csproj">
-      <Project>{3b05043a-dc6c-49b6-85bf-9ab055d0b414}</Project>
-      <Name>Avro.ipc</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\main\Avro.main.csproj">
-      <Project>{A0A5CA3C-F58C-4D07-98B0-2C7B62AB20F0}</Project>
-      <Name>Avro.main</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <BootstrapperPackage Include=".NETFramework,Version=v3.5">
-      <Visible>False</Visible>
-      <ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
-      <Visible>False</Visible>
-      <ProductName>Windows Installer 3.1</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="..\..\..\..\..\share\test\schemas\mail.avpr">
-      <Link>Ipc\mail.avpr</Link>
-    </EmbeddedResource>
-  </ItemGroup>
-  <ItemGroup />
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
\ No newline at end of file
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFrameworks>net40;netcoreapp2.0</TargetFrameworks>
+    <RootNamespace>Avro.test</RootNamespace>
+    <AssemblyName>Avro.test</AssemblyName>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="nunit">
+      <Version>3.10.1</Version>
+    </PackageReference>
+    <PackageReference Include="nunit3testadapter">
+      <Version>3.10.0</Version>
+    </PackageReference>
+    <PackageReference Include="NUnit.ConsoleRunner">
+      <Version>3.9.0</Version>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup Condition="'$(TargetFramework)'!='netcoreapp2.0'">
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.1" />
+  </ItemGroup>
+
+  <ItemGroup Condition="'$(TargetFramework)'=='netcoreapp2.0'">
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\main\Avro.main.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+  </ItemGroup>
+
+</Project>
diff --git a/lang/csharp/src/apache/test/CodGen/CodeGenTest.cs b/lang/csharp/src/apache/test/CodGen/CodeGenTest.cs
index f1141db..b96bbed 100644
--- a/lang/csharp/src/apache/test/CodGen/CodeGenTest.cs
+++ b/lang/csharp/src/apache/test/CodGen/CodeGenTest.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -30,6 +30,7 @@ namespace Avro.Test
 
     class CodeGenTest
     {
+#if !NETCOREAPP2_0 // System.CodeDom compilation not supported in .NET Core: https://github.com/dotnet/corefx/issues/12180
         [TestCase(@"{
 ""type"" : ""record"",
 ""name"" : ""ClassKeywords"",
@@ -48,7 +49,7 @@ namespace Avro.Test
 			{ ""name"" : ""string"", ""type"" : { ""type"": ""fixed"", ""size"": 16, ""name"": ""static"" } }
 		]
 }
-", new object[] {"com.base.ClassKeywords", typeof(int), typeof(long), typeof(bool), typeof(double), typeof(float), typeof(byte[]), typeof(string),typeof(object),"com.base.class", "com.base.static"})]
+", new object[] {"com.base.ClassKeywords", typeof(int), typeof(long), typeof(bool), typeof(double), typeof(float), typeof(byte[]), typeof(string),typeof(object),"com.base.class", "com.base.static"}, TestName = "TestCodeGen0")]
         [TestCase(@"{
 ""type"" : ""record"",
 ""name"" : ""SchemaObject"",
@@ -67,7 +68,7 @@ namespace Avro.Test
 		}
 	]
 }
-", new object[] { "schematest.SchemaObject", typeof(IList<object>) })]
+", new object[] { "schematest.SchemaObject", typeof(IList<object>) }, TestName = "TestCodeGen1")]
         public static void TestCodeGen(string str, object[] result)
         {
             Schema schema = Schema.Parse(str);
@@ -149,7 +150,7 @@ namespace Avro.Test
 
             var comparam = new CompilerParameters(new string[] { "mscorlib.dll" });
             comparam.ReferencedAssemblies.Add("System.dll");
-            comparam.ReferencedAssemblies.Add("Avro.dll");
+            comparam.ReferencedAssemblies.Add(Path.Combine(TestContext.CurrentContext.TestDirectory, "Avro.dll"));
             comparam.GenerateInMemory = true;
             var ccp = new CSharpCodeProvider();
             var units = new[] { compileUnit };
@@ -162,5 +163,6 @@ namespace Avro.Test
             Assert.AreEqual(0, compres.Errors.Count);
             return compres;
         }
+#endif
     }
 }
diff --git a/lang/csharp/src/apache/test/File/FileTests.cs b/lang/csharp/src/apache/test/File/FileTests.cs
index b3dbfb2..9d7f1d7 100644
--- a/lang/csharp/src/apache/test/File/FileTests.cs
+++ b/lang/csharp/src/apache/test/File/FileTests.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -40,15 +40,15 @@ namespace Avro.Test.File
         /// <param name="schemaStr"></param>
         /// <param name="recs"></param>
         /// <param name="codecType"></param>
-        [TestCase(specificSchema, new object[] { new object[] { "John", 23 } }, Codec.Type.Deflate)]
-        [TestCase(specificSchema, new object[] { new object[] { "Jane", 23 } }, Codec.Type.Deflate)]
-        [TestCase(specificSchema, new object[] { new object[] { "John", 23 }, new object[] { "Jane", 99 }, new object[] { "Jeff", 88 } }, Codec.Type.Deflate)]
+        [TestCase(specificSchema, new object[] { new object[] { "John", 23 } }, Codec.Type.Deflate, TestName = "TestSpecificData0")]
+        [TestCase(specificSchema, new object[] { new object[] { "Jane", 23 } }, Codec.Type.Deflate, TestName = "TestSpecificData1")]
+        [TestCase(specificSchema, new object[] { new object[] { "John", 23 }, new object[] { "Jane", 99 }, new object[] { "Jeff", 88 } }, Codec.Type.Deflate, TestName = "TestSpecificData2")]
         [TestCase(specificSchema, new object[] { new object[] {"John", 23}, new object[] { "Jane", 99 }, new object[] { "Jeff", 88 },
                                                  new object[] {"James", 13}, new object[] { "June", 109 }, new object[] { "Lloyd", 18 },
-                                                 new object[] {"Jenny", 3}, new object[] { "Bob", 9 }, new object[] { null, 48 }}, Codec.Type.Deflate)]
-        [TestCase(specificSchema, new object[] { new object[] { "John", 23 } }, Codec.Type.Null)]
-        [TestCase(specificSchema, new object[] { new object[] { "Jane", 23 } }, Codec.Type.Null)]
-        [TestCase(specificSchema, new object[] { new object[] { "John", 23 }, new object[] { "Jane", 99 }, new object[] { "Jeff", 88 } }, Codec.Type.Null)]
+                                                 new object[] {"Jenny", 3}, new object[] { "Bob", 9 }, new object[] { null, 48 }}, Codec.Type.Deflate, TestName = "TestSpecificData3")]
+        [TestCase(specificSchema, new object[] { new object[] { "John", 23 } }, Codec.Type.Null, TestName = "TestSpecificData4")]
+        [TestCase(specificSchema, new object[] { new object[] { "Jane", 23 } }, Codec.Type.Null, TestName = "TestSpecificData5")]
+        [TestCase(specificSchema, new object[] { new object[] { "John", 23 }, new object[] { "Jane", 99 }, new object[] { "Jeff", 88 } }, Codec.Type.Null, TestName = "TestSpecificData6")]
         [TestCase(specificSchema, new object[] { new object[] {"John", 23}, new object[] { "Jane", 99 }, new object[] { "Jeff", 88 },
                                                  new object[] {"James", 13}, new object[] { "June", 109 }, new object[] { "Lloyd", 18 },
                                                  new object[] {"Jamie", 53}, new object[] { "Fanessa", 101 }, new object[] { "Kan", 18 },
@@ -59,7 +59,7 @@ namespace Avro.Test.File
                                                  new object[] {"Ernie", 43}, new object[] { "Joel", 99 }, new object[] { "Dan", 78 },
                                                  new object[] {"Dave", 103}, new object[] { "Hillary", 79 }, new object[] { "Grant", 88 },
                                                  new object[] {"JJ", 14}, new object[] { "Bill", 90 }, new object[] { "Larry", 4 },
-                                                 new object[] {"Jenny", 3}, new object[] { "Bob", 9 }, new object[] { null, 48 }}, Codec.Type.Null)]
+                                                 new object[] {"Jenny", 3}, new object[] { "Bob", 9 }, new object[] { null, 48 }}, Codec.Type.Null, TestName = "TestSpecificData7")]
         public void TestSpecificData(string schemaStr, object[] recs, Codec.Type codecType)
         {
             // create and write out
@@ -471,11 +471,11 @@ namespace Avro.Test.File
         [TestCase(specificSchema, Codec.Type.Null, 2, 0, 1)]
         [TestCase(specificSchema, Codec.Type.Null, 10, 1, 4)]
         [TestCase(specificSchema, Codec.Type.Null, 200, 111, 15)]
-        [TestCase(specificSchema, Codec.Type.Null, 1000, 588, 998)]
+        // Disabled due to long runtime [TestCase(specificSchema, Codec.Type.Null, 1000, 588, 998)]
         [TestCase(specificSchema, Codec.Type.Deflate, 2, 0, 1)]
         [TestCase(specificSchema, Codec.Type.Deflate, 10, 1, 4)]
         [TestCase(specificSchema, Codec.Type.Deflate, 200, 111, 15)]
-        [TestCase(specificSchema, Codec.Type.Deflate, 1000, 588, 998)]
+        // Disabled due to long runtime [TestCase(specificSchema, Codec.Type.Deflate, 1000, 588, 998)]
         public void TestSyncAndSeekPositions(string schemaStr, Codec.Type codecType, int iterations, int firstSyncPosition, int secondSyncPosition)
         {
             // create and write out
diff --git a/lang/csharp/src/apache/test/Generic/GenericTests.cs b/lang/csharp/src/apache/test/Generic/GenericTests.cs
index b5bdc8d..c65ad8b 100644
--- a/lang/csharp/src/apache/test/Generic/GenericTests.cs
+++ b/lang/csharp/src/apache/test/Generic/GenericTests.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -121,11 +121,17 @@ namespace Avro.Test.Generic
         [TestCase("[{\"type\": \"enum\", \"symbols\": [\"s1\", \"s2\"], \"name\": \"e\"}, \"string\"]",
             "{\"type\": \"enum\", \"symbols\": [\"s1\", \"s2\"], \"name\": \"e\"}", "s2")]
         [TestCase("[{\"type\": \"enum\", \"symbols\": [\"s1\", \"s2\"], \"name\": \"e\"}, \"string\"]",
-            "{\"type\": \"enum\", \"symbols\": [\"s1\", \"s2\"], \"name\": \"e\"}", "s3",
-            ExpectedException = typeof(AvroException))]
-        public void TestUnion_enum(string unionSchema, string enumSchema, string value)
+            "{\"type\": \"enum\", \"symbols\": [\"s1\", \"s2\"], \"name\": \"e\"}", "s3", typeof(AvroException))]
+        public void TestUnion_enum(string unionSchema, string enumSchema, string value, Type expectedExceptionType = null)
         {
-            test(unionSchema, mkEnum(enumSchema, value));
+            if (expectedExceptionType != null)
+            {
+                Assert.Throws(expectedExceptionType, () => { test(unionSchema, mkEnum(enumSchema, value)); });
+            }
+            else
+            {
+                test(unionSchema, mkEnum(enumSchema, value));
+            }
         }
 
 
@@ -139,14 +145,19 @@ namespace Avro.Test.Generic
         [TestCase("[{\"type\": \"fixed\", \"size\": 2, \"name\": \"f\"}, \"string\"]",
             "{\"type\": \"fixed\", \"size\": 2, \"name\": \"f\"}", new byte[] { 1, 2 })]
         [TestCase("[{\"type\": \"fixed\", \"size\": 2, \"name\": \"f\"}, \"string\"]",
-            "{\"type\": \"fixed\", \"size\": 2, \"name\": \"f\"}", new byte[] { 1, 2, 3 },
-            ExpectedException = typeof(AvroException))]
+            "{\"type\": \"fixed\", \"size\": 2, \"name\": \"f\"}", new byte[] { 1, 2, 3 }, typeof(AvroException))]
         [TestCase("[{\"type\": \"fixed\", \"size\": 2, \"name\": \"f\"}, \"string\"]",
-            "{\"type\": \"fixed\", \"size\": 3, \"name\": \"f\"}", new byte[] { 1, 2, 3 },
-            ExpectedException = typeof(AvroException))]
-        public void TestUnion_fixed(string unionSchema, string fixedSchema, byte[] value)
+            "{\"type\": \"fixed\", \"size\": 3, \"name\": \"f\"}", new byte[] { 1, 2, 3 }, typeof(AvroException))]
+        public void TestUnion_fixed(string unionSchema, string fixedSchema, byte[] value, Type expectedExceptionType = null)
         {
-            test(unionSchema, mkFixed(fixedSchema, value));
+            if (expectedExceptionType != null)
+            {
+                Assert.Throws(expectedExceptionType, () => { test(unionSchema, mkFixed(fixedSchema, value)); });
+            }
+            else
+            {
+                test(unionSchema, mkFixed(fixedSchema, value));
+            }
         }
 
         public void TestResolution<T, S>(string writerSchema, T actual, string readerSchema, S expected)
@@ -300,89 +311,124 @@ namespace Avro.Test.Generic
             deserialize<object>(ms, ws, Schema.Parse(readerSchema));
         }
 
-        [TestCase("boolean", true, "null", ExpectedException = typeof(AvroException))]
-        [TestCase("int", 10, "boolean", ExpectedException = typeof(AvroException))]
-        [TestCase("int", 10, "string", ExpectedException = typeof(AvroException))]
-        [TestCase("int", 10, "bytes", ExpectedException = typeof(AvroException))]
+        [TestCase("boolean", true, "null", typeof(AvroException))]
+        [TestCase("int", 10, "boolean", typeof(AvroException))]
+        [TestCase("int", 10, "string", typeof(AvroException))]
+        [TestCase("int", 10, "bytes", typeof(AvroException))]
         [TestCase("int", 10, "{\"type\":\"record\",\"name\":\"r\",\"fields\":[{\"name\":\"f\", \"type\":\"int\"}]}",
-            ExpectedException = typeof(AvroException))]
-        [TestCase("int", 10, "{\"type\":\"enum\",\"name\":\"e\",\"symbols\":[\"s\", \"t\"]}", ExpectedException = typeof(AvroException))]
-        [TestCase("int", 10, "{\"type\":\"array\",\"items\":\"int\"}", ExpectedException = typeof(AvroException))]
-        [TestCase("int", 10, "{\"type\":\"map\",\"values\":\"int\"}", ExpectedException = typeof(AvroException))]
-        [TestCase("int", 10, "[\"string\", \"bytes\"]", ExpectedException = typeof(AvroException))]
-        [TestCase("int", 10, "{\"type\":\"fixed\",\"name\":\"f\",\"size\":2}", ExpectedException = typeof(AvroException))]
+            typeof(AvroException))]
+        [TestCase("int", 10, "{\"type\":\"enum\",\"name\":\"e\",\"symbols\":[\"s\", \"t\"]}", typeof(AvroException))]
+        [TestCase("int", 10, "{\"type\":\"array\",\"items\":\"int\"}", typeof(AvroException))]
+        [TestCase("int", 10, "{\"type\":\"map\",\"values\":\"int\"}", typeof(AvroException))]
+        [TestCase("int", 10, "[\"string\", \"bytes\"]", typeof(AvroException))]
+        [TestCase("int", 10, "{\"type\":\"fixed\",\"name\":\"f\",\"size\":2}", typeof(AvroException))]
         [TestCase("{\"type\":\"array\",\"items\":\"int\"}", new int[] { 10 },
-            "\"boolean\"", ExpectedException = typeof(AvroException))]
+            "\"boolean\"", typeof(AvroException))]
         [TestCase("{\"type\":\"array\",\"items\":\"int\"}", new int[] { 10 },
-            "{\"type\":\"array\",\"items\":\"string\"}", ExpectedException = typeof(AvroException))]
-        [TestCase("[\"int\", \"boolean\"]", 10, "[\"string\", \"bytes\"]", ExpectedException = typeof(AvroException))]
-        [TestCase("[\"int\", \"boolean\"]", 10, "\"string\"", ExpectedException = typeof(AvroException))]
-        public void TestResolutionMismatch_simple(string writerSchema, object value, string readerSchema)
+            "{\"type\":\"array\",\"items\":\"string\"}", typeof(AvroException))]
+        [TestCase("[\"int\", \"boolean\"]", 10, "[\"string\", \"bytes\"]", typeof(AvroException))]
+        [TestCase("[\"int\", \"boolean\"]", 10, "\"string\"", typeof(AvroException))]
+        public void TestResolutionMismatch_simple(string writerSchema, object value, string readerSchema, Type expectedExceptionType = null)
         {
-            testResolutionMismatch(writerSchema, value, readerSchema);
+            if (expectedExceptionType != null)
+            {
+                Assert.Throws(expectedExceptionType, () => { testResolutionMismatch(writerSchema, value, readerSchema); });
+            }
+            else
+            {
+                testResolutionMismatch(writerSchema, value, readerSchema);
+            }
         }
 
         [TestCase("{\"type\":\"record\",\"name\":\"r\",\"fields\":" +
             "[{\"name\":\"f1\",\"type\":[\"int\", \"null\"]},{\"name\":\"f2\",\"type\":\"int\"}]}",
             new object[] { "f1", 101, "f2", 100 }, "int",
-            ExpectedException = typeof(AvroException), Description = "Non-record schema")]
+            typeof(AvroException), Description = "Non-record schema")]
         [TestCase("{\"type\":\"record\",\"name\":\"r\",\"fields\":" +
             "[{\"name\":\"f1\",\"type\":[\"int\", \"null\"]},{\"name\":\"f2\",\"type\":\"int\"}]}",
             new object[] { "f1", 101, "f2", 100 },
             "{\"type\":\"record\",\"name\":\"s\",\"fields\":" +
             "[{\"name\":\"f2\",\"type\":\"int\"}]}",
-            ExpectedException = typeof(AvroException), Description = "Name mismatch")]
+            typeof(AvroException), Description = "Name mismatch")]
         [TestCase("{\"type\":\"record\",\"name\":\"r\",\"fields\":" +
             "[{\"name\":\"f1\",\"type\":[\"int\", \"null\"]},{\"name\":\"f2\",\"type\":\"int\"}]}",
             new object[] { "f1", 101, "f2", 100 },
             "{\"type\":\"record\",\"name\":\"r\",\"fields\":" +
             "[{\"name\":\"f2\",\"type\":\"string\"}]}",
-            ExpectedException = typeof(AvroException), Description = "incompatible field")]
+            typeof(AvroException), Description = "incompatible field")]
         [TestCase("{\"type\":\"record\",\"name\":\"r\",\"fields\":" +
             "[{\"name\":\"f1\",\"type\":[\"int\", \"null\"]},{\"name\":\"f2\",\"type\":\"int\"}]}",
             new object[] { "f1", 101, "f2", 100 },
             "{\"type\":\"record\",\"name\":\"r\",\"fields\":" +
             "[{\"name\":\"f3\",\"type\":\"string\"}]}",
-            ExpectedException = typeof(AvroException), Description = "new field without default")]
-        public void TestResolutionMismatch_record(string ws, object[] actual, string rs)
+            typeof(AvroException), Description = "new field without default")]
+        public void TestResolutionMismatch_record(string ws, object[] actual, string rs, Type expectedExceptionType = null)
         {
-            testResolutionMismatch(ws, mkRecord(actual, Schema.Parse(ws) as RecordSchema), rs);
+            if (expectedExceptionType != null)
+            {
+                Assert.Throws(expectedExceptionType, () => { testResolutionMismatch(ws, mkRecord(actual, Schema.Parse(ws) as RecordSchema), rs); });
+            }
+            else
+            {
+                testResolutionMismatch(ws, mkRecord(actual, Schema.Parse(ws) as RecordSchema), rs);
+            }
         }
 
         [TestCase("{\"type\":\"enum\",\"name\":\"e\",\"symbols\":[\"s\", \"t\"]}", "s", "int",
-            ExpectedException = typeof(AvroException), Description = "Non-enum schema")]
+            typeof(AvroException), Description = "Non-enum schema")]
         [TestCase("{\"type\":\"enum\",\"name\":\"e\",\"symbols\":[\"s\", \"t\"]}",
             "s", "{\"type\":\"enum\",\"name\":\"f\",\"symbols\":[\"s\", \"t\"]}",
-            ExpectedException = typeof(AvroException), Description = "Name mismatch")]
+            typeof(AvroException), Description = "Name mismatch")]
         [TestCase("{\"type\":\"enum\",\"name\":\"e\",\"symbols\":[\"s\", \"t\"]}",
             "s", "{\"type\":\"enum\",\"name\":\"f\",\"symbols\":[\"t\", \"u\"]}",
-            ExpectedException = typeof(AvroException), Description = "Incompatible symbols")]
-        public void TestResolutionMismatch_enum(string ws, string value, string rs)
+            typeof(AvroException), Description = "Incompatible symbols")]
+        public void TestResolutionMismatch_enum(string ws, string value, string rs, Type expectedExceptionType = null)
         {
-            testResolutionMismatch(ws, mkEnum(ws, value), rs);
+            if (expectedExceptionType != null)
+            {
+                Assert.Throws(expectedExceptionType, () => { testResolutionMismatch(ws, mkEnum(ws, value), rs); });
+            }
+            else
+            {
+                testResolutionMismatch(ws, mkEnum(ws, value), rs);
+            }
         }
 
         [TestCase("{\"type\":\"map\",\"values\":\"int\"}", new object[] { "a", 0 }, "int",
-            ExpectedException = typeof(AvroException), Description = "Non-map schema")]
+            typeof(AvroException), Description = "Non-map schema")]
         [TestCase("{\"type\":\"map\",\"values\":\"int\"}",
             new object[] { "a", 0 }, "{\"type\":\"map\",\"values\":\"string\"}",
-            ExpectedException = typeof(AvroException), Description = "Name mismatch")]
-        public void TestResolutionMismatch_map(string ws, object[] value, string rs)
+            typeof(AvroException), Description = "Name mismatch")]
+        public void TestResolutionMismatch_map(string ws, object[] value, string rs, Type expectedExceptionType = null)
         {
-            testResolutionMismatch(ws, mkMap(value), rs);
+            if (expectedExceptionType != null)
+            {
+                Assert.Throws(expectedExceptionType, () => { testResolutionMismatch(ws, mkMap(value), rs); });
+            }
+            else
+            {
+                testResolutionMismatch(ws, mkMap(value), rs);
+            }
         }
 
         [TestCase("{\"type\":\"fixed\",\"name\":\"f\",\"size\":2}", new byte[] { 1, 1 }, "int",
-            ExpectedException = typeof(AvroException), Description = "Non-fixed schema")]
+            typeof(AvroException), Description = "Non-fixed schema")]
         [TestCase("{\"type\":\"fixed\",\"name\":\"f\",\"size\":2}",
             new byte[] { 1, 1 }, "{\"type\":\"fixed\",\"name\":\"g\",\"size\":2}",
-            ExpectedException = typeof(AvroException), Description = "Name mismatch")]
+            typeof(AvroException), Description = "Name mismatch")]
         [TestCase("{\"type\":\"fixed\",\"name\":\"f\",\"size\":2}",
             new byte[] { 1, 1 }, "{\"type\":\"fixed\",\"name\":\"f\",\"size\":1}",
-            ExpectedException = typeof(AvroException), Description = "Size mismatch")]
-        public void TestResolutionMismatch_fixed(string ws, byte[] value, string rs)
+            typeof(AvroException), Description = "Size mismatch")]
+        public void TestResolutionMismatch_fixed(string ws, byte[] value, string rs, Type expectedExceptionType = null)
         {
-            testResolutionMismatch(ws, mkFixed(ws, value), rs);
+            if (expectedExceptionType != null)
+            {
+                Assert.Throws(expectedExceptionType, () => { testResolutionMismatch(ws, mkFixed(ws, value), rs); });
+            }
+            else
+            {
+                 testResolutionMismatch(ws, mkFixed(ws, value), rs); 
+            }
         }
 
         [Test]
diff --git a/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs b/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs
index 19eeee8..453d2ed 100644
--- a/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs
+++ b/lang/csharp/src/apache/test/Protocol/ProtocolTest.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -49,7 +49,7 @@ namespace Avro.Test
       ""errors"": [""Curse"", ""CurseMore""]
     }
   }
-}", true)]
+}", true, TestName = "TestProtocol0")]
         [TestCase(@"{
   ""protocol"" : ""MyProtocol"",
   ""namespace"" : ""com.foo"",
@@ -107,7 +107,7 @@ namespace Avro.Test
 	""type"" : ""int""
    }
    ]
-}", true)]
+}", true, TestName = "TestProtocol1")]
         [TestCase(@"{
   ""protocol"" : ""MyProtocol"",
   ""namespace"" : ""com.bar"",
@@ -168,7 +168,7 @@ namespace Avro.Test
 	""type"" : ""int""
    }
    ]
-}", true)]
+}", true, TestName = "TestProtocol2")]
         public static void TestProtocol(string str, bool valid)
         {
             Protocol protocol = Protocol.Parse(str);
@@ -221,7 +221,7 @@ namespace Avro.Test
     }
   }
 }",
-  true,true)]
+  true,true, TestName = "TestProtocolHash_ProtocolsMatch")]
         // Protocols match, order of schemas in 'types' are different
         [TestCase(
 @"{
@@ -262,7 +262,7 @@ namespace Avro.Test
     }
   }
 }",
-  false,true)]
+  false,true, TestName = "TestProtocolHash_ProtocolsMatch_OrderOfSchemasInTypesAreDifferent")]
         // Name of protocol is different
         [TestCase(
 @"{
@@ -303,7 +303,7 @@ namespace Avro.Test
     }
   }
 }",
-  false,false)]
+  false,false, TestName = "TestProtocolHash_NameOfProtocolIsDifferent")]
         // Name of a message request is different: 'hi'
         [TestCase(
 @"{
@@ -344,7 +344,7 @@ namespace Avro.Test
     }
   }
 }",
-  false,false)]
+  false,false, TestName = "TestProtocolHash_NameOfMessageRequestIsDifferent")]
         // Name of a type is different : Curse1
         [TestCase(
 @"{
@@ -385,7 +385,7 @@ namespace Avro.Test
     }
   }
 }",
-  false,false)]
+  false,false, TestName = "TestProtocolHash_NameOfTypeIsDifferent_Curse1")]
         // Name of a record field is different: 'mymessage'
         [TestCase(
 @"{
@@ -426,7 +426,7 @@ namespace Avro.Test
     }
   }
 }",
-  false,false)]
+  false,false, TestName = "TestProtocolHash_NameOfRecordFieldIsDifferent_MyMessage")]
         public static void TestProtocolHash(string str1, string str2, bool md5_equal, bool hash_equal)
         {
             Protocol protocol1 = Protocol.Parse(str1);
diff --git a/lang/csharp/src/apache/test/Schema/AliasTest.cs b/lang/csharp/src/apache/test/Schema/AliasTest.cs
index 96dec9e..c480076 100644
--- a/lang/csharp/src/apache/test/Schema/AliasTest.cs
+++ b/lang/csharp/src/apache/test/Schema/AliasTest.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -143,64 +143,64 @@ namespace Avro.Test
                   @"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
-                  true)]
+                  true, TestName = "TestRecordAliasesResolution1")]
         [TestCase(2,@"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
                   @"{""type"":""record"",""name"":""NewRec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
-                  false)]
+                  false, TestName = "TestRecordAliasesResolution2")]
         [TestCase(3,@"{""type"":""record"",""name"":""Rec"", ""aliases"":[""NewRec""],
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
                   @"{""type"":""record"",""name"":""NewRec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
-                  true)]
+                  true, TestName = "TestRecordAliasesResolution3")]
         [TestCase(4,@"{""type"":""record"",""name"":""Rec"", ""aliases"":[""OtherRec"",""DiffRec""],
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
                   @"{""type"":""record"",""name"":""NewRec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
-                  false)]
+                  false, TestName = "TestRecordAliasesResolution4")]
         [TestCase(5,@"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f3"",""type"": ""int""}]}",
                   @"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
-                  false)]
+                  false, TestName = "TestRecordAliasesResolution5")]
         [TestCase(6,@"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f3"",""type"": ""int"", ""aliases"":[""f2""]}]}",
                   @"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
-                  true)]
+                  true, TestName = "TestRecordAliasesResolution6")]
         [TestCase(7,@"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f3"",""type"": ""int"", ""aliases"":[""f4"",""f5""]}]}",
                   @"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"":""long"" },
                                  {""name"":""f2"",""type"": ""int""}]}",
-                  false)]
+                  false, TestName = "TestRecordAliasesResolution7")]
         [TestCase(8,@"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"": {""type"":""enum"", ""name"":""Symbol"", ""symbols"":[""A""] }}]}",
                   @"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"": {""type"":""enum"", ""name"":""NewSymbol"", ""symbols"":[""A""] }}]}",
-                  false)]
+                  false, TestName = "TestRecordAliasesResolution8")]
         [TestCase(9,@"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"": {""type"":""enum"", ""name"":""Symbol"", ""aliases"":[""NewSymbol""], ""symbols"":[""A""] }}]}",
                   @"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"": {""type"":""enum"", ""name"":""NewSymbol"", ""symbols"":[""A""] }}]}",
-                  true)]
+                  true, TestName = "TestRecordAliasesResolution9")]
         [TestCase(10,@"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"": {""type"":""enum"", ""name"":""Symbol"", ""aliases"":[""DiffSymbol""], ""symbols"":[""A""] }}]}",
                   @"{""type"":""record"",""name"":""Rec"",
                      ""fields"":[{""name"":""f1"",""type"": {""type"":""enum"", ""name"":""NewSymbol"", ""symbols"":[""A""] }}]}",
-                  false)]
+                  false, TestName = "TestRecordAliasesResolution10")]
         [TestCase(11,@"{""type"":""record"",""name"":""Rec"",""aliases"":[""NewRec""],
                     ""fields"":[{""name"":""f2"",""aliases"":[""f1""],""type"": {""type"":""enum"", ""name"":""Symbol"", ""aliases"":[""NewSymbol""], ""symbols"":[""A""] }},
                                 {""name"":""f3"",""aliases"":[""f4""],""type"": {""type"":""fixed"", ""name"":""Fixed"", ""aliases"":[""NewFixed""], ""size"": 1 }}
@@ -209,7 +209,7 @@ namespace Avro.Test
                      ""fields"":[{""name"":""f1"",""type"": {""type"":""enum"", ""name"":""NewSymbol"", ""symbols"":[""A""] }},
                                  {""name"":""f4"",""type"": {""type"":""fixed"", ""name"":""NewFixed"", ""size"": 1 }}
                                 ]}",
-                  true)]
+                  true, TestName = "TestRecordAliasesResolution11")]
         [TestCase(12,@"{""type"":""record"",""name"":""Rec"",""aliases"":[""NewRec""],
                      ""fields"":[{""name"":""f2"",""aliases"":[""f1""],""type"": {""type"":""enum"", ""name"":""Symbol"", ""aliases"":[""NewSymbol""], ""symbols"":[""A""] }},
                                  {""name"":""f3"",""aliases"":[""f4""],""type"": {""type"":""fixed"", ""name"":""Fixed"", ""aliases"":[""NewFixed""], ""size"":1 }}
@@ -218,7 +218,7 @@ namespace Avro.Test
                      ""fields"":[{""name"":""f1"",""type"": {""type"":""enum"", ""name"":""NewSymbol"", ""symbols"":[""A"",""B""] }},
                                  {""name"":""f4"",""type"": {""type"":""fixed"", ""name"":""NewFixed"", ""size"":1 }}
                                 ]}",
-                  true)]
+                  true, TestName = "TestRecordAliasesResolution12")]
 
         public void TestRecordAliasesResolution(int testid, string reader, string writer, bool canread)
         {
diff --git a/lang/csharp/src/apache/test/Schema/SchemaNormalizationTests.cs b/lang/csharp/src/apache/test/Schema/SchemaNormalizationTests.cs
index c3b0cd1..f097715 100644
--- a/lang/csharp/src/apache/test/Schema/SchemaNormalizationTests.cs
+++ b/lang/csharp/src/apache/test/Schema/SchemaNormalizationTests.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -50,7 +50,9 @@ namespace Avro.Test
 
         private static List<object[]> ProvideFingerprintTestCases()
         {
-            using (StreamReader reader = new StreamReader("../../../../../share/test/data/schema-tests.txt"))
+            var dir = Path.GetDirectoryName(new Uri(typeof(SchemaNormalizationTests).Assembly.CodeBase).LocalPath);
+            var testsPath = Path.Combine(dir, "../../../../../../../../share/test/data/schema-tests.txt");
+            using (StreamReader reader = new StreamReader(testsPath))
             {
                 return CaseFinder.Find(reader, "fingerprint", new List<object[]>());
             }
@@ -58,7 +60,9 @@ namespace Avro.Test
 
         private static List<object[]> ProvideCanonicalTestCases()
         {
-            using (StreamReader reader = new StreamReader("../../../../../share/test/data/schema-tests.txt"))
+            var dir = Path.GetDirectoryName(new Uri(typeof(SchemaNormalizationTests).Assembly.CodeBase).LocalPath);
+            var testsPath = Path.Combine(dir, "../../../../../../../../share/test/data/schema-tests.txt");
+            using (StreamReader reader = new StreamReader(testsPath))
             {
                 return CaseFinder.Find(reader, "canonical", new List<object[]>());
             }
diff --git a/lang/csharp/src/apache/test/Schema/SchemaTests.cs b/lang/csharp/src/apache/test/Schema/SchemaTests.cs
index 8e13087..41db0a2 100644
--- a/lang/csharp/src/apache/test/Schema/SchemaTests.cs
+++ b/lang/csharp/src/apache/test/Schema/SchemaTests.cs
@@ -64,23 +64,23 @@ namespace Avro.Test
             "\"fields\":[{\"name\":\"value\",\"type\":\"long\"},{\"name\":\"next\",\"type\":[\"LongList\",\"null\"]}]}")] // Recursive.
         [TestCase("{\"type\":\"record\",\"name\":\"LongList\"," +
             "\"fields\":[{\"name\":\"value\",\"type\":\"long\"},{\"name\":\"next\",\"type\":[\"LongListA\",\"null\"]}]}",
-            Description = "Unknown name", ExpectedException = typeof(SchemaParseException))]
+            typeof(SchemaParseException), Description = "Unknown name")]
         [TestCase("{\"type\":\"record\",\"name\":\"LongList\"}",
-            Description = "No fields", ExpectedException = typeof(SchemaParseException))]
+            typeof(SchemaParseException), Description = "No fields")]
         [TestCase("{\"type\":\"record\",\"name\":\"LongList\", \"fields\": \"hi\"}",
-            Description = "Fields not an array", ExpectedException = typeof(SchemaParseException))]
+            typeof(SchemaParseException), Description = "Fields not an array")]
         [TestCase("[{\"type\": \"record\",\"name\": \"Test\",\"namespace\":\"ns1\",\"fields\": [{\"name\": \"f\",\"type\": \"long\"}]}," + 
                    "{\"type\": \"record\",\"name\": \"Test\",\"namespace\":\"ns2\",\"fields\": [{\"name\": \"f\",\"type\": \"long\"}]}]")]
         // Enum
         [TestCase("{\"type\": \"enum\", \"name\": \"Test\", \"symbols\": [\"A\", \"B\"]}")]
         [TestCase("{\"type\": \"enum\", \"name\": \"Status\", \"symbols\": \"Normal Caution Critical\"}",
-            Description = "Symbols not an array", ExpectedException = typeof(SchemaParseException))]
+            typeof(SchemaParseException), Description = "Symbols not an array")]
         [TestCase("{\"type\": \"enum\", \"name\": [ 0, 1, 1, 2, 3, 5, 8 ], \"symbols\": [\"Golden\", \"Mean\"]}",
-            Description = "Name not a string", ExpectedException = typeof(SchemaParseException))]
+            typeof(SchemaParseException), Description = "Name not a string")]
         [TestCase("{\"type\": \"enum\", \"symbols\" : [\"I\", \"will\", \"fail\", \"no\", \"name\"]}",
-            Description = "No name", ExpectedException = typeof(SchemaParseException))]
+            typeof(SchemaParseException), Description = "No name")]
         [TestCase("{\"type\": \"enum\", \"name\": \"Test\", \"symbols\" : [\"AA\", \"AA\"]}",
-            Description = "Duplicate symbol", ExpectedException = typeof(SchemaParseException))]
+            typeof(SchemaParseException), Description = "Duplicate symbol")]
 
         // Array
         [TestCase("{\"type\": \"array\", \"items\": \"long\"}")]
@@ -93,22 +93,27 @@ namespace Avro.Test
         // Union
         [TestCase("[\"string\", \"null\", \"long\"]")]
         [TestCase("[\"string\", \"long\", \"long\"]",
-            Description = "Duplicate type", ExpectedException = typeof(SchemaParseException))]
+            typeof(SchemaParseException), Description = "Duplicate type")]
         [TestCase("[{\"type\": \"array\", \"items\": \"long\"}, {\"type\": \"array\", \"items\": \"string\"}]",
-            Description = "Duplicate type", ExpectedException = typeof(SchemaParseException))]
+            typeof(SchemaParseException), Description = "Duplicate type")]
         [TestCase("{\"type\":[\"string\", \"null\", \"long\"]}")]
 
         // Fixed
         [TestCase("{ \"type\": \"fixed\", \"name\": \"Test\", \"size\": 1}")]
         [TestCase("{\"type\": \"fixed\", \"name\": \"MyFixed\", \"namespace\": \"org.apache.hadoop.avro\", \"size\": 1}")]
-        [TestCase("{ \"type\": \"fixed\", \"name\": \"Test\", \"size\": 1}")]
-        [TestCase("{ \"type\": \"fixed\", \"name\": \"Test\", \"size\": 1}")]
-        [TestCase("{\"type\": \"fixed\", \"name\": \"Missing size\"}", ExpectedException = typeof(SchemaParseException))]
+        [TestCase("{\"type\": \"fixed\", \"name\": \"Missing size\"}", typeof(SchemaParseException))]
         [TestCase("{\"type\": \"fixed\", \"size\": 314}",
-            Description = "No name", ExpectedException = typeof(SchemaParseException))]
-        public void TestBasic(string s)
+            typeof(SchemaParseException), Description = "No name")]
+        public void TestBasic(string s, Type expectedExceptionType = null)
         {
-            Schema.Parse(s);
+            if (expectedExceptionType != null)
+            {
+                Assert.Throws(expectedExceptionType, () => { Schema.Parse(s); });
+            }
+            else
+            {
+                Schema.Parse(s);
+            }
         }
 
         [TestCase("null", Schema.Type.Null)]
@@ -305,7 +310,7 @@ namespace Avro.Test
             Assert.AreEqual(expectedDoc, fs.Documentation);
         }
 
-        [TestCase("a", "o.a.h", Result = "o.a.h.a")]
+        [TestCase("a", "o.a.h", ExpectedResult = "o.a.h.a")]
         public string testFullname(string s1, string s2)
         {
             var name = new SchemaName(s1, s2, null);
diff --git a/lang/csharp/src/apache/test/Specific/SpecificTests.cs b/lang/csharp/src/apache/test/Specific/SpecificTests.cs
index aedf8f2..a88976e 100644
--- a/lang/csharp/src/apache/test/Specific/SpecificTests.cs
+++ b/lang/csharp/src/apache/test/Specific/SpecificTests.cs
@@ -31,6 +31,7 @@ namespace Avro.Test
     [TestFixture]
     class SpecificTests
     {
+#if !NETCOREAPP2_0 // System.CodeDom compilation not supported in .NET Core: https://github.com/dotnet/corefx/issues/12180
         // The dynamically created assembly used in the test below can only be created
         // once otherwise repeated tests will fail as the same type name will exist in
         // multiple assemblies and so the type in the test and the type found by ObjectCreator
@@ -157,8 +158,7 @@ namespace Avro.Test
     myArray3.Add(o1);
     myArray3.Add(o2);
 
-"}
-)]
+"}, TestName = "TestSpecific")]
         public void TestSpecific(string str, object[] result)
         {
             if(compres == null)
@@ -191,7 +191,7 @@ namespace Avro.Test
             // compile
             var comparam = new CompilerParameters(new string[] { "mscorlib.dll" });
             comparam.ReferencedAssemblies.Add("System.dll");
-            comparam.ReferencedAssemblies.Add("Avro.dll");
+            comparam.ReferencedAssemblies.Add(Path.Combine(TestContext.CurrentContext.TestDirectory, "Avro.dll"));
             comparam.GenerateInMemory = true;
             var ccp = new Microsoft.CSharp.CSharpCodeProvider();
             var units = new CodeCompileUnit[] { compileUnit };
@@ -225,6 +225,7 @@ namespace Avro.Test
             Assert.IsFalse(rec2 == null);
             AssertSpecificRecordEqual(rec, rec2);
         }
+#endif
 
         [TestCase]
         public void TestEnumResolution()
diff --git a/lang/csharp/src/apache/test/Utils/CaseFinderTests.cs b/lang/csharp/src/apache/test/Utils/CaseFinderTests.cs
index 1257863..7b46096 100644
--- a/lang/csharp/src/apache/test/Utils/CaseFinderTests.cs
+++ b/lang/csharp/src/apache/test/Utils/CaseFinderTests.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -72,7 +72,7 @@ namespace Avro.Test.Utils
             Assert.True(Eq(result, expectedOutput), Pr(result));
         }
 
-        private List<Object[]> OutputTestCases()
+        private static List<Object[]> OutputTestCases()
         {
             List<Object[]> result = new List<Object[]>();
             result.Add(new Object[] { "", "foo", new List<object[]> { } });
@@ -82,7 +82,6 @@ namespace Avro.Test.Utils
             result.Add(new Object[] { "<<INPUT a\r<<OUTPUT b", "OUTPUT", new List<object[]> { new object[] { "a", "b" } } });
             result.Add(new Object[] { "// This is a test\n<<INPUT a\n\n\n<<OUTPUT b", "OUTPUT", new List<object[]> { new object[] { "a", "b" } } });
             result.Add(new Object[] { "<<INPUT a\n<<OUTPUT\nb\nOUTPUT", "OUTPUT", new List<object[]> { new object[] { "a", "b" } } });
-            result.Add(new Object[] { "<<INPUT a\n<<OUTPUT\nb\nOUTPUT", "OUTPUT", new List<object[]> { new object[] { "a", "b" } } });
             result.Add(new Object[] { "<<INPUT a\n<<OUTPUT\nb\n\nOUTPUT", "OUTPUT", new List<object[]> { new object[] { "a", "b\n" } } });
             result.Add(new Object[] { "<<INPUT a\n<<OUTPUT\n\n  b  \n\nOUTPUT", "OUTPUT", new List<object[]> { new object[] { "a", "\n  b  \n" } } });
             result.Add(new Object[] { "<<INPUT a\n<<O b\n<<INPUT c\n<<O d", "O", new List<object[]> { new object[] { "a", "b" }, new object[] { "c", "d" } } });
diff --git a/pom.xml b/pom.xml
index 8f0276e..7fa4f36 100644
--- a/pom.xml
+++ b/pom.xml
@@ -264,7 +264,7 @@
                 <exclude>lang/java/tools/src/test/compiler/output-string/Position.java</exclude>
                 <exclude>lang/java/tools/src/test/compiler/output/Player.java</exclude>
                 <exclude>lang/java/tools/src/test/compiler/output/Position.java</exclude>
-                <exclude>lang/csharp/src/apache/test/Ipc/GeneratedFiles/**/*.cs</exclude>
+                <exclude>lang/csharp/src/apache/ipc.test/GeneratedFiles/**/*.cs</exclude>
                 <exclude>lang/csharp/src/apache/perf/com/foo/*.cs</exclude>
                 <exclude>lang/csharp/src/apache/ipc/org/apache/avro/ipc/*.cs</exclude>
                 <exclude>lang/java/mapred/src/test/resources/org/apache/avro/mapreduce/mapreduce-test-input.txt</exclude>
@@ -319,7 +319,7 @@
                 <exclude>lang/perl/Changes</exclude>
                 <exclude>lang/c/README.maintaining_win32.txt</exclude>
                 <exclude>lang/c/docs/index.txt</exclude>
-                <exclude>lang/csharp/README</exclude>
+                <exclude>lang/csharp/README.md</exclude>
                 <exclude>lang/java/archetypes/avro-service-archetype/src/test/integration/projects/basic/archetype.properties</exclude> <!-- used to generate user projects -->
                 <!-- files and directories covered by LICENSE.txt -->
                 <exclude>lang/py/lib/simplejson/**</exclude>
diff --git a/share/docker/Dockerfile b/share/docker/Dockerfile
index bbf675c..ca27195 100644
--- a/share/docker/Dockerfile
+++ b/share/docker/Dockerfile
@@ -28,6 +28,12 @@ RUN curl -sL https://deb.nodesource.com/setup_4.x | bash -
 
 # Install dependencies from packages
 RUN apt-get -qq update && \
+  # Add the repository for Mono (https://www.mono-project.com/download/stable/#download-lin-debian)
+  apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \
+  apt-get -qq install -y apt-transport-https && \
+  echo "deb https://download.mono-project.com/repo/debian stable-jessie main" | tee /etc/apt/sources.list.d/mono-official-stable.list && \
+  apt-get -qq update && \
+  # END Add the repository for Mono
   apt-get -qq install --no-install-recommends -y \
     ant \
     asciidoc \
@@ -50,8 +56,8 @@ RUN apt-get -qq update && \
     make \
     maven \
     mono-devel \
+    mono-complete \
     nodejs \
-    nunit \
     perl \
     php5 \
     php5-gmp \
@@ -91,15 +97,6 @@ RUN curl -L http://cpanmin.us | perl - --self-upgrade && \
   IO::String Object::Tiny Compress::Zlib Test::More \
   Test::Exception Test::Pod
 
-# Install mono modules
-RUN mkdir -p /tmp/nunit/ && \
-  cd /tmp/nunit/ && \
-  curl -L -s -o nunit.zip https://github.com/nunit-legacy/nunitv2/releases/download/2.7.0/NUnit-2.7.0.zip && \
-  unzip nunit.zip && \
-  rm nunit.zip
-
-ENV MONO_PATH /tmp/nunit/bin/lib
-
 # Install Ruby modules
 RUN gem install echoe yajl-ruby multi_json snappy