OK, I’m a little late at getting to this but I have just posted the code for my recent talk: Creating Awesome Chat Bots with the Bot Framework and C#.

To all that attended, thanks for joining me. I had a lot of fun preparing and presenting.

The code is here: https://github.com/schwammy/bot-demo

Unfortunately, this isn’t the easiest sample to get running. I think the code serves as a good example of some great things you can do with bots. However, if you want to actually use it, there are several steps that need to be done in advance. I’ve copied the text below from the readme file. As I say in a lot of my presentations, each step is pretty easy. However, putting them all together, especially for the first time, can be tricky. There are lots of good articles and videos on the web already for getting started with Bot Framework (and LUIS and QnA). I suggest reading up a bit and then follow my very basic instructions to get the code sample running.

Contact me if you have any questions or issues. Have Fun!

Getting Started

Before using this code you need to get set up

  1. Follow the instructions in the Prerequisites section here: https://docs.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-quickstart
  2. Install the emulator. The link is on the same page as above in the section: “Test your bot”

  3. You will also need:

Resources Setup

  1. After you create a LUIS account, create a LUIS app. You can leave it blank if you want. TechBashBot.sln contains a file LuisModel.json that can be imported to get started quickly.

  2. After you create a QnA Maker account, create a QnA service. You can import the questionsn and answers from TechBashBot.sln using the QnAMaker.tsv file.
  3. After you create your Azure Account, create a Web App Bot. Just add a resource and search “bot”, then choose Web App Bot

App Configuration

Once all of your resources are set up, you need to configure the code:

  1. Update the web.config file with the MicrosoftAppId and MicrosoftAppPassword for your new Web App Bot

  2. Update LuisDialog.cs by setting the new LUIS model id and subscription key
  3. Update QnADialog.cs by setting the QnA Service subscription key and knowledgebase id

Not a lot has changed with LINQ over the years. But I still find that developers aren’t completely familiar with the differences with some of the methods. In this post I’ll show the differences between:

  • Single()
  • SingleOrDefault()
  • First()
  • FirstOrDefault()

Of course these methods are similar but there are times when using the wrong one could lead to big problems with your application. The obvious similarity between these methods is that they are meant to return a single item. This is quite different from methods like Where() which returns a collection of items.

Now let’s focus on the differences.

I have noticed that in most cases, developers tend to use First() as the go to method for returning a single item from a collection. In my opinion, this is a bad idea. I tend to use Single() more often but of course there are times when each is appropriate. Here’s why…

Let’s start with a data set to work from. Here are some members of two great bands:

	List<Person> list = new List<Person>();
	list.Add(new Person {Id = 1, FirstName = "John", LastName = "Lennon"});
	list.Add(new Person {Id = 2, FirstName = "Paul", LastName = "McCartney"});
	list.Add(new Person {Id = 3, FirstName = "George", LastName = "Harrison"});
	list.Add(new Person {Id = 4, FirstName = "Ringo", LastName = "Starr"});
	list.Add(new Person {Id = 5, FirstName = "Jimmy", LastName = "Page"});
	list.Add(new Person {Id = 6, FirstName = "Robert", LastName = "Plant"});
	list.Add(new Person {Id = 7, FirstName = "John", LastName = "Bohnam"});
	list.Add(new Person {Id = 8, FirstName = "John Paul", LastName = "Jones"});

Let’s assume that the Id field is unique.

First, the method Single()

If I want to select a user by Id, I could use Single()

Person x = people.Single(p => p.Id == 1);

That will return the Person object for John Lennon.

For Single, the big difference comes when things aren’t as I expect them to be. Consider the following examples.

Person x = people.Single(p => p.Id == 9);

In this case, there is no person with an Id of 9. So Single() will throw an exception: “Sequence contains no matching element”.

Here’s another scenario

Person x = people.Single(p => p.FirstName == "John");

This too will throw an exception. This time it is “Sequence contains more than one matching element”.

So which is the best to use? It really depend on the situation. Often when you are selecting an item by Id, it is because you already know the Id. And if you do, I think it is safe to expect that the object with that Id exists. So I use Single(). In this case, the exception will be thrown if the user doesn’t exist but maybe that is ok because exceptions are for when things go wrong and in this case, something must have gone wrong. I also showed using Single(p => p.FirstName == “John”). But why would I do that? What reason could I have for selecting a Single item by a field that is not unique? Was I just curious to know if we had any Johns in the system? Would I have been better off with Any(p => p.FirstName == “John”) that returns a boolean?

