Tips and Tricks in a world of Mix

Archive for the ‘SPA’ Category

Image

Getting images byte[] from MS SQLServer through WCF to Ionic3 Angular4

So , that was quite a challenge.

After saving the images as byte[] pretty neat through the MVC client into the MS SqlServer , I wanted to get them into the app of Ionic3 with Angular4 ..

 

The problem was –

Well there were several problems –

  1. How to return the data through the http without loosing data in “translation” on the way ?

Solution is in C# WCF before returning it convert to base64 – it will send the data intact through the www traffic.

dto.Logo = Convert.ToBase64String(dal.Logo);

       2.   When we get the data – we need to translate it into the image again :

this post helped me –  Search for the comment with 400 upvotes!

So, in my ts client side – my Ionic3 Angular4 baby ,  I added a function translating the byte[] into a Blob.

Blob object represents a file-like object of immutable, raw data. Blobs represent data that isn’t necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user’s system.

b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || ”;
sliceSize = sliceSize || 512;

let byteCharacters = atob(b64Data);
let byteArrays = [];

for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
let slice = byteCharacters.slice(offset, offset + sliceSize);

let byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}

let byteArray = new Uint8Array(byteNumbers);

byteArrays.push(byteArray);
}

let blob = new Blob(byteArrays, {type: contentType});
return blob;
}

3. Now I started getting those messages from Chrome 

unsafe:blob:http://localhost:8100/55df97ad-0b55-4724-8a4f-83861b87e60a:1 GET unsafe:blob:http://localhost:8100/55df97ad-0b55-4724-8a4f-83861b87e60a net::ERR_UNKNOWN_URL_SCHEME

 

So I’ve built a pipe as suggested here  in compbination with the DomSanitation suggested here :

So at last I have taken this solution :

import { Pipe } from ‘@angular/core’;

import { Pipe } from ‘@angular/core’;

import { DomSanitizer, SafeHtml, SafeStyle, SafeScript, SafeUrl, SafeResourceUrl } from ‘@angular/platform-browser’;
@Pipe({ name: ‘safe’})

export class SafePipe {
constructor(protected _sanitizer: DomSanitizer) {
}
public transform(value: string, type: string = ‘html’): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {

switch (type) {

case ‘html’: return this._sanitizer.bypassSecurityTrustHtml(value);

case ‘style’: return this._sanitizer.bypassSecurityTrustStyle(value);

case ‘script’: return this._sanitizer.bypassSecurityTrustScript(value);

case ‘url’: return this._sanitizer.bypassSecurityTrustUrl(value);

case ‘resourceUrl’:

return this._sanitizer.bypassSecurityTrustResourceUrl(value);

default: throw new Error(`Invalid safe type specified: ${type}`);

}

}
}

 

Added it to declarations in your app.module.ts with class name SafePipe .
And added the pipe on the html template
<img [src]=”company.LogoImage | safe: ‘resourceUrl'”>
And here I am – after two days without sleep I have images from the server side in my app..
   WiseAppSettings.JPG
Now it’s just about vise-versa – trying to upload those slippery brothers  🙂
Advertisements

AngularJS Fundamentals in 60-ish Minutes

Lecture Summary

http://weblogs.asp.net/dwahlin/archive/2013/04/12/video-tutorial-angularjs-fundamentals-in-60-ish-minutes.aspx

Dan Wahlin

@danwahlin

http://weblogs.asp.net/dwahlin 

 

Demos :

http://tinyurl.com/angularjsdemos

 

http://angularjs.org/

 

image

 

   With the spa the content is loaded from begging and then only refreshes itself with data on the fly by the demand of the user.

   Spa by yourself is hard to connect all the components

image

 

but it’s built in Angular.js rather than using different libraries.

In the Angular framework we have :

image

 

Angularjs – directives , filters and data binding

 

ng-app – directive  <html ng-app>  ( better to write data-ng-app=”” – it’ll be accepted better)

ng-model – <input type=”text” ng-model=”name”>  {{ name }}

property is added to a scope , making an empty viewmodel and filling it with this  property .

