From 906a17ea3c222829eca7294285bfada172780693 Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Wed, 9 Dec 2015 17:30:35 +0000 Subject: [PATCH] Define ValidationErrorResult in SpaServices; use it in MusicStore --- .../ValidationErrorResult.cs | 30 +++++++++++ Microsoft.AspNet.SpaServices/project.json | 1 + .../MusicStore/Apis/AlbumsApiController.cs | 26 ++++------ .../MusicStore/Infrastructure/ApiResult.cs | 51 ------------------- .../components/admin/album-edit/album-edit.ts | 5 +- 5 files changed, 44 insertions(+), 69 deletions(-) create mode 100644 Microsoft.AspNet.SpaServices/ValidationErrorResult.cs delete mode 100644 samples/angular/MusicStore/Infrastructure/ApiResult.cs diff --git a/Microsoft.AspNet.SpaServices/ValidationErrorResult.cs b/Microsoft.AspNet.SpaServices/ValidationErrorResult.cs new file mode 100644 index 0000000..9cd0ba1 --- /dev/null +++ b/Microsoft.AspNet.SpaServices/ValidationErrorResult.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNet.Mvc; +using Microsoft.AspNet.Mvc.ModelBinding; + +namespace Microsoft.AspNet.SpaServices +{ + public class ValidationErrorResult : ObjectResult { + public const int DefaultStatusCode = 400; + + public ValidationErrorResult(ModelStateDictionary modelState, int errorStatusCode = DefaultStatusCode) + : base(CreateResultObject(modelState)) + { + if (!modelState.IsValid) { + this.StatusCode = errorStatusCode; + } + } + + private static IDictionary> CreateResultObject(ModelStateDictionary modelState) + { + if (modelState.IsValid) { + return null; + } else { + return modelState + .Where(m => m.Value.Errors.Any()) + .ToDictionary(m => m.Key, m => m.Value.Errors.Select(me => me.ErrorMessage)); + } + } + } +} diff --git a/Microsoft.AspNet.SpaServices/project.json b/Microsoft.AspNet.SpaServices/project.json index 19c848c..4813c74 100644 --- a/Microsoft.AspNet.SpaServices/project.json +++ b/Microsoft.AspNet.SpaServices/project.json @@ -10,6 +10,7 @@ "projectUrl": "", "licenseUrl": "", "dependencies": { + "Microsoft.AspNet.Mvc": "6.0.0-rc1-*", "Microsoft.AspNet.Routing": "1.0.0-rc1-*" }, "frameworks": { diff --git a/samples/angular/MusicStore/Apis/AlbumsApiController.cs b/samples/angular/MusicStore/Apis/AlbumsApiController.cs index dbd9459..3b57e0b 100644 --- a/samples/angular/MusicStore/Apis/AlbumsApiController.cs +++ b/samples/angular/MusicStore/Apis/AlbumsApiController.cs @@ -6,6 +6,7 @@ using Microsoft.Data.Entity; using AutoMapper; using MusicStore.Models; using MusicStore.Infrastructure; +using Microsoft.AspNet.SpaServices; namespace MusicStore.Apis { @@ -95,7 +96,7 @@ namespace MusicStore.Apis if (!ModelState.IsValid) { // Return the model errors - return new ApiResult(ModelState); + return new ValidationErrorResult(ModelState); } // Save the changes to the DB @@ -105,11 +106,10 @@ namespace MusicStore.Apis // TODO: Handle missing record, key violations, concurrency issues, etc. - return new ApiResult - { + return new ObjectResult(new { Data = dbAlbum.AlbumId, Message = "Album created successfully." - }; + }); } [HttpPut("{albumId:int}/update")] @@ -118,18 +118,16 @@ namespace MusicStore.Apis if (!ModelState.IsValid) { // Return the model errors - return new ApiResult(ModelState); + return new ValidationErrorResult(ModelState); } var dbAlbum = await _storeContext.Albums.SingleOrDefaultAsync(a => a.AlbumId == albumId); if (dbAlbum == null) { - return new ApiResult - { - StatusCode = 404, + return new ObjectResult(new { Message = string.Format("The album with ID {0} was not found.", albumId) - }; + }) { StatusCode = 404 }; } // Save the changes to the DB @@ -138,10 +136,9 @@ namespace MusicStore.Apis // TODO: Handle missing record, key violations, concurrency issues, etc. - return new ApiResult - { + return new ObjectResult (new { Message = "Album updated successfully." - }; + }); } [HttpDelete("{albumId:int}")] @@ -161,10 +158,9 @@ namespace MusicStore.Apis // TODO: Handle missing record, key violations, concurrency issues, etc. } - return new ApiResult - { + return new ObjectResult (new { Message = "Album deleted successfully." - }; + }); } } diff --git a/samples/angular/MusicStore/Infrastructure/ApiResult.cs b/samples/angular/MusicStore/Infrastructure/ApiResult.cs deleted file mode 100644 index 7adac59..0000000 --- a/samples/angular/MusicStore/Infrastructure/ApiResult.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Microsoft.AspNet.Mvc; -using Microsoft.AspNet.Mvc.ModelBinding; -using Newtonsoft.Json; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace MusicStore.Infrastructure -{ - public class ApiResult : ActionResult - { - public ApiResult(ModelStateDictionary modelState) - : this() - { - if (modelState.Any(m => m.Value.Errors.Any())) - { - StatusCode = 400; - Message = "The model submitted was invalid. Please correct the specified errors and try again."; - ModelErrors = modelState - .Where(m => m.Value.Errors.Any()) - .ToDictionary(m => m.Key, m => m.Value.Errors.Select(me => me.ErrorMessage )); - } - } - - public ApiResult() - { - - } - - [JsonIgnore] - public int? StatusCode { get; set; } - - public string Message { get; set; } - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public object Data { get; set; } - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public IDictionary> ModelErrors { get; set; } - - public override Task ExecuteResultAsync(ActionContext context) - { - if (StatusCode.HasValue) - { - context.HttpContext.Response.StatusCode = StatusCode.Value; - } - - return new ObjectResult(this).ExecuteResultAsync(context); - } - } -} diff --git a/samples/angular/MusicStore/wwwroot/ng-app/components/admin/album-edit/album-edit.ts b/samples/angular/MusicStore/wwwroot/ng-app/components/admin/album-edit/album-edit.ts index 6119d9f..6aabf4a 100644 --- a/samples/angular/MusicStore/wwwroot/ng-app/components/admin/album-edit/album-edit.ts +++ b/samples/angular/MusicStore/wwwroot/ng-app/components/admin/album-edit/album-edit.ts @@ -71,7 +71,7 @@ export class AlbumEdit { if (response.status === 200) { this.changesSaved = true; } else { - var errors = ((response.json())).ModelErrors; + var errors = (response.json()); Object.keys(errors).forEach(key => { errors[key].forEach(errorMessage => { // TODO: There has to be a better API for this @@ -101,6 +101,5 @@ export class AlbumEdit { } interface ValidationResponse { - Message: string; - ModelErrors: { [key: string]: string[] }; + [propertyName: string]: string[]; }