Another option is SingleOrDefault()

Person x = people.SingleOrDefault(p => p.Id == 1);

This too will return the object for John Lennon.

Person x = people.SingleOrDefault(p => p.Id == 9);

SingleOrDefault() is safer. This time instead of an exception, x will be Null. Of course, as the developer, only I can decide which is better (Single or SingleOrDefault). It really depends on what I expect to happen and what other code exists to deal with unexpected results.

Person x = people.SingleOrDefault(p => p.FirstName == "John");

And SingleOrDefault() will still throw an exception if there is more than one “John”: “Sequence contains more than one matching element”

Next, a look at First() and FirstOrDefault()

Often, First() will give similar results but I find it misleading and using First() where inappropriate may actually hide problems. Consider the following:

Person x = people.First(p => p.Id == 1);

This too returns the object John Lennon.

Seems like everything is fine. But what if our data was bad. What if somehow we had two people with Id 1. Before you say “that would never happen”, think about some of the systems that you have supported. What if there was a mistake in the data entry validation? What if there was a bad import. My point is, it could happen. So now, if we use First(), we will get the first item in the collection that has the matching Id. It seems to me like in this case, I’d rather have Single throw an exception for me!

Unlike Single(), First() will NOT throw an exception if there is more than one matching element. Consider this:

Person x = people.First(p => p.FirstName == "John");

You can’t just assume that the result is John Lennon. It could depend on your data source and how the data was entered. Also, if a statement also had an OrderBy()

Person x = people.OrderBy(o => o.LastName).First(p => p.FirstName == "John");

Now I’m getting John Bohnam.

Yes, there are definitely cases when this is OK. But most of the time, I’d bet it is not. Why would I ever want the First() John?

Person x = people.FirstOrDefault(p => p.FirstName == "John");

This would have the same result as above. I could get John Lennon or John Bohnam depending on other factors.

Person x = people.FirstOrDefault(p => p.FirstName == "Pete");

Here, I get Null again (no exception). Sorry Pete Best, you’re not in the list.

So which to use?

There are circumstances for all of these. It’s great that we have 4 options. The important part is that as the developer, you understand that these are different. Please just don’t fall back on First() and use it all the time. Think about which is right for the circumstances you have at the moment.

One last tip

These statements may work correctly but they are just wasting keystrokes. I always say “less is more” with code.

Person x = people.Where(p => p.Id == 1).Single();
Person x = people.Where(p => p.Id == 1).First();

Please don’t do that. It’s much simpler to just say:

Person x = people.Single(p => p.Id == 1);
Person x = people.First(p => p.Id == 1);

The Microsoft Bot Framework makes it pretty easy to get started creating Chat Bots. If you haven’t gotten started yet, I recommend checking out this site: Bot Framework.

For a recent Bot that I created, we had the need for the Bot to expand. What I mean is, I want my bot chat UI to start out collapsed like a search box but then expand once a user starts talking to my bot.

7F9021F8-69F8-40A0-A26B-8EEC0CD32A1B

 

There are lots of examples for getting started with the Bot Framework. For this post, I will assume you already know how to do that. Hopefully you already know how to hook up the Web Chat control to communicate with your bot – here are some details about that.

I’ll start with the client-side code for this feature

For this feature, we will utilize the Web Chat’s backchannel using the DirectLine connection to the Bot. Then we can respond to events sent to the Web Chat from the bot. Here is the JavaScript needed to do this.

First, create a connection to the Bot with DirectLine:

        var directLine = new BotChat.DirectLine({ secret: &quot;YOUR KEY GOES HERE&quot; })

Next, subscribe to the event. All I am doing is listening for the event named “init” and when it occurs, add a class “fullSize” to the HTML element that hosts the bot.

        directLine.activity$
            .filter(isInitEvent)
            .subscribe(changeSize);

        function isInitEvent(activity) {
            return activity.type === &quot;event&quot; &amp;&amp; activity.name === &quot;init&quot;;
        }

        function changeSize(activity) {
            console.log(&quot;here&quot;)
            var container = document.getElementById(&quot;bot-chat-container&quot;);
            container.classList.add(&quot;fullSize&quot;);
        }

Lastly, create the Web Chat:

        BotChat.App({
            botConnection: this.directLine,
            user: { id: &#39;user&#39; },
            bot: { id: &#39;bot&#39; },
        }, document.getElementById(&quot;bot-chat-container&quot;));

I’m just using a little CSS to hide and show the rest of the Web Chat UI. Feel free to enhance this part a little, it could be better. Hopefully you get the idea.

        #bot-chat-container {
            border: 1px solid #333;
            height: 50px;
        }

        #bot-chat-container.fullSize {
            height: 300px;
        }

        .wc-header {
            display: none;
        }

        .fullSize .wc-header {
            display: block;
        }

        .wc-console svg {
            fill: black;
            margin: 11px;
        }

        /* These styles are used to hide the upload button...*/

        .wc-console label {
            display: none;
        }

        .wc-console .wc-textbox {
            left: 10px;
        }

All that is left to show of the UI is this DIV. But this isn’t too exciting:

<div id="bot-chat-container" />

Here is the Server-Side Code

This whole thing is based on an event coming to the Web Chat UI from the Bot on the server. I’m using C# and it is pretty simple stuff. When you create a Bot, the MessagesController is stubbed out for you to handle various Activity Types. In this case, I am concerned with ActivityType.ConversationUpdate. Check to see if the a new member is added to the conversation and if so, send event named “init”.

