Enterprise Framework

Software Solutions in the Enterprise

ASP.NET Core - Entity Framework - Code First Add-Migration - Unable to resolve service for type Microsoft.EntityFrameworkCore.Migrations.IMigrator.

Entity Framework Error:

Unable to resolve service for type 'Microsoft.EntityFrameworkCore.Migrations.IMigrator'. This is often because no database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.

Solution:

Verify the connectionstring in the appsettings.json file.

{
  "ConnectionStrings": {
    "CustomerDb":  "Server=(localdb)\\mssqllocaldb;Database=Customer;Trusted_Connection=True;"
  }
}
On Startup.cs, ConfigureService method, verify, you are correctly initializing the Context

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("CustomerDb")));

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }


How To: Unobtrusive Javascript - Manually Add Required Rule and Message.

How To: Unobtrusive Javascript - Manually Add/Remove Required Rule and Message.  

<script type="text/javascript">
$(function () {

var addRequired = function () {
// Manually add required fields to certain fields
$('#scheduledLockDate').rules('add', {
required: true,
messages: {
required: "The Scheduled Lock Date is required"
}
})
;
$('#scheduledDisposeDate').rules('add', {
required: true,
messages: {
required: "The Scheduled Dispose Date is required"
}
})
;
$('#issueDate').rules('add', {
required: true,
messages: {
required: "The Issue Date is required"
}
})
;
}

// This will remove the manually required fields
var removeRequired = function () {
// Manually remove required fields to certain controls
$('#scheduledLockDate').rules('remove', 'required');
$('#scheduledDisposeDate').rules('remove', 'required');
$('#issueDate').rules('remove', 'required');
}

// Handle the form submit method
$('#workspaceForm').submit(function (e) {
e.preventDefault();
var form = this;

// Trigger Form Validation
var isValid = $('#workspaceForm').valid();

if (!isValid) {
// Exit out
return false;
}

form.submit();
});

//Manually add the required fields
addRequired();

//Manually remvoe the required fields
removeRequired();
});
</script>
Reference:  https://jqueryvalidation.org/rules/

Add Google Maps and restrict to specific urls

Goto:  https://console.developers.google.com/apis/dashboard

Choose your domain from the top navigation dropdown

Then

Goto:  https://console.developers.google.com/apis/library

Choose your domain from the top navigation dropdown

Not all these API are required, I just added few more for helpfulness

Enable the following:

  • Maps Javascript API
  • Maps Embed API
  • Directions API
  • Places API
  • Geocoding API
  • Geolocation API

Choose Restrictions

Choose Referers

Enter the urls:

localhost/*
*.yourwebsite.com/*
yourwebsite.com/*
yourwebsite.azurewebsites.net/*

MANS Stack (Mac, ASP.NET MVC, .NET Core, SQL Server 2017) - Developing on a Microsoft Stack on a Mac

MANS Stack (Mac, ASP.NET MVC, .NET Core, SQL Server 2017)


Valid as of April 18, 2018

Let's install .NET SDK for Mac.

https://www.microsoft.com/net/learn/get-started/macos

Download Visual Studio for Mac

https://www.visualstudio.com/vs/mac/

Download Docker for Mac

https://www.docker.com/docker-mac

Download SQL Server 2017 Ubuntu Docker Image

https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker

NOTE:  After you pull the SQL Server 2017 Docker Image.  Run it and accept the EULA.  Exit the SQL Server 2017 Image and commit the image

$ docker ps

CONTAINER ID        IMAGE                                      COMMAN                  CREATED             STATUS              PORTS                    NAMES
cb31a41d1f1b        microsoft/mssql-server-linux:2017-latest   "/opt/mssql/bin/sqls…"   2 hours ago         Up 2 hours          0.0.0.0:1401->1433/tcp   sql1

$ docker commit cb31a41d1f1b microsoft/mssql-server-linux:2017-latest

Running the docker image without commiting will show the error:

$ docker run microsoft/mssql-server-linux:2017-latest

The SQL Server End-User License Agreement (EULA) must be accepted before SQL

Server can start. The license terms for this product can be downloaded from

http://go.microsoft.com/fwlink/?LinkId=746388.



You can accept the EULA by specifying the --accept-eula command line option,

setting the ACCEPT_EULA environment variable, or using the mssql-conf tool.

Connection String Example:

Server=127.0.0.1,1401;Database=AppDb;User Id=sa;Password=P@ssw0rd;

GraphQL - Dice Example without the GraphQL schema language:

GraphQL - Dice Example without the GraphQL schema language:

Using GraphQL schema language, you would use root and set it to the schema.



var express = require('express')
var graphqlHTTP = require('express-graphql')
var graphql = require('graphql')
const { GraphQLInt, GraphQLList, GraphQLObjectType, GraphQLString } = require('graphql')

class RandomDie {
  constructor (numSides) {
    this.numSides = numSides;
  }

  rollOnce () {
    return 1 + Math.floor(Math.random() * this.numSides);
  }

  roll ({numRolls}) {
    var output = [];
    for (var i = 0; i < numRolls; i++) {
      output.push(this.rollOnce())
    }
    return output
  }
}

// Define the Query type
var RandomDieType = new GraphQLObjectType({
  name: 'RandomDie',
  fields: {
    numSides: { type: GraphQLInt },
    rollOnce: { type: GraphQLInt },
    otherValue: { type: GraphQLString },
    roll: {
      type: new GraphQLList(graphql.GraphQLInt),
      args: {
        numRolls: { type: graphql.GraphQLInt }
      },
      resolve: function (_, {numRolls}, context) {
        // "_" represents the parent node in this case "getDie Type".  
        // It's the result of this.fields bound to the parent nodes
        // resolve data.
        // _ = {
        //   numSides: numSides,
        //   rollOnce: randomDie.rollOnce(),
        //   randomDie: randomDie
        // }
        console.log(_)
        console.log(`hello ${_.otherValue}`)
        var randomDie = new RandomDie(6)
        return randomDie.roll({
          numRolls: numRolls
        })
      }
    }
  }
})

var getDie = new graphql.GraphQLObjectType({
  name: 'Query',
  fields: {
    getDie: {
      type: RandomDieType,
      args: {
        numSides: { type: graphql.GraphQLInt }
      },
      resolve: function (_, {numSides}, context) {
        var randomDie = new RandomDie(numSides || 6)
        // THIS INFORMATION WILL BE PASSED TO "type: RandomDieType" RESOLVE
        // WITH THE FIELDS SET TO _
        return {
          numSides: numSides,
          rollOnce: randomDie.rollOnce(),
          randomDie: randomDie
        }
      }
    }
  }
})

var schema = new graphql.GraphQLSchema(
  {
    query: getDie
  }
)

var app = express()
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true
}))
app.listen(4000)
console.log('Running a GraphQL API server at localhost:4000/graphql')

Request

{ getDie(numSides: 6) { numSides rollOnce roll(numRolls: 3) } }

Outputs

{ "data": { "getDie": { "numSides": 6, "rollOnce": 3, "roll": [ 1, 6, 3 ] } } }


Node JS - Standard JS -> Errors ('describe' is not defined, 'it' is not defined, 'jest' is not defined, 'expect' is not defined)

Running standard --fix on node shows errors ('describe' is not defined, 'it' is not defined, 'jest' is not defined, 'expect' is not defined)

$ standard --fix

standard: Use JavaScript Standard Style (https://standardjs.com)

  /test/getUser.test.js:7:1: 'jest' is not defined.

  /test/getUser.test.js:12:1: 'describe' is not defined.

  /test/getUser.test.js:13:3: 'it' is not defined.

  /test/getUser.test.js:15:5: 'expect' is not defined.

Add line to package.json
  "standard": {
    "env": [
      "jest"
    ]
  }


or add comment to the unit test file 

/* eslint-env mocha */

ElasticSearch - POST JSON to Remove hits .total, .max_score, ._index, ._type, _id, ._score

PROBLEM:  ElasticSearch - POST JSON to Remove hits .total, .max_score, ._index, ._type, _id, ._score

I have to be honest, this one really upset and frustrated me because I couldn't find an easy solution/answer using Google or ElasticSearch Documentation on how to only return back _source from a search POST json body.  When I finally figured it out, I think it wasn't implemented correctly. 

SOLUTION using QUERYSTRING:

First, off if you finally find in it in the ElasticSearch documentation, you can use the query string to remove extra metadata fields like _id, max_score, _index, _type, etc...  Correction, you can tell it which fields to include through a querystring:

GET /_search?q=elasticsearch&filter_path=took,hits.hits._id,hits.hits._score

reference:  https://www.elastic.co/guide/en/elasticsearch/reference/5.6/common-options.html

You can see from the example that you need to set the filter_path and pass in the fields you want returned back.

HOWEVER!!!!, if you are using the ElasticSearch-JS client for Node/browser, it doesn't really tell you how to do it in the API examples or in a POST json body example.

If this is documented, I sure as heck couldn't find it.

THE POST BODY SOLUTION

I'm going to tell you how to do it and there is a bug.

This is the normal client json request

            this.client.search({
                index: index,
                type: type,
                from: (page - 1) * pageSize,
                size: pageSize,
                body: body
            })

But what you can actually do it pass it filter_path in the search method options
            this.client.search({
                index: index,
                type: type,
                from: (page - 1) * pageSize,
                size: pageSize,
                body: body,
                filter_path: [
                    'hits.total,hits.max_score,hits.hits._id,hits.hits._score,hits.hits._source'                    
                ]
            })

But if you look at it, you're like, WTF? it's an array, however he's passing in a string delimited by comma(,)

Passing in the different values individually returns back weird results. For example, if i pass in

[ 'hits.total', 'hits.max_score' ]

On the results back, total will be undefined or max_score will be set.

By doing it all in a single string delimited by comma(,) it worked as expected. I should submit a bug but it's late, and i'm tired.

Hopefully, this helps somebody!!!