Last active
January 3, 2016 18:19
-
-
Save lnickers2004/8501299 to your computer and use it in GitHub Desktop.
WebApi 2: Add DiaryEntriesController and implement Gets Diary Entries using IdentityService, Repository, ModelFactory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CountingKs.Data; | |
using CountingKs.Models; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Web.Http; | |
namespace CountingKs.Controllers | |
{ | |
//make base controller abstract so it cannot be instantiated | |
//all our controllers will derive from base controller to | |
//inherit common funtionality | |
public abstract class BaseApiController : ApiController | |
{ | |
private ModelFactory _modelFactory; | |
private ICountingKsRepository _repo; | |
public BaseApiController( ICountingKsRepository repo ) | |
{ | |
_repo = repo; | |
} | |
protected ICountingKsRepository TheRepository | |
{ | |
get | |
{ | |
return _repo; | |
} | |
} | |
//KEY POINT: we need to defer the creation of the model factory until | |
// it is needed. So we create a deferred property | |
//Note: this is basically a singleton pattern.. | |
//the factory will exist for the lifetime of the controller | |
protected ModelFactory TheModelFactory | |
{ | |
//remember, we're using factory pattern to copy database entities into DTO's that contain | |
//discoverable Hyperlinks for each resource returned to the user | |
get | |
{ | |
//the first get will cause the factory to be created | |
if(_modelFactory == null) | |
{ | |
//it should be late enough for the request to not be null | |
//the model factory will be crated as a result of a user request | |
//so we can create the model factory and pass it the request so we may | |
//use it and the Url helper to generate the requested resource's URI Hyperlinks for including | |
//in the DTO that we pass back to the user | |
_modelFactory = new ModelFactory(this.Request); | |
} | |
return _modelFactory; | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Web.Http; | |
using CountingKs.Data; | |
using CountingKs.Services; | |
using CountingKs.Models; | |
namespace CountingKs.Controllers | |
{ | |
public class DiaryEntriesController : BaseApiController | |
{ | |
private ICountingKsIdentityService _identityService; | |
public DiaryEntriesController(ICountingKsRepository repo,ICountingKsIdentityService identityService) | |
: base(repo) | |
{ | |
_identityService = identityService; | |
} | |
//return all the diary entries for the current user on the given date | |
public IEnumerable<DiaryEntryModel> Get(DateTime diaryId) | |
{ | |
var results = TheRepository.GetDiaryEntries(_identityService.CurrentUser, diaryId) | |
.ToList() | |
.Select(e => TheModelFactory.Create(e)); | |
//NOTE: if results = null we will return empty collection | |
return results; | |
} | |
//return the specific diary entry for the current user by diary entry id | |
public HttpResponseMessage Get(DateTime diaryId, int id) | |
{ | |
var result = TheRepository.GetDiaryEntry(_identityService.CurrentUser,diaryId,id); | |
if(result == null) | |
{ | |
return Request.CreateResponse(HttpStatusCode.NotFound); | |
} | |
else | |
{ | |
return Request.CreateResponse(HttpStatusCode.OK, TheModelFactory.Create(result)); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace CountingKs.Data.Entities | |
{ | |
public class DiaryEntry | |
{ | |
public int Id { get; set; } | |
public Food FoodItem { get; set; } | |
public Measure Measure { get; set; } | |
public double Quantity { get; set; } | |
public virtual Diary Diary { get; set; } | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace CountingKs.Models | |
{ | |
public class DiaryEntryModel | |
{ | |
public string Url { get; set; } | |
public string FoodDescription; | |
public string MeasureDescription; | |
public string MeasureUrl; | |
public double Quantity; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CountingKs.Data.Entities; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace CountingKs.Models | |
{ | |
public class DiaryModel | |
{ | |
public string Url { get; set; } | |
public DateTime CurrentDate; | |
public IEnumerable<DiaryEntryModel> Entries { get; set; } | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
using CountingKs.Data.Entities; | |
using System.Web.Http.Routing; | |
using System.Net.Http; | |
namespace CountingKs.Models | |
{ | |
//using a Model Factory, we have only one place to handling Mapping from | |
//Database entities to DTO's | |
public class ModelFactory | |
{ | |
private UrlHelper _urlHelper; | |
//LEN NOTE: THE REASON WE DID NOT USE AUTOMAPPER IS BECAUSE WE WANTED TO USE THE REQUEST | |
//AND THE URL HELPER TO AID US IN CREATING OUR HYPERLINKS | |
public ModelFactory( HttpRequestMessage request ) | |
{ | |
//Remember to use the Url helper for WebAPI | |
//which is in System.Web.Http.Routing | |
_urlHelper = new UrlHelper(request); //this will help us to build | |
//the URLs for developer API discovery | |
} | |
public FoodModel Create( Food food ) | |
{ | |
return new FoodModel() | |
{ | |
//get an url for the Food roud and supply the id of the food that we're returning | |
Url = _urlHelper.Link("Food", new { foodid = food.Id }), | |
Description = food.Description, | |
Measures = food.Measures.Select(m => Create(m)) | |
}; | |
} | |
public MeasureModel Create( Measure measure ) | |
{ | |
return new MeasureModel() | |
{ | |
Url = _urlHelper.Link("Measures", new { foodid = measure.Food.Id, id = measure.Id }), | |
Description = measure.Description, | |
Calories = Math.Round(measure.Calories) | |
}; | |
} | |
public DiaryModel Create( Diary d ) | |
{ | |
return new DiaryModel() | |
{ | |
//NOTE: IMPORTANT, we are not using the Id property for the diary ID | |
//we are using the created date, or current date. There will be one diary per day per user. | |
//We need to insure that only one diary exists per user for any given date!!! We will do that | |
//elsewhere. We will assume that the database has unique constraint set on this field also | |
Url = _urlHelper.Link("Diaries", new { diaryid = d.CurrentDate.ToString("yyyy-MM-dd") }), | |
CurrentDate = d.CurrentDate, | |
Entries = d.Entries | |
.ToList() | |
.Select(e => Create(e)) | |
}; | |
} | |
public DiaryEntryModel Create( DiaryEntry e ) | |
{ | |
return new DiaryEntryModel() | |
{ | |
Url = _urlHelper.Link("DiaryEntries", new { diaryid = e.Diary.CurrentDate.ToString("yyyy-MM-dd"), id=e.Id }), | |
FoodDescription = e.FoodItem.Description, | |
MeasureDescription = e.Measure.Description, | |
MeasureUrl = _urlHelper.Link("Measures", new { foodid = e.Measure.Food.Id, id = e.Measure.Id }), | |
Quantity= e.Quantity | |
}; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net.Http.Formatting; | |
using System.Web.Http; | |
using Newtonsoft.Json.Serialization; | |
namespace CountingKs | |
{ | |
public static class WebApiConfig | |
{ | |
public static void Register( HttpConfiguration config ) | |
{ | |
config.Routes.MapHttpRoute( | |
name: "Food", | |
//routeTemplate: "api/foods/{foodid}", | |
routeTemplate: "api/v1/nutrition/foods/{foodid}", | |
defaults: new { controller = "foods", foodid = RouteParameter.Optional } | |
); | |
config.Routes.MapHttpRoute( | |
name: "Measures", | |
routeTemplate: "api/v1/nutrition/foods/{foodid}/measures/{id}", | |
defaults: new { controller = "measures", id = RouteParameter.Optional } | |
); | |
config.Routes.MapHttpRoute( | |
name: "FoodOrig", | |
routeTemplate: "api/nutrition/foodsOrig/{foodid}", | |
defaults: new { controller = "foodsOrig", foodid = RouteParameter.Optional } | |
); | |
//setting up a route to return diaries for the current logged in user | |
//LEN Note: we will secure the api and use that info to get the logged user | |
//we did not have to pass the user's id since we're dealing with logger in user | |
config.Routes.MapHttpRoute( | |
name: "Diaries", | |
routeTemplate: "api/user/diaries/{diaryid}", | |
defaults: new { controller = "diaries", diaryid = RouteParameter.Optional } | |
); | |
config.Routes.MapHttpRoute( | |
name: "DiaryEntries", | |
routeTemplate: "api/user/diaries/{diaryid}/entries/{id}", | |
defaults: new { controller = "diaryentries", id = RouteParameter.Optional } | |
); | |
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type. | |
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries. | |
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712. | |
//LEN NOTE: | |
//config.EnableQuerySupport();//optional support to expose an iqueryable endpoint for | |
//ODATA feeds for line of business that is Microsoft centric | |
//so we don't do this we don't support querying over the wire | |
//we will instead build a standard restful api that returns | |
//standard json or xml | |
//add camel casing | |
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); | |
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment