├── README.md ├── WpfApplication1.sln ├── WpfApplication1.v11.suo ├── WpfApplication1 ├── ApiController.cs ├── App.config ├── App.xaml ├── App.xaml.cs ├── ChatProxy.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Message.cs ├── MessageReceiver.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── WpfApplication1.csproj ├── bin │ └── Debug │ │ ├── System.Json.dll │ │ ├── System.Json.xml │ │ ├── System.Net.Http.Formatting.dll │ │ ├── System.Net.Http.Formatting.xml │ │ ├── System.Net.Http.WebRequest.dll │ │ ├── System.Net.Http.WebRequest.xml │ │ ├── System.Net.Http.dll │ │ ├── System.Net.Http.xml │ │ ├── System.Web.Http.Common.dll │ │ ├── System.Web.Http.Common.xml │ │ ├── System.Web.Http.SelfHost.dll │ │ ├── System.Web.Http.SelfHost.xml │ │ ├── System.Web.Http.dll │ │ ├── System.Web.Http.xml │ │ ├── WpfApplication1.exe │ │ ├── WpfApplication1.exe.config │ │ ├── WpfApplication1.pdb │ │ ├── WpfApplication1.vshost.exe │ │ └── WpfApplication1.vshost.exe.config ├── obj │ └── Debug │ │ ├── App.g.cs │ │ ├── App.g.i.cs │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── Filip.ChatGUI.Properties.Resources.resources │ │ ├── MainWindow.baml │ │ ├── MainWindow.g.cs │ │ ├── MainWindow.g.i.cs │ │ ├── TempPE │ │ └── Properties.Resources.Designer.cs.dll │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ ├── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ ├── WpfApplication1.csproj.FileListAbsolute.txt │ │ ├── WpfApplication1.csproj.GenerateResource.Cache │ │ ├── WpfApplication1.csprojResolveAssemblyReference.cache │ │ ├── WpfApplication1.exe │ │ ├── WpfApplication1.g.resources │ │ ├── WpfApplication1.pdb │ │ ├── WpfApplication1_MarkupCompile.cache │ │ └── WpfApplication1_MarkupCompile.i.cache └── packages.config └── packages ├── AspNetWebApi.Core.4.0.20126.16343 ├── AspNetWebApi.Core.4.0.20126.16343.nupkg └── lib │ └── net40 │ ├── System.Web.Http.dll │ └── System.Web.Http.xml ├── AspNetWebApi.SelfHost.4.0.20126.16343 ├── AspNetWebApi.SelfHost.4.0.20126.16343.nupkg └── lib │ └── net40 │ ├── System.Web.Http.SelfHost.dll │ └── System.Web.Http.SelfHost.xml ├── System.Json.4.0.20126.16343 ├── System.Json.4.0.20126.16343.nupkg └── lib │ └── net40 │ ├── System.Json.dll │ └── System.Json.xml ├── System.Net.Http.2.0.20126.16343 ├── System.Net.Http.2.0.20126.16343.nupkg └── lib │ └── net40 │ ├── System.Net.Http.WebRequest.dll │ ├── System.Net.Http.WebRequest.xml │ ├── System.Net.Http.dll │ └── System.Net.Http.xml ├── System.Net.Http.Formatting.4.0.20126.16343 ├── System.Net.Http.Formatting.4.0.20126.16343.nupkg └── lib │ └── net40 │ ├── System.Net.Http.Formatting.dll │ └── System.Net.Http.Formatting.xml ├── System.Web.Http.Common.4.0.20126.16343 ├── System.Web.Http.Common.4.0.20126.16343.nupkg └── lib │ └── net40 │ ├── System.Web.Http.Common.dll │ └── System.Web.Http.Common.xml └── repositories.config /README.md: -------------------------------------------------------------------------------- 1 | Build p2p chat application with WPF and ASP.NET Web API 2 | ========================= 3 | 4 | This source code is accompanying the tutorial from here - http://www.strathweb.com/2012/03/build-p2p-chat-application-with-wpf-and-asp-net-web-api/ 5 | 6 | Please note that the tutorial was written some time ago against ASP.NET Web API Beta, so it might not compile against the latest project DLLs (update coming soon). 7 | 8 | The solution file is Visual Studio 11. 9 | 10 | Enjoy. -------------------------------------------------------------------------------- /WpfApplication1.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 11 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfApplication1", "WpfApplication1\WpfApplication1.csproj", "{B24656A9-4F1A-4585-AB9D-3379FEA86134}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B24656A9-4F1A-4585-AB9D-3379FEA86134}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {B24656A9-4F1A-4585-AB9D-3379FEA86134}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {B24656A9-4F1A-4585-AB9D-3379FEA86134}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {B24656A9-4F1A-4585-AB9D-3379FEA86134}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /WpfApplication1.v11.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filipw/aspnetwebapi-wpf-p2p-chat/36409f0b94b213956dc63ba00c55d3c7684a0ae9/WpfApplication1.v11.suo -------------------------------------------------------------------------------- /WpfApplication1/ApiController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Web.Http.SelfHost; 7 | using System.Net.Http; 8 | using System.Net.Http.Formatting; 9 | using System.Web.Http; 10 | using Filip.ChatModels; 11 | 12 | namespace Filip.ChatBusiness 13 | { 14 | public class ChatController : ApiController 15 | { 16 | public void Post(MessageReceiver simpleMessage) 17 | { 18 | MessageArrived(new Message(simpleMessage)); 19 | } 20 | 21 | public delegate void EventHandler(object sender, MessageEventArgs args); 22 | public static event EventHandler ThrowMessageArrivedEvent = delegate { }; 23 | 24 | public void MessageArrived(Message m) 25 | { 26 | ThrowMessageArrivedEvent(this, new MessageEventArgs(m)); 27 | } 28 | } 29 | 30 | public class MessageEventArgs : EventArgs 31 | { 32 | public MessageEventArgs(Message m) 33 | { 34 | this.Message = m; 35 | } 36 | public Message Message; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WpfApplication1/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /WpfApplication1/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WpfApplication1/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Web.Http.SelfHost; 9 | using System.Net.Http; 10 | using System.Net.Http.Formatting; 11 | using System.Web.Http; 12 | using System.Threading.Tasks; 13 | 14 | namespace Filip.ChatGUI 15 | { 16 | /// 17 | /// Interaction logic for App.xaml 18 | /// 19 | public partial class App : Application 20 | { 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WpfApplication1/ChatProxy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Http; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Web.Http; 8 | using System.Web.Http.SelfHost; 9 | using System.Windows.Threading; 10 | using Filip.ChatModels; 11 | 12 | namespace Filip.ChatBusiness 13 | { 14 | public class ChatProxy 15 | { 16 | public bool Status { get; set; } 17 | 18 | public delegate void ShowReceivedMessage(Message m); 19 | public delegate void ShowStatus(string txt); 20 | 21 | private ShowReceivedMessage _srm; 22 | private ShowStatus _sst; 23 | private HttpClient _client; 24 | private HttpSelfHostServer _server; 25 | 26 | //constructor 27 | public ChatProxy(ShowReceivedMessage srm, ShowStatus sst, string myport, string partneraddress) 28 | { 29 | StartChatServer(myport); 30 | if (Status) 31 | { 32 | _srm = srm; 33 | _sst = sst; 34 | _client = new HttpClient() { BaseAddress = new Uri(partneraddress) }; 35 | 36 | ChatController.ThrowMessageArrivedEvent += (sender, args) => { ShowMessage(args.Message); }; 37 | } 38 | } 39 | 40 | //private methods 41 | private void StartChatServer(string myport) 42 | { 43 | try 44 | { 45 | string url = "http://localhost:" + myport + "/"; 46 | HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(url); 47 | 48 | config.Routes.MapHttpRoute( 49 | name: "DefaultApi", 50 | routeTemplate: "api/{controller}/{id}", 51 | defaults: new { id = RouteParameter.Optional } 52 | ); 53 | 54 | _server = new HttpSelfHostServer(config); 55 | _server.OpenAsync().Wait(); 56 | 57 | Status = true; 58 | } 59 | catch (Exception e) 60 | { 61 | Status = false; 62 | ShowError("Something happened!"); 63 | } 64 | } 65 | 66 | private void stopChatServer() 67 | { 68 | _server.CloseAsync().Wait(); 69 | } 70 | 71 | private void ShowMessage(Message m) 72 | { 73 | _srm(m); 74 | } 75 | 76 | private void ShowError(string txt) 77 | { 78 | _sst(txt); 79 | } 80 | 81 | //public methods 82 | public async void SendMessage(Message m) 83 | { 84 | try 85 | { 86 | HttpResponseMessage response = await _client.PostAsync("api/chat", m.serializedMessage); 87 | if (response.StatusCode != System.Net.HttpStatusCode.OK) 88 | ShowError("Partner responded, but awkwardly! Better hide!"); 89 | ShowMessage(m); 90 | } 91 | catch (Exception e) 92 | { 93 | stopChatServer(); 94 | ShowError("Partner unreachable. Closing your server!"); 95 | } 96 | } 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /WpfApplication1/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |