Skip to content

Commit

Permalink
Added WCF REST error handler sample
Browse files Browse the repository at this point in the history
  • Loading branch information
sixeyed committed May 30, 2012
1 parent 1b5cde4 commit 58cd914
Show file tree
Hide file tree
Showing 23 changed files with 786 additions and 0 deletions.
Binary file modified .DS_Store
Binary file not shown.
10 changes: 10 additions & 0 deletions Sixeyed.WcfRestErrorHandler/Local.testsettings
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestSettings name="Local" id="a4692175-8e4d-4fa6-a81c-0c717c9f715c" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Description>These are default test settings for a local test run.</Description>
<Deployment enabled="false" />
<Execution>
<TestTypeSpecific />
<AgentRule name="Execution Agents">
</AgentRule>
</Execution>
</TestSettings>
@@ -0,0 +1,69 @@
using System.Net;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Sixeyed.WcfRestErrorHandler.Sample.Tests
{
[TestClass]
public class ErrorProneServiceTest
{
[TestMethod]
public void ServiceExceptionReturns500()
{
int statusCode;
string statusDescription;
var url = "http://localhost/Sixeyed.WcfRestErrorHandler.Sample/ErrorProneService.svc/dbz";
DownloadString(url, out statusCode, out statusDescription);
Assert.AreEqual(500, statusCode);
Assert.IsTrue(statusDescription.StartsWith("Something has gone wrong. Please contact our support team with helpdesk ID: "));
}

[TestMethod]
public void ClientExceptionReturns400()
{
int statusCode;
string statusDescription;

var url = "http://localhost/Sixeyed.WcfRestErrorHandler.Sample/ErrorProneService.svc/lastLogin?userId=96";
DownloadString(url, out statusCode, out statusDescription);
Assert.AreEqual(400, statusCode);
Assert.AreEqual("User with userId: 96 not found", statusDescription);

url = "http://localhost/Sixeyed.WcfRestErrorHandler.Sample/ErrorProneService.svc/lastLogin?userId=xyz";
DownloadString(url, out statusCode, out statusDescription);
Assert.AreEqual(400, statusCode);
Assert.AreEqual("Invalid userId. Must be provided as a positive integer", statusDescription);
}

[TestMethod]
public void ValidReturns200()
{
int statusCode;
string statusDescription;

var url = "http://localhost/Sixeyed.WcfRestErrorHandler.Sample/ErrorProneService.svc/lastLogin?userId=196";
DownloadString(url, out statusCode, out statusDescription);
Assert.AreEqual(200, statusCode);
Assert.AreEqual(string.Empty, statusDescription);
}

private void DownloadString(string url, out int statusCode, out string statusDescription)
{
string response = null;
using (var client = new WebClient())
{
try
{
response = client.DownloadString(url);
statusCode = 200;
statusDescription = string.Empty;
}
catch (WebException webEx)
{
var webResponse = (HttpWebResponse)webEx.Response;
statusCode = (int)webResponse.StatusCode;
statusDescription = webResponse.StatusDescription;
}
}
}
}
}
@@ -0,0 +1,26 @@
<Query Kind="Statements">
<Reference>&lt;RuntimeDirectory&gt;\System.Runtime.Serialization.dll</Reference>
<Namespace>System.Net</Namespace>
</Query>

var url = "http://localhost/Sixeyed.WcfRestErrorHandler.Sample/ErrorProneService.svc/lastLogin?userId=xyz";
//var url = "http://localhost/Sixeyed.WcfRestErrorHandler.Sample/ErrorProneService.svc/dbz";

string response = null;
using (var client = new WebClient())
{
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate {return true;};
client.Proxy = System.Net.GlobalProxySelection.GetEmptyWebProxy();
url.Dump("Request URL");
try
{
response = client.DownloadString(url);
response.Dump("Response");
client.Dump("Headers");
}
catch (WebException webEx)
{
var webResponse = (HttpWebResponse)webEx.Response;
string.Format("Status Code: {0}, Description: {1}", (int)webResponse.StatusCode, webResponse.StatusDescription).Dump("Error");
}
}
@@ -0,0 +1,13 @@
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyCompany("Sixeyed Consulting")]
[assembly: AssemblyCopyright("Copyright © Sixeyed Consulting 2012")]

[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

[assembly: AssemblyTitle("Sixeyed.WcfRestErrorHandler.Sample.Tests")]
[assembly: AssemblyProduct("Sixeyed.WcfRestErrorHandler.Sample")]
[assembly: Guid("50bdc178-18af-4591-ba8c-89f4c75055b0")]
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<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>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{16A320CE-881C-4586-BFD9-2DE02B9B3859}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Sixeyed.WcfRestErrorHandler.Sample.Tests</RootNamespace>
<AssemblyName>Sixeyed.WcfRestErrorHandler.Sample.Tests</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\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>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
<Visible>False</Visible>
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ErrorProneServiceTest.cs" />
</ItemGroup>
<ItemGroup>
<None Include="ErrorProneServiceTest.linq" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\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>
@@ -0,0 +1,6 @@
<%@ ServiceHost
Language="C#"
Debug="true"
Service="Sixeyed.WcfRestErrorHandler.Sample.ErrorProneService"
CodeBehind="ErrorProneService.svc.cs"
Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>
@@ -0,0 +1,42 @@
using System;
using System.ServiceModel;
using System.ServiceModel.Web;
using Sixeyed.WcfRestErrorHandler.ServiceModel.Exceptions;

namespace Sixeyed.WcfRestErrorHandler.Sample
{
/// <summary>
/// Sample service which throws client and server errors
/// </summary>
/// <remarks>
/// Host in IIS, not Cassini, if you want to return HTTP status description:
/// http://stackoverflow.com/questions/3418959/wcf-4-rest-service-cant-return-a-statusdescription-only-statuscode
/// </remarks>
[ServiceContract]
public class ErrorProneService
{
[OperationContract]
[WebGet(UriTemplate = "lastLogin?userId={userId}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
public DateTime GetLastLoggedInAt(string userId)
{
var iUserId = 0;
if (!int.TryParse(userId, out iUserId) || iUserId < 1)
{
throw new ClientException("Invalid userId. Must be provided as a positive integer");
}
if (iUserId < 100)
{
throw new ClientException("User with userId: {0} not found", iUserId);
}
return DateTime.Now.AddDays(-1);
}

[OperationContract]
[WebGet(UriTemplate = "dbz", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
public void DivideByZero()
{
var iUserId = 0;
var dbz = 1 / iUserId;
}
}
}
@@ -0,0 +1,13 @@
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyCompany("Sixeyed Consulting")]
[assembly: AssemblyCopyright("Copyright © Sixeyed Consulting 2012")]

[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

[assembly: AssemblyTitle("Sixeyed.WcfRestErrorHandler.Sample")]
[assembly: AssemblyProduct("Sixeyed.WcfRestErrorHandler.Sample")]
[assembly: Guid("6407e916-7b11-4ad0-856e-68eb8dc05e04")]
@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<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>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{58AB72FD-4EE5-4E51-AD2E-05BD040880A7}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Sixeyed.WcfRestErrorHandler.Sample</RootNamespace>
<AssemblyName>Sixeyed.WcfRestErrorHandler.Sample</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</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>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Services" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Content Include="ErrorProneService.svc" />
<Content Include="Web.config" />
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
</ItemGroup>
<ItemGroup>
<Compile Include="ErrorProneService.svc.cs">
<DependentUpon>ErrorProneService.svc</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Sixeyed.WcfRestErrorHandler.ServiceModel\Sixeyed.WcfRestErrorHandler.ServiceModel.csproj">
<Project>{2187E9EF-B50C-41CD-B69D-97E03DC612C1}</Project>
<Name>Sixeyed.WcfRestErrorHandler.ServiceModel</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>16958</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
<EnableWcfTestClientForSVCDefaultValue>True</EnableWcfTestClientForSVCDefaultValue>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<!-- 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>
@@ -0,0 +1,7 @@
<?xml version="1.0"?>

<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">

</configuration>
@@ -0,0 +1,11 @@
<?xml version="1.0"?>

<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">

<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>

</configuration>

0 comments on commit 58cd914

Please sign in to comment.