Skip to content

Commit

Permalink
Adding ImageCaption CSharp sample
Browse files Browse the repository at this point in the history
  • Loading branch information
kgrashad committed Sep 28, 2016
1 parent 517d0bb commit 7d8bd0d
Show file tree
Hide file tree
Showing 18 changed files with 841 additions and 0 deletions.
33 changes: 33 additions & 0 deletions CSharp/ImageCaption/App_Start/WebApiConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace ImageCaption
{
using System.Web.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Json settings
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
};

// Web API configuration and services

// Web API routes
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
}
}
}
126 changes: 126 additions & 0 deletions CSharp/ImageCaption/Controllers/MessagesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
namespace ImageCaption.Controllers
{
using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Connector;
using Services;

[BotAuthentication]
public class MessagesController : ApiController
{
private readonly ICaptionService captionService = new MicrosoftCognitiveCaptionService();

/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
string message;

try
{
message = await this.GetCaptionAsync(activity);
}
catch (ArgumentException e)
{
message = "Did you upload an image? I'm more of a visual person. " +
"Try sending me an image or an image URL";

Trace.TraceError(e.ToString());
}
catch (Exception e)
{
message = "Oops! Something went wrong. Try again later.";

Trace.TraceError(e.ToString());
}

Activity reply = activity.CreateReply(message);
await connector.Conversations.ReplyToActivityAsync(reply);
}
else
{
await this.HandleSystemMessage(activity);
}

var response = this.Request.CreateResponse(HttpStatusCode.OK);
return response;
}

/// <summary>
/// Gets the caption asynchronously by checking the type of the image (stream vs URL)
/// and calling the appropriate caption service method.
/// </summary>
/// <param name="activity">The activity.</param>
/// <returns>The caption if found</returns>
/// <exception cref="ArgumentException">The activity doesn't contain a valid image attachment or an image URL.</exception>
private async Task<string> GetCaptionAsync(Activity activity)
{

var imageAttachment = activity.Attachments?.FirstOrDefault(a => a.ContentType.Contains("image"));
if (imageAttachment != null)
{
var req = WebRequest.Create(imageAttachment.ContentUrl);

using (var stream = req.GetResponse().GetResponseStream())
{
return await this.captionService.GetCaptionAsync(stream);
}
}
else if (Uri.IsWellFormedUriString(activity.Text, UriKind.Absolute))
{
return await this.captionService.GetCaptionAsync(activity.Text);
}

// If we reach here then the activity is neither an image attachment nor an image URL.
throw new ArgumentException("The activity doesn't contain a valid image attachment or an image URL.");
}
/// <summary>
/// Handles the system activity.
/// </summary>
/// <param name="activity">The activity.</param>
/// <returns>Activity</returns>
private async Task<Activity> HandleSystemMessage(Activity activity)
{
switch (activity.Type)
{
case ActivityTypes.DeleteUserData:
// Implement user deletion here
// If we handle user deletion, return a real message
break;
case ActivityTypes.ConversationUpdate:
// Greet the user the first time the bot is added to a conversation.
if (activity.MembersAdded.Any(m => m.Id == activity.Recipient.Id))
{
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));

var response = activity.CreateReply();
response.Text = "Hi! I am ImageCaption Bot. I can understand the content of any image" +
" and try to describe it as well as any human. Try sending me an image or an image URL.";

await connector.Conversations.ReplyToActivityAsync(response);
}
break;
case ActivityTypes.ContactRelationUpdate:
// Handle add/remove from contact lists
break;
case ActivityTypes.Typing:
// Handle knowing that the user is typing
break;
case ActivityTypes.Ping:
break;
}

return null;
}
}
}
1 change: 1 addition & 0 deletions CSharp/ImageCaption/Global.asax
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%@ Application Codebehind="Global.asax.cs" Inherits="ImageCaption.WebApiApplication" Language="C#" %>
12 changes: 12 additions & 0 deletions CSharp/ImageCaption/Global.asax.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace ImageCaption
{
using System.Web.Http;

public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
181 changes: 181 additions & 0 deletions CSharp/ImageCaption/ImageCaption.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ImageCaption</RootNamespace>
<AssemblyName>ImageCaption</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Chronic, Version=0.3.2.0, Culture=neutral, PublicKeyToken=3bd1f1ef638b0d3c, processorArchitecture=MSIL">
<HintPath>packages\Chronic.Signed.0.3.2\lib\net40\Chronic.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Bot.Builder, Version=3.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Bot.Builder.3.2.1\lib\net46\Microsoft.Bot.Builder.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Bot.Connector, Version=3.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Bot.Builder.3.2.1\lib\net46\Microsoft.Bot.Connector.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.IdentityModel.Protocol.Extensions, Version=1.0.2.33, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.IdentityModel.Protocol.Extensions.1.0.2.206221351\lib\net45\Microsoft.IdentityModel.Protocol.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ProjectOxford.Vision, Version=1.0.370.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.ProjectOxford.Vision.1.0.370\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Microsoft.ProjectOxford.Vision.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Rest.ClientRuntime.2.3.2\lib\net45\Microsoft.Rest.ClientRuntime.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.WindowsAzure.ConfigurationManager.3.2.1\lib\net40\Microsoft.WindowsAzure.Configuration.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=4.0.20622.1351, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\System.IdentityModel.Tokens.Jwt.4.0.2.206221351\lib\net45\System.IdentityModel.Tokens.Jwt.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Content Include="default.htm" />
<Content Include="Global.asax" />
<Content Include="Images\bread-on-board.jpg" />
<Content Include="Images\outcome-emulator-stream.png" />
<Content Include="Images\outcome-emulator-url.png" />
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Compile Include="App_Start\WebApiConfig.cs" />
<Compile Include="Controllers\MessagesController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\ICaptionService.cs" />
<Compile Include="Services\MicrosoftCognitiveCaptionService.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config" />
<Content Include="README.md" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Content Include="azuredeploy.json" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<PropertyGroup>
<EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>3979</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:3979/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
22 changes: 22 additions & 0 deletions CSharp/ImageCaption/ImageCaption.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageCaption", "ImageCaption.csproj", "{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Binary file added CSharp/ImageCaption/Images/bread-on-board.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7d8bd0d

Please sign in to comment.