Skip to content

Commit 185a556

Browse files
author
Kolappan N
committed
Added helper functions
1 parent 83298c3 commit 185a556

File tree

8 files changed

+202
-11
lines changed

8 files changed

+202
-11
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
9+
## [0.0.1] - 2019-01-02
810
### Added
911
- Added changelog.
10-
- Added core library.
12+
- Added core library.
13+
- Added API Helper functions
14+
15+
### Changed
16+
- Format of model validation errors
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using Core.Constants;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Net;
5+
6+
namespace API.Helpers
7+
{
8+
public static class Notification
9+
{
10+
/// <summary>
11+
/// Contains mapping for error codes to the Error messages and status
12+
/// </summary>
13+
private static readonly Dictionary<int, Tuple<string, HttpStatusCode>> notifications = new Dictionary<int, Tuple<string, HttpStatusCode>>()
14+
{
15+
{ -1, Tuple.Create(Errors.InternalServerError, HttpStatusCode.InternalServerError) },
16+
{ -102, Tuple.Create(Errors.AccountNotFound, HttpStatusCode.Unauthorized) },
17+
{ -103, Tuple.Create(Errors.InvalidCredentials, HttpStatusCode.Unauthorized) },
18+
{ -104, Tuple.Create(Errors.AccountDeleted, HttpStatusCode.Unauthorized) }
19+
};
20+
21+
/// <summary>
22+
/// Returns the error message, and <see cref="HttpStatusCode"/> for the specified error code
23+
/// </summary>
24+
/// <param name="code">The error code obtained from business layer or other functions</param>
25+
/// <returns></returns>
26+
public static Tuple<string, HttpStatusCode> GetNotification(int code)
27+
{
28+
Tuple<string, HttpStatusCode> value;
29+
bool hasValue = notifications.TryGetValue(code, out value);
30+
if (!hasValue)
31+
{
32+
value = Tuple.Create(Errors.InternalServerError, HttpStatusCode.InternalServerError);
33+
}
34+
return value;
35+
}
36+
}
37+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Microsoft.AspNetCore.Mvc.ModelBinding;
3+
4+
namespace API.Helpers
5+
{
6+
public class ValidationHelper
7+
{
8+
private WebAPIHelper webAPIHelper;
9+
10+
public ValidationHelper()
11+
{
12+
webAPIHelper = new WebAPIHelper();
13+
}
14+
15+
public BadRequestObjectResult GetDataValidationError(ModelStateDictionary model)
16+
{
17+
var errorText = string.Empty;
18+
foreach (var value in model.Values)
19+
{
20+
for (var i = 0; i < value.Errors.Count; i++)
21+
{
22+
errorText = errorText + ", " + value.Errors[i].ErrorMessage;
23+
}
24+
}
25+
errorText = errorText.Substring(1, errorText.Length - 1);
26+
return webAPIHelper.CreateBadRequest(errorText);
27+
}
28+
}
29+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using Core.Constants;
2+
using Microsoft.AspNetCore.Mvc;
3+
using Model;
4+
using System;
5+
using System.Net;
6+
7+
namespace API.Helpers
8+
{
9+
public class WebAPIHelper
10+
{
11+
#region [Declarations]
12+
13+
private APIResponse apiResponse;
14+
15+
#endregion [Declarations]
16+
17+
/// <summary>
18+
/// Creates a error or successful response based on the data to be sent
19+
/// </summary>
20+
/// <param name="data"></param>
21+
/// <returns></returns>
22+
public JsonResult CreateResponse(object data)
23+
{
24+
if (data == null || (data is bool && Convert.ToBoolean(data) == false))
25+
{
26+
apiResponse = new APIResponse(string.Empty, Errors.InternalServerError, true);
27+
return new JsonResult(apiResponse)
28+
{
29+
StatusCode = (int)HttpStatusCode.InternalServerError
30+
};
31+
}
32+
else if (data is int && Convert.ToInt32(data) < 0)
33+
{
34+
Tuple<string, HttpStatusCode> resData = Notification.GetNotification(Convert.ToInt32(data));
35+
apiResponse = new APIResponse(string.Empty, resData.Item1, true);
36+
return new JsonResult(apiResponse)
37+
{
38+
StatusCode = (int)resData.Item2
39+
};
40+
}
41+
else if (data is APIResponse)
42+
{
43+
apiResponse = (APIResponse)data;
44+
return new JsonResult(apiResponse)
45+
{
46+
StatusCode = apiResponse.IsError ? (int)HttpStatusCode.InternalServerError : (int)HttpStatusCode.OK
47+
};
48+
}
49+
else
50+
{
51+
apiResponse = new APIResponse(data, string.Empty, false);
52+
return new JsonResult(apiResponse);
53+
}
54+
}
55+
56+
/// <summary>
57+
/// Creates a Json response with 400 status code(Bad Request)
58+
/// </summary>
59+
/// <param name="errorText">Error message to be sent</param>
60+
/// <returns>The http response</returns>
61+
public BadRequestObjectResult CreateBadRequest(string errorText)
62+
{
63+
apiResponse = new APIResponse(string.Empty, errorText, true);
64+
return new BadRequestObjectResult(apiResponse);
65+
}
66+
67+
/// <summary>
68+
/// Creates an error response with a 500 status code(Internal Server error)
69+
/// </summary>
70+
/// <param name="errorText">Error message to be sent</param>
71+
/// <param name="data">Data to be sent</param>
72+
/// <returns></returns>
73+
public JsonResult CreateErrorResponse(string errorText, dynamic data = null)
74+
{
75+
apiResponse = new APIResponse(data, errorText, true);
76+
return new JsonResult(apiResponse)
77+
{
78+
StatusCode = (int)HttpStatusCode.InternalServerError
79+
};
80+
}
81+
}
82+
}

src/WebApiBolierplate/API/Startup.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Threading.Tasks;
1+
using API.Helpers;
52
using Microsoft.AspNetCore.Builder;
63
using Microsoft.AspNetCore.Hosting;
7-
using Microsoft.AspNetCore.HttpsPolicy;
84
using Microsoft.AspNetCore.Mvc;
95
using Microsoft.Extensions.Configuration;
106
using Microsoft.Extensions.DependencyInjection;
11-
using Microsoft.Extensions.Logging;
12-
using Microsoft.Extensions.Options;
137

148
namespace API
159
{
@@ -26,6 +20,15 @@ public Startup(IConfiguration configuration)
2620
public void ConfigureServices(IServiceCollection services)
2721
{
2822
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
23+
24+
var validationHelper = new ValidationHelper();
25+
26+
// To handle model validation errors and change it to
27+
// Ref: https://stackoverflow.com/a/51159755/5407188
28+
services.Configure<ApiBehaviorOptions>(o =>
29+
{
30+
o.InvalidModelStateResponseFactory = actionContext => validationHelper.GetDataValidationError(actionContext.ModelState);
31+
});
2932
}
3033

3134
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
</Project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace Core.Constants
2+
{
3+
/// <summary>
4+
/// Constains all the error messages across the application
5+
/// </summary>
6+
public class Errors
7+
{
8+
public const string InternalServerError = "Oops! An Internal Error Occured.";
9+
public const string DatabaseSaveFailed = "Failed to save to the database";
10+
11+
#region [Authorization]
12+
13+
public const string InvalidCredentials = "The credentials are invalid.";
14+
public const string UnauthorizedRequest = "The request is unauthorised.";
15+
public const string AccountNotFound = "No acount exists for the specified email. Are you trying to Signup?";
16+
public const string AccountDeleted = "The user account has been deleted. Contact administrator.";
17+
18+
#endregion [Authorization]
19+
}
20+
}

src/WebApiBolierplate/WebApiBolierplate.sln

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
44
VisualStudioVersion = 15.0.28307.168
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API", "API\API.csproj", "{63F1C3A8-3F0D-47F1-8BC9-2E2645C6ABF3}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "API", "API\API.csproj", "{63F1C3A8-3F0D-47F1-8BC9-2E2645C6ABF3}"
77
EndProject
88
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{DF265B0E-249D-4395-BCE8-03B031708DB5}"
99
EndProject
10-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Lib", "Core.Lib\Core.Lib.csproj", "{3C9B3915-9D3D-4D3B-ADB4-1F976DF2B60B}"
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core.Lib", "Core.Lib\Core.Lib.csproj", "{3C9B3915-9D3D-4D3B-ADB4-1F976DF2B60B}"
1111
EndProject
12-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "Model\Model.csproj", "{45F145EE-EB8D-401E-A1EA-1743F5A06C49}"
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj", "{45F145EE-EB8D-401E-A1EA-1743F5A06C49}"
13+
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Constants", "Core.Constants\Core.Constants.csproj", "{B97C8E88-5711-44D9-A362-43F91A6F2C0C}"
1315
EndProject
1416
Global
1517
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -29,12 +31,17 @@ Global
2931
{45F145EE-EB8D-401E-A1EA-1743F5A06C49}.Debug|Any CPU.Build.0 = Debug|Any CPU
3032
{45F145EE-EB8D-401E-A1EA-1743F5A06C49}.Release|Any CPU.ActiveCfg = Release|Any CPU
3133
{45F145EE-EB8D-401E-A1EA-1743F5A06C49}.Release|Any CPU.Build.0 = Release|Any CPU
34+
{B97C8E88-5711-44D9-A362-43F91A6F2C0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35+
{B97C8E88-5711-44D9-A362-43F91A6F2C0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{B97C8E88-5711-44D9-A362-43F91A6F2C0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
37+
{B97C8E88-5711-44D9-A362-43F91A6F2C0C}.Release|Any CPU.Build.0 = Release|Any CPU
3238
EndGlobalSection
3339
GlobalSection(SolutionProperties) = preSolution
3440
HideSolutionNode = FALSE
3541
EndGlobalSection
3642
GlobalSection(NestedProjects) = preSolution
3743
{3C9B3915-9D3D-4D3B-ADB4-1F976DF2B60B} = {DF265B0E-249D-4395-BCE8-03B031708DB5}
44+
{B97C8E88-5711-44D9-A362-43F91A6F2C0C} = {DF265B0E-249D-4395-BCE8-03B031708DB5}
3845
EndGlobalSection
3946
GlobalSection(ExtensibilityGlobals) = postSolution
4047
SolutionGuid = {5E2BFE0C-9475-430E-95F1-3D76F7FD2BBE}

0 commit comments

Comments
 (0)