private async Task&lt;Activity&gt; HandleSystemMessage(Activity message)
        {
            if (message.Type == ActivityTypes.DeleteUserData)
            {
		// ...
            }
            else if (message.Type == ActivityTypes.ConversationUpdate)
            {
                using (var scope = Microsoft.Bot.Builder.Dialogs.Internals.DialogModule.BeginLifetimeScope(Conversation.Container, message))
                {
                    var client = scope.Resolve&lt;IConnectorClient&gt;();
                    if (message.MembersAdded.Any())
                    {
                        foreach (var newMember in message.MembersAdded)
                        {
                            if (newMember.Id != message.Recipient.Id)
                            {
                                var reply = message.CreateReply();
                                reply.Type = ActivityTypes.Event;
                                reply.Name = &quot;init&quot;;
                                await client.Conversations.ReplyToActivityAsync(reply);

                            }
                        }
                    }
                }
            }
		// ... etc. etc.

That’s all.

What? You haven’t registered for the best developer conference in the Northeastern U.S. yet? Well don’t worry, there is still time. First, let me tell you why you need to attend.

Full disclosure: I am a founding board member of the TechBash Foundation. Myself and a few other people run this event for the community. We make no money from the event. All fees and revenue generated by TechBash are put directly into the event to cover costs.

OK, on to it…

What is TechBash?

TechBash is a 3 day developer conference. If you are interested in topics like .NET, Web, Cloud, JavaScript, DevOps, Architecture, Patterns, Mobile, Frameworks and more, you should be at TechBash.

Why should you be at TechBash 2017?

I’ll summarize and you can read on below for more details:

1. Content – TechBash has got great content. Want to learn about the latest frameworks and patterns from industry experts? We’ve got them. Want to hear directly from Microsoft employees and MVPs? We’ve got plenty of them. TechBash is bringing in the best speakers from top tech companies to deliver content to you. read more…

2. Location TechBash is organized by a small group of developers who were tired of traveling across the country for good content. So now they are bringing the content to you. TechBash is in the Poconos in Pennsylvania. That’s less than a 2 hour drive from NYC or Philly. Plus, the short drive time means you won’t need to ask your boss for two extra travel days. read more…

3. Price. Book now and you can register for TechBash plus 3 nights in the hotel for less than $1000. That’s a great price for a conference of this caliber. Plus, no airfare needed so TechBash fits into your budget!  After 9/8 hotel rates may vary. read more…

4. Venue  The Kalahari Resort. This is the largest indoor water park in the country. So while you are coming to learn and network with tech leaders from around the country and meet up with old friends and new, you can have a little fun and hit the water slides. read more…

5. Fun for the Family – Yes, it’s a huge water park. But there are a ton of other activities at the Kalahari Resort and nearby. Plus, Friday afternoon we have Sara Chipps hosting a Jewelbots build event for kids 8 and up. They can learn to code too. read more…

 

Plus, if you want to bring the whole team, contact us regarding group discounts: info@techbash.com

 

Great Content – Learn from the best

We’ve got great speakers from top tech firms around the country coming in to speak to you. And you may notice these are some of the same speakers that you’ll see at much more expensive conferences. Here are a just few of our featured speakers:

image

 

And if you are interested in content direct from Microsoft, we’ve got that too:

image

OK, here is a full list of our speakers. You can see our current schedule on our website.

Alon Fliess, Ambrose Little, Anne Bougie, Anoop Kumar, Ashley Grant, Bill Wolff, Cameron Presley, Chris Houdeshell, Damian Brady, Danny Brown, Dave Voyles, Donovan Brown, Eran Stiller, Erika Carlson, Gajan Pathmanathan, Jason van Brackel, Jeffrey Fritz, Jeremy Clark, Jim Wooley, Joseph Guadagno, Joshua Garverick, Ken Dale, Kevin Griffin, Lee Brandt, Nate Barbettini, Nick Landry, Ondrej Balas, Oren Novotny, Paul Hacker, Richard Taylor, Sam Basu, Sara Chipps, Scott Allen, Scott Kay, Stephanie Herr, Stephen Bohlen, Steve Michelotti

Location – If you are in the Northeast, we are close by

Just check out the map below. We are about 2 hours from NYC, NJ, and Philly. We are close by to Delaware, Central and Western PA, NY State, Maryland, DC and much more. The best part is that you don’t need to sit on long flights or ask the boss for extra travel days just to attend TechBash! Oh, and that means travel costs are lower too.

image

Price – The Price is Right!

TechBash fits your budget! An all access ticket to TechBash is only $349. That includes 3 days of content plus breakfast, lunch and coffee/snacks too. Compare that price to some other conferences and see what you think. Of course, you’ll need to stay over for a few nights. We’ve got great prices reserved at the Kalahari Resort (use group id 1145) and if you book quickly you can still get the conference registration and 3 nights in the hotel for under $1000. That is an incredible deal for the content we provide. If you need help convincing your boss, check this out.

Venue – The Kalahari Resort is AWESOME!

To start, The Kalahari is a first class conference center with plenty of Wi-Fi to go around! The place was brand new last year and this year they expanded to add another 500 hotel rooms. Plus, it is now the largest indoor waterpark in the country! So after you are done learning from the best, hit the slides and have some fun!

imageimageimageimageimageimageimageimage

Family Fun – There is plenty to do!

Bring the whole family to TechBash! The kids will love the waterpark but that isn’t all there is for families. This year TechBash is very proud to announce that Sara Chipps will be offering a hands-on event for kids ages 8 and up to learn to code and work with Jewelbots. Kids will learn entry level coding and Arduino. Plus there is face painting, crafts, and more! There is a $10 ticket required to cover costs for this. Check out all of the great stuff to do while at TechBash on our site. We’ve got a ton of ideas.

I hope I’ve shown you why TechBash is the best conference for you. Contact me via my blog if you have any questions.

Thanks,

Andy

If you find yourself stuck because you need to use EF 6 features in an ASP.NET Core web app with Identity, don’t worry, it is easy!

Like many of you, I am trying to get all caught up with ASP.NET Core. It has some great features and I’ve been looking forward to using it. I finally have a new project to start so Core was my first choice.To expand on that a bit, I am using ASP.NET Core with the full .NET Framework. At this point, I don’t need to use .NET Core in cross platform scenarios.

It wasn’t long after I got started that I ran into what I thought was a big problem.Spoiler Alert: It wasn’t a big problem at all!

A new project created for ASP.NET Core (configured to use Individual Accounts for security) will be all loaded up with Entity Framework Core as well as Controllers and Views and Code to make all the authentication stuff work. This post isn’t about that. It was all working nicely. That is, until I needed Entity Framework Spatial Types with SQL Server. My website needs to calculate distance between two points, something that is surprisingly easy with the right tools. However, EF Core doesn’t yet support that! I’d needed EF 6 instead. Now, this is where I made my big mistake. I assumed that I couldn’t have EF 6 and EF Core in the same project so I removed all of the EF Core stuff. I began to set up EF 6 instead and ran into issues wiring things up with ASP.NET Core. To set up all of the Dependency Injection stuff and wire up services, you need code like this:

services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();

But it turns out that AddEntityFrameworkStores doesn’t exist in EF 6. This got me going on all kinds of research, trial and error. All for nothing.

You see, I was going about this all wrong.

Thanks to some help from Julie Lerman (Entity Framework Guru and fellow Microsoft MVP) and Diego Vega (from the EF team at Microsoft), I found out that I could in fact run EF 6 and EF Core in the same project! All I needed to do (after getting all of the EF Core nuget packages all loaded up again) was create 2 DbContexts! One with EF Core for the Identity stuff. And one with EF6 for my application logic (so I can use the spatial features including DbGeography). At first, I had a some namespace confusion because there are classes with the same names in EF 6 and Core. But that was easily resolved.

It’s great when the solution is so simple.