{{ name }} – binded data of the model property will be shown on the page

 

<body data-ng-init=”myList=[‘one’, ‘two’]”> – just primitively initiates some list

<li data-ng-repeat=”instance in myList”> {{instance }}</li> loop through all myList

 

Filters

 

 

{{cust.name | uppercase}}

 

 

 

MVVM

 

image

 

 

 

Controller serves the View without knowing anything about the view.

 

image

 

 

 

ng-controller =”SimpleController” connects us.

$scope sent in is the one that carries the data inside.

 

tip- to be explicit with the names of vars and funcs

 

 

 

 

Each Module has some config to define its route.

Routing

            we’ll define view and controller for each route

Factory – will crud data  , not to place in controller  – services , providers , values , resources – access to data

Directives/filters will be placed in View

 

image

 

 

maybe views are divided by device – mobile or desktop

Module is an object container that can hold of : <html ng-app=”moduleName”>

 

image

 

var demoApp = angular.module(‘demoApp’,[]);

(tips – also through angular can get jqLite functionality , jquery Dom manipulation )

Dependency Injection – your module can rely other module to get some data

 

image

 

It’s like a require.js – it’s automatically include the needed modules .

 

Controller in AngularJs = ViewModel

So you can connect your module to a controller and wirte the name of the module in the view

with the ng-app tag naming the module .

You can initialize controller with anonymous function

 

image

 

or you can send an initiated controller

image

 

or you can create a namespace for all controllers , send it in , and the ng-controller attribute will find it in the list of other controllers by the name (this is good way for prototyping) :

 

image

 

 

after that you should put the connection to the controller into the html with a data-ng-controller=”SimpleController” attribute.

 

Routes

 

/view1

/view2

angular only loads the peaces we want by hash

doesn’t reload the whole shell

script template in the shell set / or partials on server

 

 

demoApp.config(function($routeProvider){

               $routeProvider

root:                         .when(‘/’ , ..  {controller: .. , templateUrl:View1.html})

                                 .when (‘partial2’ …

                               

 

templateUrl – it is better to set a folder for templates

 

image

it also handles the history and navigation accordingly

 

 

 

Reuse – Incapsulating code

Get Customers in multiple controllers

Factory – creates object inside the factory and returns it

Service – standard function that uses “this” keyword to define the functions

Provider – $get function that returns the data

Value – getting simple config function. Like  version  and it’s value will be 1.4

 

*Defined Factory can be injected inside some controller -  provides:

               dependency injection

               centralized place for functionality

 

              

image

 

 

Getting data from server by ajax or web sockets

We’ll define the factory/ service/ provider in demoApp

demoApp.factory(‘simpleFactory, function($http){

});

 

we can inject the http angular ajax call request and to perform get , post , put , delete type of calls for restfull type of calls.

in factory you can define a function where you return the object  . that can happen by ajax requst where you shall return a promiss and work in async mode

 

in controller best practice is to init from zero

 

image

 

in controller you can see we’ve sent simpleFactory in .

Than by private function we init the data through the factory.

Custom Directive – animated-view – animation will be activated when you are in the enabled browser.

image

SPA 4–Camper Camper– Surfacing JSON Data with ASP.NET Web API Code – JOHN PAPA

You can check out the series of the posts on the subject

<—SPA 3– Data Models, Entity Framework, and Data Patterns

SPA 5– Code Camper – Web Optimization—>

image

 

image

 

image

image

image

 

Routing

 

image

 

 

image

 

image

image

   1:  

   2: routes.MapHttpRoute( 

   3:  name: 

   4:  ControllerAction, 

   5:  routeTemplate: 

   6:  "api/{controller}/{action}"

   7:  );

 

APIController GET

 

The ApiController offers you an automatic functionality matched to EF UoW structure playing nicely together ! You’’ll most likely create a base with UoW property that will be inherited in every controller .

You can add Json Viewer to Chrome for a better reading.

The Ioc is coming into play when the ICodeCamperUow initializes each controller constructor matched to concrete type of Model Entity.

 

 

We’ve seen the actual class – it sums up the repository interfaces of the whole system

so it will be only one Interface to pass through as a promiss to constructors

   1: public class CodeCamperUow : ICodeCamperUow, IDisposable

   2:   {

   3:       public CodeCamperUow(IRepositoryProvider repositoryProvider)

   4:       {

   5:           CreateDbContext();

   6:  

   7:           repositoryProvider.DbContext = DbContext;

   8:           RepositoryProvider = repositoryProvider;       

   9:       }

  10:  

  11:       // Code Camper repositories

  12:  

  13:       public IRepository<Room> Rooms { get { return GetStandardRepo<Room>(); } }

  14:       public IRepository<TimeSlot> TimeSlots { get { return GetStandardRepo<TimeSlot>(); } }

  15:       public IRepository<Track> Tracks { get { return GetStandardRepo<Track>(); } }

  16:       public ISessionsRepository Sessions { get { return GetRepo<ISessionsRepository>(); } }

  17:       public IPersonsRepository Persons { get { return GetRepo<IPersonsRepository>(); } }

  18:       public IAttendanceRepository Attendance { get { return GetRepo<IAttendanceRepository>(); } }

 

 

Pay attention that the special Repositories For Persons , Sessions and Atrtendace also entered the ICodeCamperUow.

 

Also we could have changed the Implementation to a mock implementation for debugging purposes if needed and we’re getting Disposable at the base.

 

Here we have three classes handling the connectivity and registration of the Model per Interfaces throughout the project.

   1: public class IocConfig

   2:    {

   3:        public static void RegisterIoc(HttpConfiguration config)

   4:        {

   5:            var kernel = new StandardKernel(); // Ninject IoC

   6:  

   7:            // These registrations are "per instance request".

   8:            // See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/

   9:  

  10:            kernel.Bind<RepositoryFactories>().To<RepositoryFactories>()

  11:                .InSingletonScope();

  12:  

  13:            kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>();

  14:            kernel.Bind<ICodeCamperUow>().To<CodeCamperUow>();

  15:  

  16:            // Tell WebApi how to use our Ninject IoC

  17:            config.DependencyResolver = new NinjectDependencyResolver(kernel);

  18:        }

  19:    }

 

 

Those two are standard development taken by John Papa from Microsoft Dev Team.

   1: public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver

   2:   {

   3:       private IKernel kernel;

   4:  

   5:       public NinjectDependencyResolver(IKernel kernel)

   6:           : base(kernel)

   7:       {

   8:           this.kernel = kernel;

   9:       }

  10:  

  11:       public IDependencyScope BeginScope()

  12:       {

  13:           return new NinjectDependencyScope(kernel.BeginBlock());

  14:       }

  15:   }

 
 
 
   1: public class NinjectDependencyScope : IDependencyScope

   2:     {

   3:         private IResolutionRoot resolver;

   4:  

   5:         internal NinjectDependencyScope(IResolutionRoot resolver)

   6:         {

   7:             Contract.Assert(resolver != null);

   8:  

   9:             this.resolver = resolver;

  10:         }

  11:  

  12:         public void Dispose()

  13:         {

  14:             var disposable = resolver as IDisposable;

  15:             if (disposable != null)

  16:                 disposable.Dispose();

  17:  

  18:             resolver = null;

  19:         }

  20:  

  21:         public object GetService(Type serviceType)

  22:         {

  23:             if (resolver == null)

  24:                 throw new ObjectDisposedException("this", "This scope has already been disposed");

  25:  

  26:             return resolver.TryGet(serviceType);

  27:         }

  28:  

  29:         public IEnumerable<object> GetServices(Type serviceType)

  30:         {

  31:             if (resolver == null)

  32:                 throw new ObjectDisposedException("this", "This scope has already been disposed");

  33:  

  34:             return resolver.GetAll(serviceType);

  35:         }

  36:     }

 

LookupsController –

   1: [ActionName("tracks")]

   2:        public IEnumerable<Track> GetTracks()

You are renaming the functions names to something shorter and easier

 

You can add the right route for it –

image

the trouble is that

   1: routes.MapHttpRoute(

   2:                name: ControllerAndId,

   3:                routeTemplate: "api/{controller}/{id}",

   4:               defaults: new { id = RouteParameter.Optional } 

   5:               

   6:            );

matches any parameter.

 

the most basic route – like call for speakers

   1: // This controller-per-type route is ideal for GetAll calls.

   2:            // It finds the method on the controller using WebAPI conventions

   3:            // The template has no parameters.

   4:            //

   5:            // ex: api/sessionbriefs

   6:            // ex: api/sessions

   7:            // ex: api/persons

   8:            routes.MapHttpRoute(

   9:                name: ControllerOnly,

  10:                routeTemplate: "api/{controller}"

  11:            );

 

we’ll change the original one to match only the digits and another route to match actions specifically , digits parameter only by regex

   1: //  ex: api/sessions/1

   2:           //  ex: api/persons/1

   3:           routes.MapHttpRoute(

   4:               name: ControllerAndId,

   5:               routeTemplate: "api/{controller}/{id}",

   6:               defaults: null, //defaults: new { id = RouteParameter.Optional } //,

   7:               constraints: new { id = @"^\d+$" } // id must be all digits

   8:           );

 

and the last will work with action names that we’ve defined.

   1: // This RPC style route is great for lookups and custom calls

   2:            // It matches the {action} to a method on the controller 

   3:            //

   4:            // ex: api/lookups/all

   5:            // ex: api/lookups/rooms

   6:            routes.MapHttpRoute(

   7:                name: ControllerAction,

   8:                routeTemplate: "api/{controller}/{action}"

   9:            );

 

Attention – John papa has closed the default route of MVC all together.

 

APIController  PUT

image

We can test our put method by fiddler

In fiddler you get the JSON from the Get Method 

http://localhost:52692/api/persons/3

, that in Composer change to the right URI and change the method to PUT 

http://localhost:52692/api/persons

In Request Header we will add the type of the data we send

Content-Type:application/json; charset=utf-8

In the Request Body I’ve just changed Papa to PAPA

 

image

 

When Executed we can see that the data has changed

image

204 code – co content returned as we defined

And the Data changed as I put it in..

 

 

Testing WebAPI Requests with Qunit 

image

 

Qunit – in NuGet it’s “ qunit for ASP.NET MVC

qunit gives you the opportunity to test the Web API , sending and receiving data from client .

It’s a specific testing per every scenario.

  QUnit.testSuites can run all of the tests together which can be very helpful.

 

Testing Model Validation and Other Customization

 

   1: public static class GlobalConfig

   2:     {

   3:         public static void CustomizeConfig(HttpConfiguration config)

   4:         {

   5:             // Remove Xml formatters. This means when we visit an endpoint from a browser,

   6:             // Instead of returning Xml, it will return Json.

   7:             // More information from Dave Ward: http://jpapa.me/P4vdx6

   8:             config.Formatters.Remove(config.Formatters.XmlFormatter);

   9:  

  10:             // Configure json camelCasing per the following post: http://jpapa.me/NqC2HH

  11:             // Here we configure it to write JSON property names with camel casing

  12:             // without changing our server-side data model:

  13:             var json = config.Formatters.JsonFormatter;

  14:             json.SerializerSettings.ContractResolver =

  15:                 new CamelCasePropertyNamesContractResolver();

  16:  

  17:             // Add model validation, globally

  18:             config.Filters.Add(new ValidationActionFilter());

  19:         }

  20:     }

 

json.SerializerSettings.ContractResolver =

    new CamelCasePropertyNamesContractResolver();

will allow to translate the Camel case between server and client so that at client the Upper case won’t be needed.

 

config.Formatters.Remove(config.Formatters.XmlFormatter);

will allow JSON format response.

 

   1: public class ValidationActionFilter : ActionFilterAttribute 

   2:   { 

   3:       public override void OnActionExecuting(HttpActionContext context) 

   4:       { 

   5:           var modelState = context.ModelState; 

   6:           if (!modelState.IsValid) 

   7:           { 

   8:               var errors = new JObject(); 

   9:               foreach (var key in modelState.Keys) 

  10:               { 

  11:                   var state = modelState[key]; 

  12:                   if (state.Errors.Any()) 

  13:                   { 

  14:                       errors[key] = state.Errors.First().ErrorMessage; 

  15:                   } 

  16:               } 

  17:  

  18:               context.Response = context.Request.CreateResponse<JObject>(HttpStatusCode.BadRequest, errors); 

  19:           } 

  20:       } 

  21:   }

  22: }

 

Summary

image

You can check out the series of the posts on the subject

<—SPA 3– Data Models, Entity Framework, and Data Patterns

SPA 5– Code Camper – Web Optimization—>

SPA 5– Code Camper – Web Optimization

 

You can check out the series of the posts on the subject

SPA 4–Camper Camper– Surfacing JSON Data with ASP.NET Web API Code – JOHN PAPA
SPA 6 – SPA Basics – Separating the Ravioli – Code Camper

image

Preload to prevent additional calls

Reloading on the client different sections of content while staying on the client

 

Best Practices

 

image

 

HTML5 BOILERPLATE

image

 

So the best practise for js reference is

image

  • leaving the HTTP HTTPS area empty to make it take the file from either of protocols
  • enter the version as a sub folder – the formation online as it located
  • add the local version of the file in case it’s not found(important to have that local file available , for the case) For instance jQuery cdn library .When downloaded HTML5 BoilerplateGet the index.html into VSSets different classes per type of browser
       1: <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->

       2: <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->

       3: <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->

       4: <!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->

     
    Reading chars as they are
       1: <meta charset="utf-8">

    Trying to set the right view for devices by their size of the screen.(responsive design)

       1: <meta name="viewport" content="width=device-width">

    css rendered before allmodernizr is the only reference to js we”ll put at the headadded the cdn automatically for us

       1: <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
       1:  

       2:     <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.0.min.js"><\/script>')

    </script>

    all the JavaScript  files added at the end to not hold the html rendering of the page

      Web Optimization

    image

      Must allow optimization in web.config
         1: <!--Toggle "compilation debug" to false to activate bundling/minification-->

         2:    <compilation debug="false" targetFramework="4.5" />

        Minify –  the scripts are getting smaller  , extra spaces remark and etc. are removed.
      Bundling        if you have 40 javascript files it also unreadable and hits 40 requests to get the code from server to client – do it once with bundle uniting all to one request and sets the chaous to order

    image

      So the bundles are starting from Global.asax with
         1: BundleConfig.RegisterBundles(BundleTable.Bundles);

    And defined at App_Start folder

       1: // Force optimization to be on or off, regardless of web.config setting

       2:            //BundleTable.EnableOptimizations = false;

       3:            bundles.UseCdn = false;

     

    ScriptBundle – without the version it makes it louse from the version

       1: // Modernizr goes separate since it loads first

       2:  bundles.Add(new 

       3:   ScriptBundle("~/bundles/modernizr") 

       4:    .Include("~/Scripts/lib/modernizr-{version}.js"));

    you can and should include all your scripts as one folder

       1: // All application JS files (except mocks)

       2: bundles.Add(new 

       3:   ScriptBundle("~/bundles/jsapplibs")

       4:    .IncludeDirectory("~/Scripts/app/", "*.js", searchSubdirectories: false));

     

    Style Bundle

       1: // 3rd Party CSS files

       2: bundles.Add(new 

       3: StyleBundle("~/Content/css").Include(

       4:  "~/Content/boilerplate-styles.css",

       5:  "~/Content/toastr.css",

       6:  "~/Content/toastr-responsive.css"));

     

    Regular Transform for LESS styling

       1: // Custom LESS files

       2:  bundles.Add(new Bundle("~/Content/Less", 

       3:            new LessTransform(),  

       4:            new CssMinify())

       5:           .Include("~/Content/styles.less"));

    LessTransform is the translation class from Less to Css .

       1: public class LessTransform : IBundleTransform

       2:  {

       3:  public void Process(BundleContext context, BundleResponse response)

       4:  {

       5:      response.Content = dotless.Core.Less.Parse(response.Content);

       6:       response.ContentType = "text/css"; 

       7:   }

       8: }

     

    Now we can see that the number of approaches are fewer and it’s all in bundles

     

    image

     

    image

    You can check out the series of the posts on the subject

    SPA 4–Camper Camper– Surfacing JSON Data with ASP.NET Web API Code – JOHN PAPA
    SPA 6 – SPA Basics – Separating the Ravioli – Code Camper

    SPA 3–JOHN PAPA– Data Models, Entity Framework, and Data Patterns of the Code Camper SPA

    You can check out the series of the posts on the subject

    <—SPA 2 Technologies&Patterns 

     SPA 4 Surfacing JSON Data with ASP.NET Web API—>

    Data Layer Technologies

    image

    • SQL Server CE
    • ORM                   Using Entity Framework Code First (version 5)

                      Data stored and save to its own context (DBContext)

    image

     

     

    Models are simple classes without any additional references.

     

    Creating a Model

    Data containers – define your data and vehicle for you data

    Domain objects

    POCO– plain old class(CLR) object

    Don’t have additional references – Independent and stand alone objects

    makes them ease to  pass around across domain –

    through the EF(fills the POCO up)  –> Repositories –> UoW –> WebAPI

     

    So we can define a SessionBrief object to contain a short minimum data to revive the program when fails and some more robust and full object to init the program fully after the primamry reviving. All that through inj=heritance

     

    image

     

    Model Diagram

     

    image

     

    You can set [Key] attribute for EF to understand the key property

     

    DBContext

    Defines relations between Models And Database

    Stores objects and changes in its context (in memory)

     

    Defines Sets of Data – DBSet<T>

    Configuring the DBContext –

        

    image

     

    Defining Conventions with the DBContext

     

    • One to Many connection

    Connecting unique Speaker to multiple sessions

    Doing it through list property on a persons POCO model.

    (in my opinion can be added to speaker class instead)

     

       1: public class SessionConfiguration : EntityTypeConfiguration<Session>

       2:   {

       3:       public SessionConfiguration()

       4:       {

       5:           // Session has 1 Speaker, Speaker has many Session records

       6:           HasRequired(s => s.Speaker)

       7:              .WithMany(p => p.SpeakerSessions)

       8:              .HasForeignKey(s => s.SpeakerId);

       9:       }

      10:   }

      11: }

     

    • A Many-to-Many example – Sessions to  Persons through Attendance

    There can be few persons attending few sessions – the key

     

       1: public class AttendanceConfiguration : EntityTypeConfiguration<Attendance>

       2:    {

       3:        public AttendanceConfiguration()

       4:        {

       5:            // Attendance has a composite key: SessionId and PersonId

       6:            HasKey(a => new { a.SessionId, a.PersonId });

       7:  

       8:            // Attendance has 1 Session, Sessions have many Attendance records

       9:            HasRequired(a => a.Session)

      10:                .WithMany(s => s.AttendanceList)

      11:                .HasForeignKey(a => a.SessionId)

      12:                .WillCascadeOnDelete(false);

      13:  

      14:            // Attendance has 1 Person, Persons have many Attendance records

      15:            HasRequired(a => a.Person)

      16:                .WithMany(p => p.AttendanceList)

      17:                .HasForeignKey(a => a.PersonId)

      18:                .WillCascadeOnDelete(false);

      19:        }

      20:    }

      21:  

     

    the key is to have a connecting model between them two

       1: public class Attendance

       2:    {

       3:        public int PersonId { get; set; }

       4:        public Person Person { get; set; }

       5:        

       6:        public int SessionId { get; set; }

       7:        public Session Session { get; set; }

       8:  

       9:        /// <summary>Get and set the person's rating of the session from 1-5 (0=not rated).</summary>

      10:        [Range(0,5)]

      11:        public int Rating { get; set; }

      12:  

      13:        /// <summary>Get and set the person's session evaluation text.</summary>

      14:        public string Text { get; set; }

      15:    }

    Here we can see that there are two properties of ID type – one for session and the second for person.

    So through the connection of attendance activity we are connecting multiple persons to multiple sessions.

     

    All that is connected in DBContext

     

    • Establish Seed Data – creating basic data if the db doesn’t exist (good for development and debugging on unattached environments) through SetInitializer of Database
    • Define conventions – plural/singular table names
    • Adding the configurations for Model Relationships as described before

     

       1: public class CodeCamperDbContext : DbContext

       2:    {

       3:        // ToDo: Move Initializer to Global.asax; don't want dependence on SampleData

       4:        static CodeCamperDbContext()

       5:        {

       6:            Database.SetInitializer(new CodeCamperDatabaseInitializer());

       7:        }

       8:  

       9:        public CodeCamperDbContext()

      10:            : base(nameOrConnectionString: "CodeCamper") { }

      11:  

      12:        protected override void OnModelCreating(DbModelBuilder modelBuilder)

      13:        {

      14:            // Use singular table names

      15:            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

      16:  

      17:            modelBuilder.Configurations.Add(new SessionConfiguration());

      18:            modelBuilder.Configurations.Add(new AttendanceConfiguration());

      19:        }

      20:  

      21:        public DbSet<Person> Persons { get; set; }

      22:        public DbSet<Session> Sessions { get; set; }

      23:        public DbSet<Attendance> Attendance { get; set; }

      24:  

      25:        // Lookup Lists

      26:        public DbSet<Room> Rooms { get; set; }

      27:        public DbSet<TimeSlot> TimeSlots { get; set; }

      28:        public DbSet<Track> Tracks { get; set; }

      29:    }

     

     

    Repository Pattern – Why?

    Maintenance  – Data access code is easy to find , debug an d change

    Code Reuse – brake down the functionality , concentrate the code

    Focused on getting and saving data

    Consistent API

    Single Responsibility Principle (SRP) pattern – have each of your classes to concentrate on one thing only

     

    Make a simple consistent API matched for any type

     

       1: public interface IRepository<T> where T : class

       2:    {

       3:        IQueryable<T> GetAll();

       4:        T GetById(int id);

       5:        void Add(T entity);

       6:        void Update(T entity);

       7:        void Delete(T entity);

       8:        void Delete(int id);

       9:    }

     

    EFRepository –

    • Generalizing a set of ordinary functionality for each model , so we shouldn’t write it specific for each of them.
    • It implements IRepository – It allows you to abstract the types in additional layer, even though it’s not a necessary. Allows to use LINQ queries.
    • And we’ll have additional Interfaces for each Model when it’ll be a specific functionality per Model, or a DTO arrangement that will rearrange and minify the amount of data that will be passed.
    • We also can inherit from EFRepository but override the functions to match the specific scenario for our Model.
    • The EFRepository encapsulates the DBContext   and exposes functionality to deal with it.
    • Interactions with DBContext  through the EF  abilities.

     

    Uow – Unit of Work –

     

    image

     

    Through the Factory Pattern it builds the wright repositories concluded by the given type.

       1: public class CodeCamperUow : ICodeCamperUow, IDisposable

       2: {

       3:     // Code Camper repositories

       4:     // You can add here your types easily

       5:     public IRepository<Room> Rooms { get { return GetStandardRepo<Room>(); } }

       6:  

       7:     /// Save pending changes to the database

       8:     public void Commit()

       9:     {

      10:         //System.Diagnostics.Debug.WriteLine("Committed");

      11:         DbContext.SaveChanges();

      12:     }

      13:  

      14: }

      15:  

      16:  

      17: //and you'll call the UoW from Controllers like this :

      18:  

      19:  

      20: public class LookupsController : ApiControllerBase

      21:  {

      22:      public LookupsController(ICodeCamperUow uow)

      23:      {

      24:          Uow = uow;

      25:      }

      26:  

      27:      // GET: api/lookups/rooms

      28:      [ActionName("rooms")]

      29:      public IEnumerable<Room> GetRooms()

      30:      {

      31:          return Uow.Rooms.GetAll().OrderBy(r => r.Name);

      32:      }

      33: ...

      34:  

      35: }

     

    So you can organize and rearrange the repositories inside the UoW and that’s the methods that will be called from the WebAPI layer .

     

    You can check out the series of the posts on the subject

    <—SPA 2 Technologies&Patterns 

     SPA 4 Surfacing JSON Data with ASP.NET Web API—>

    SPA 2–JOHN PAPA– Technologies and Patterns of the Code Camper SPA

    You can check out the series of the posts on the subject

    <—SPA 1.1. Getting Code Camper Started

    SPA 3– Data Models, Entity Framework, and Data Patterns –>

     

    Exploring the Solution Structure

    Data Project

    • Global Conventions at the configuration folder ( c# fluent EF definitions)
    • DBContext – in charge for basic CRUD functionality
    • Unit Of Work combining the Repositories and orchestrating it by the process flow as needed.

     

    image

     

    Model Project – will be returned to client as part of an AJAX request

     

    image

     

    Web Project  –image

    WebApi

    • routing issues connected to global.asax
    • Ninject IOC global configurations
    • bundle for js and css connectivity …and more

    image

     

    CSS/LESS

    LESSLESS extends CSS with dynamic behavior such as variables, mixins , operations and functions.LESS runs on both the server-side (with Node.js and Rhino) or client-side (modern browsers only).

     

    Opening the projects –

    At the course he’s talking about building it from scratch there he’ll  open MVC4 template with WebApi template because we are going to serve WebApi services which will serve JSON for us,  but we already have the project from my previous post  – Getting Code Camper Started.

    Now all we need is is to update the packages thought the NuGet Package Manager Console :

    View –> Other Windows –> Package Manager Console

    For instance write :

    Update-Package jQuery   

    It’ll uninstall the old version and install a new one.

    After half an hour I’ve discovered the option of just –

    Update-Package  which will update all of the packages in your project

     http://nuget.codeplex.com/wikipage?title=Updating%20All%20Packages

    now I had all my packages updated at once .

     

    I’ve resolved some bizarre issue with critical error on jQuery map and went on .

     

    Helpful Tools

    You can check out the series of the posts on the subject

    <—SPA 1.1. Getting Code Camper Started

    SPA 3– Data Models, Entity Framework, and Data Patterns –>

    SPA 1.1 – Getting Code Camper Started or Using NuGet without committing packages to source control – auto rebuild missing references

    In previous post I have started the SPA  course by John Papa .

    You can read my posts on the subject here

      <—SPA 1 – Getting Started                 SPA 2 – Technologies and Patterns –>

     

    Well before going on , I wanted to install the Getting CodeCamper project to fill from close .

     

    So I got the code from GitHub just by login and getting the zip file

    UPDATE: Pay attetion!

    https://github.com/nihique/CodeCamper  -  this is not a full project , don’t use it

    https://github.com/NicholasMurray/CodeCamper – this one seems to be good. download this one!

     

    Then opened it and got lost with all the missing references.

    The trouble was that there was all the needed packages configurations , but yet the NuGet didn’t know how to handle it automatically .

     

    image

     

     

    so the solution

    Enabling Package Restore During Build

    In Visual Studio, enable "Allow NuGet to download missing packages during build". This setting lives under Options -> Package Manager -> General.

    allow-package-restore-configuration

     

    Project Setup

    Let’s assume that you have a solution that is either already using NuGet, or planning to use it, and that you want to set up the no-commit workflow.

    Right click on the Solution node in Solution Explorer and select Enable NuGet Package Restore.

    Enable NuGet Package Restore Context Menu item

    and there it was – my CodeCamper was healthy again

     

    image

    …keeping playing

    You can read my posts on the subject here

      <—SPA 1 – Getting Started                    SPA 2 – Technologies and Patterns –>

    Tag Cloud

    %d bloggers like this: