Search Results

Search found 3192 results on 128 pages for 'implicit conversion'.

Page 128/128 | < Previous Page | 124 125 126 127 128 

  • Memory limit for running external executables within Asp.net

    - by itsbalur
    I am using WkhtmltoPdf in my C# web application running in .NET 4.0 to generate PDFs from HTML files. In general everything works fine except when the size of the HTML file is below 250KB. Once the HTML file size increases beyond that, the process which runs the wkhtmltopdf.exe gives an exception as below. On the Task Manager, I have seen that the Memory value for the wkhtmltopdf.exe process does not increase beyond a value of 40,096 K, which I believe is the reason why the process is abandoned in between. How can we configure such that the memory limit for external exes can be increased? Is there any other way of solving this issue? More info: When I run the conversion from the command line directly, the PDF is generated fine. So, its unlikely to be a problem with WkhtmlToPdf. The error is from localhost. I have tried the same on the DEV server, with the same result. Exception: > [Exception: Loading pages (1/6) [> > ] 0% [======> ] > 10% [======> ] 11% > [=======> ] 13% > [=========> ] 15% > [==========> ] 18% > [============> ] 20% > [=============> ] 22% > [==============> ] 24% > [===============> ] 26% > [=================> ] 29% > [==================> ] 31% > [===================> ] 33% > [=====================> ] 35% > [======================> ] 37% > [========================> ] 40% > [=========================> ] 42% > [==========================> ] 44% > [============================> ] 47% > [=============================> ] 49% > [==============================> ] 51% > [============================================================] 100% > Counting pages (2/6) > [============================================================] Object > 1 of 1 Resolving links (4/6) > [============================================================] Object > 1 of 1 Loading headers and footers (5/6) > Printing pages (6/6) [> > ] Preparing [=> > ] Page 1 of 49 [==> > ] Page 2 of 49 [===> > ] Page 3 of 49 [====> > ] Page 4 of 49 [======> > ] Page 5 of 49 [=======> > ] Page 6 of 49 [========> > ] Page 7 of 49 [=========> > ] Page 8 of 49 [==========> > ] Page 9 of 49 [============> > ] Page 10 of 49 [=============> > ] Page 11 of 49 [==============> > ] Page 12 of 49 [===============> > ] Page 13 of 49 [================> > ] Page 14 of 49 [==================> > ] Page 15 of 49 [===================> > ] Page 16 of 49 [====================> > ] Page 17 of 49 [=====================> > ] Page 18 of 49 [======================> > ] Page 19 of 49 [========================> > ] Page 20 of 49 [=========================> > ] Page 21 of 49 [==========================> > ] Page 22 of 49 [===========================> > ] Page 23 of 49 [============================> > ] Page 24 of 49 [==============================> > ] Page 25 of 49 [===============================> > ] Page 26 of 49 [=================================> > ] Page 27 of 49 [==================================> > ] Code that I use: var fileName = " - "; var wkhtmlDir = ConfigurationManager.AppSettings[Constants.AppSettings.ExportToPdfExecutablePath]; var wkhtml = ConfigurationManager.AppSettings[Constants.AppSettings.ExportToPdfExecutablePath] + "\\wkhtmltopdf.exe"; var p = new Process(); string switches = ""; switches += "--print-media-type "; switches += "--margin-top 10mm --margin-bottom 10mm --margin-right 5mm --margin-left 5mm "; switches += "--page-size A4 "; switches += "--disable-smart-shrinking "; var startInfo = new ProcessStartInfo { CreateNoWindow = true, FileName = wkhtml, Arguments = switches + " " + url + " " + fileName, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput=true, WorkingDirectory=wkhtmlDir }; p.StartInfo = startInfo; p.Start();

    Read the article

  • Windows Start Menu Not Staying on Top

    - by Jeff Rapp
    Hey everyone. I've had this problem since Windows Vista. I did a clean install with Windows 7 and hoped it would fix the problem. Also swapped out the video card just to rule out a strange driver issue. Here's what's happening. After running for some period of time (usually a few hours), the Start button/orb will loose it's "Chrome" and turn into a plain button that just says "Start." It will work fine for a while, but then the start menu will just stop showing. Additionally, when I hit Win+D to show the desktop, the entire taskbar completely disappears. I can get it back usually by moving/minimizing windows that may be overlapping where the start menu should show. Otherwise, it requires either a full reboot or I'll end up killing & restarting the explorer.exe process. I realize that this is a strange issue - I took a video of it http://www.youtube.com/watch?v=0B3WwT0uyr4 Thanks! --Edit-- Here's my HijackThis log: Logfile of Trend Micro HijackThis v2.0.3 (BETA) Scan saved at 4:19:00 PM, on 12/16/2009 Platform: Unknown Windows (WinNT 6.01.3504) MSIE: Internet Explorer v8.00 (8.00.7600.16385) Boot mode: Normal Running processes: C:\Program Files (x86)\Pantone\hueyPRO\hueyPROTray.exe C:\Program Files (x86)\Adobe\Acrobat 9.0\Acrobat\acrotray.exe C:\Program Files (x86)\iTunes\iTunesHelper.exe C:\Program Files (x86)\Java\jre6\bin\jusched.exe C:\Program Files (x86)\MagicDisc\MagicDisc.exe C:\Program Files (x86)\Trillian\trillian.exe C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Ssms.exe C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\9.0\WebDev.WebServer.EXE C:\Program Files (x86)\Notepad++\notepad++.exe C:\Program Files (x86)\Fiddler2\Fiddler.exe C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\mspdbsrv.exe C:\Program Files (x86)\iTunes\iTunes.exe C:\Program Files (x86)\Adobe\Adobe Illustrator CS4\Support Files\Contents\Windows\Illustrator.exe C:\Program Files (x86)\ColorPic 4.1\ColorPic.exe C:\Program Files (x86)\Adobe\Acrobat 9.0\Acrobat\Acrobat.exe C:\Program Files (x86)\Common Files\Microsoft Shared\Help 9\dexplore.exe C:\Program Files (x86)\Common Files\Microsoft Shared\Help 9\dexplore.exe C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe C:\Program Files (x86)\eBay\Blackthorne\bin\BT.exe C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE C:\Program Files (x86)\CamStudio\Recorder.exe C:\Program Files (x86)\CamStudio\Playplus.exe C:\Program Files (x86)\Mozilla Firefox 3.6 Beta 3\firefox.exe C:\Program Files (x86)\CamStudio\Playplus.exe C:\Program Files (x86)\PuTTY\putty.exe C:\Program Files (x86)\CamStudio\Playplus.exe C:\Program Files (x86)\CamStudio\Playplus.exe C:\Program Files (x86)\TrendMicro\HiJackThis\HiJackThis.exe R1 - HKCU\Software\Microsoft\Internet Explorer\Main,Search Page = http://go.microsoft.com/fwlink/?LinkId=54896 R0 - HKCU\Software\Microsoft\Internet Explorer\Main,Start Page = http://go.microsoft.com/fwlink/?LinkId=69157 R1 - HKLM\Software\Microsoft\Internet Explorer\Main,Default_Page_URL = http://go.microsoft.com/fwlink/?LinkId=69157 R1 - HKLM\Software\Microsoft\Internet Explorer\Main,Default_Search_URL = http://go.microsoft.com/fwlink/?LinkId=54896 R1 - HKLM\Software\Microsoft\Internet Explorer\Main,Search Page = http://go.microsoft.com/fwlink/?LinkId=54896 R0 - HKLM\Software\Microsoft\Internet Explorer\Main,Start Page = http://go.microsoft.com/fwlink/?LinkId=69157 R0 - HKLM\Software\Microsoft\Internet Explorer\Search,SearchAssistant = R0 - HKLM\Software\Microsoft\Internet Explorer\Search,CustomizeSearch = R0 - HKLM\Software\Microsoft\Internet Explorer\Main,Local Page = C:\Windows\SysWOW64\blank.htm R0 - HKCU\Software\Microsoft\Internet Explorer\Toolbar,LinksFolderName = F2 - REG:system.ini: UserInit=userinit.exe O2 - BHO: ContributeBHO Class - {074C1DC5-9320-4A9A-947D-C042949C6216} - C:\Program Files (x86)\Adobe\/Adobe Contribute CS4/contributeieplugin.dll O2 - BHO: AcroIEHelperStub - {18DF081C-E8AD-4283-A596-FA578C2EBDC3} - C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroIEHelperShim.dll O2 - BHO: Groove GFS Browser Helper - {72853161-30C5-4D22-B7F9-0BBC1D38A37E} - C:\PROGRA~2\MICROS~1\Office14\GROOVEEX.DLL O2 - BHO: Windows Live Sign-in Helper - {9030D464-4C02-4ABF-8ECC-5164760863C6} - C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live\WindowsLiveLogin.dll O2 - BHO: Adobe PDF Conversion Toolbar Helper - {AE7CD045-E861-484f-8273-0445EE161910} - C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroIEFavClient.dll O2 - BHO: URLRedirectionBHO - {B4F3A835-0E21-4959-BA22-42B3008E02FF} - C:\PROGRA~2\MICROS~1\Office14\URLREDIR.DLL O2 - BHO: Java(tm) Plug-In 2 SSV Helper - {DBC80044-A445-435b-BC74-9C25C1C588A9} - C:\Program Files (x86)\Java\jre6\bin\jp2ssv.dll O2 - BHO: SmartSelect - {F4971EE7-DAA0-4053-9964-665D8EE6A077} - C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroIEFavClient.dll O3 - Toolbar: Adobe PDF - {47833539-D0C5-4125-9FA8-0819E2EAAC93} - C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroIEFavClient.dll O3 - Toolbar: Contribute Toolbar - {517BDDE4-E3A7-4570-B21E-2B52B6139FC7} - C:\Program Files (x86)\Adobe\/Adobe Contribute CS4/contributeieplugin.dll O4 - HKLM\..\Run: [AdobeCS4ServiceManager] "C:\Program Files (x86)\Common Files\Adobe\CS4ServiceManager\CS4ServiceManager.exe" -launchedbylogin O4 - HKLM\..\Run: [Adobe Acrobat Speed Launcher] "C:\Program Files (x86)\Adobe\Acrobat 9.0\Acrobat\Acrobat_sl.exe" O4 - HKLM\..\Run: [Acrobat Assistant 8.0] "C:\Program Files (x86)\Adobe\Acrobat 9.0\Acrobat\Acrotray.exe" O4 - HKLM\..\Run: [Adobe_ID0ENQBO] C:\PROGRA~2\COMMON~1\Adobe\ADOBEV~1\Server\bin\VERSIO~2.EXE O4 - HKLM\..\Run: [QuickTime Task] "C:\Program Files (x86)\QuickTime\QTTask.exe" -atboottime O4 - HKLM\..\Run: [iTunesHelper] "C:\Program Files (x86)\iTunes\iTunesHelper.exe" O4 - HKLM\..\Run: [SunJavaUpdateSched] "C:\Program Files (x86)\Java\jre6\bin\jusched.exe" O4 - HKUS\S-1-5-19\..\Run: [Sidebar] %ProgramFiles%\Windows Sidebar\Sidebar.exe /autoRun (User 'LOCAL SERVICE') O4 - HKUS\S-1-5-19\..\RunOnce: [mctadmin] C:\Windows\System32\mctadmin.exe (User 'LOCAL SERVICE') O4 - HKUS\S-1-5-20\..\Run: [Sidebar] %ProgramFiles%\Windows Sidebar\Sidebar.exe /autoRun (User 'NETWORK SERVICE') O4 - HKUS\S-1-5-20\..\RunOnce: [mctadmin] C:\Windows\System32\mctadmin.exe (User 'NETWORK SERVICE') O4 - Startup: ChatNowDesktop.appref-ms O4 - Startup: MagicDisc.lnk = C:\Program Files (x86)\MagicDisc\MagicDisc.exe O4 - Startup: Trillian.lnk = C:\Program Files (x86)\Trillian\trillian.exe O4 - Global Startup: Digsby.lnk = C:\Program Files (x86)\Digsby\digsby.exe O4 - Global Startup: hueyPROTray.lnk = C:\Program Files (x86)\Pantone\hueyPRO\hueyPROTray.exe O4 - Global Startup: OfficeSAS.lnk = ? O8 - Extra context menu item: Append Link Target to Existing PDF - res://C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroIEFavClient.dll/AcroIEAppendSelLinks.html O8 - Extra context menu item: Append to Existing PDF - res://C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroIEFavClient.dll/AcroIEAppend.html O8 - Extra context menu item: Convert Link Target to Adobe PDF - res://C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroIEFavClient.dll/AcroIECaptureSelLinks.html O8 - Extra context menu item: Convert to Adobe PDF - res://C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroIEFavClient.dll/AcroIECapture.html O8 - Extra context menu item: E&xport to Microsoft Excel - res://C:\PROGRA~1\MICROS~1\Office14\EXCEL.EXE/3000 O8 - Extra context menu item: S&end to OneNote - res://C:\PROGRA~1\MICROS~1\Office14\ONBttnIE.dll/105 O9 - Extra button: Send to OneNote - {2670000A-7350-4f3c-8081-5663EE0C6C49} - C:\Program Files (x86)\Microsoft Office\Office14\ONBttnIE.dll O9 - Extra 'Tools' menuitem: Se&nd to OneNote - {2670000A-7350-4f3c-8081-5663EE0C6C49} - C:\Program Files (x86)\Microsoft Office\Office14\ONBttnIE.dll O9 - Extra button: OneNote Lin&ked Notes - {789FE86F-6FC4-46A1-9849-EDE0DB0C95CA} - C:\Program Files (x86)\Microsoft Office\Office14\ONBttnIELinkedNotes.dll O9 - Extra 'Tools' menuitem: OneNote Lin&ked Notes - {789FE86F-6FC4-46A1-9849-EDE0DB0C95CA} - C:\Program Files (x86)\Microsoft Office\Office14\ONBttnIELinkedNotes.dll O9 - Extra button: Fiddler2 - {CF819DA3-9882-4944-ADF5-6EF17ECF3C6E} - "C:\Program Files (x86)\Fiddler2\Fiddler.exe" (file missing) O9 - Extra 'Tools' menuitem: Fiddler2 - {CF819DA3-9882-4944-ADF5-6EF17ECF3C6E} - "C:\Program Files (x86)\Fiddler2\Fiddler.exe" (file missing) O13 - Gopher Prefix: O16 - DPF: {5554DCB0-700B-498D-9B58-4E40E5814405} (RSClientPrint 2008 Class) - http://reportserver/Reports/Reserved.ReportViewerWebControl.axd?ReportSession=oxadkhfvfvt1hzf2eh3y1ay2&ControlID=b89e27f15e734f3faee1308eebdfab2a&Culture=1033&UICulture=9&ReportStack=1&OpType=PrintCab&Arch=X86 O16 - DPF: {82774781-8F4E-11D1-AB1C-0000F8773BF0} (DLC Class) - https://transfers.ds.microsoft.com/FTM/TransferSource/grTransferCtrl.cab O16 - DPF: {D27CDB6E-AE6D-11CF-96B8-444553540000} (Shockwave Flash Object) - http://fpdownload2.macromedia.com/get/shockwave/cabs/flash/swflash.cab O17 - HKLM\System\CCS\Services\Tcpip\Parameters: Domain = LapkoSoft.local O17 - HKLM\System\CCS\Services\Tcpip\..\{5992B87A-643B-4385-A914-249B98BF7129}: NameServer = 192.168.1.10 O17 - HKLM\System\CS1\Services\Tcpip\Parameters: Domain = LapkoSoft.local O17 - HKLM\System\CS2\Services\Tcpip\Parameters: Domain = LapkoSoft.local O18 - Filter hijack: text/xml - {807573E5-5146-11D5-A672-00B0D022E945} - C:\Program Files (x86)\Common Files\Microsoft Shared\OFFICE14\MSOXMLMF.DLL O23 - Service: Adobe Version Cue CS4 - Adobe Systems Incorporated - C:\Program Files (x86)\Common Files\Adobe\Adobe Version Cue CS4\Server\bin\VersionCueCS4.exe O23 - Service: @%SystemRoot%\system32\Alg.exe,-112 (ALG) - Unknown owner - C:\Windows\System32\alg.exe (file missing) O23 - Service: Apple Mobile Device - Apple Inc. - C:\Program Files (x86)\Common Files\Apple\Mobile Device Support\bin\AppleMobileDeviceService.exe O23 - Service: ASP.NET State Service (aspnet_state) - Unknown owner - C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_state.exe (file missing) O23 - Service: Bonjour Service - Apple Inc. - C:\Program Files (x86)\Bonjour\mDNSResponder.exe O23 - Service: @%SystemRoot%\system32\efssvc.dll,-100 (EFS) - Unknown owner - C:\Windows\System32\lsass.exe (file missing) O23 - Service: @%systemroot%\system32\fxsresm.dll,-118 (Fax) - Unknown owner - C:\Windows\system32\fxssvc.exe (file missing) O23 - Service: FLEXnet Licensing Service - Acresso Software Inc. - C:\Program Files (x86)\Common Files\Macrovision Shared\FLEXnet Publisher\FNPLicensingService.exe O23 - Service: FLEXnet Licensing Service 64 - Acresso Software Inc. - C:\Program Files\Common Files\Macrovision Shared\FLEXnet Publisher\FNPLicensingService64.exe O23 - Service: @%windir%\system32\inetsrv\iisres.dll,-30007 (IISADMIN) - Unknown owner - C:\Windows\system32\inetsrv\inetinfo.exe (file missing) O23 - Service: iPod Service - Apple Inc. - C:\Program Files\iPod\bin\iPodService.exe O23 - Service: @keyiso.dll,-100 (KeyIso) - Unknown owner - C:\Windows\system32\lsass.exe (file missing) O23 - Service: @comres.dll,-2797 (MSDTC) - Unknown owner - C:\Windows\System32\msdtc.exe (file missing) O23 - Service: @%SystemRoot%\System32\netlogon.dll,-102 (Netlogon) - Unknown owner - C:\Windows\system32\lsass.exe (file missing) O23 - Service: NVIDIA Performance Driver Service - Unknown owner - C:\Program Files\NVIDIA Corporation\Performance Drivers\nvPDsvc.exe O23 - Service: NVIDIA Display Driver Service (nvsvc) - Unknown owner - C:\Windows\system32\nvvsvc.exe (file missing) O23 - Service: @%systemroot%\system32\psbase.dll,-300 (ProtectedStorage) - Unknown owner - C:\Windows\system32\lsass.exe (file missing) O23 - Service: @%systemroot%\system32\Locator.exe,-2 (RpcLocator) - Unknown owner - C:\Windows\system32\locator.exe (file missing) O23 - Service: @%SystemRoot%\system32\samsrv.dll,-1 (SamSs) - Unknown owner - C:\Windows\system32\lsass.exe (file missing) O23 - Service: @%SystemRoot%\system32\snmptrap.exe,-3 (SNMPTRAP) - Unknown owner - C:\Windows\System32\snmptrap.exe (file missing) O23 - Service: @%systemroot%\system32\spoolsv.exe,-1 (Spooler) - Unknown owner - C:\Windows\System32\spoolsv.exe (file missing) O23 - Service: @%SystemRoot%\system32\sppsvc.exe,-101 (sppsvc) - Unknown owner - C:\Windows\system32\sppsvc.exe (file missing) O23 - Service: TeamViewer 5 (TeamViewer5) - TeamViewer GmbH - C:\Program Files (x86)\TeamViewer\Version5\TeamViewer_Service.exe O23 - Service: @%SystemRoot%\system32\ui0detect.exe,-101 (UI0Detect) - Unknown owner - C:\Windows\system32\UI0Detect.exe (file missing) O23 - Service: @%SystemRoot%\system32\vaultsvc.dll,-1003 (VaultSvc) - Unknown owner - C:\Windows\system32\lsass.exe (file missing) O23 - Service: @%SystemRoot%\system32\vds.exe,-100 (vds) - Unknown owner - C:\Windows\System32\vds.exe (file missing) O23 - Service: @%systemroot%\system32\vssvc.exe,-102 (VSS) - Unknown owner - C:\Windows\system32\vssvc.exe (file missing) O23 - Service: @%systemroot%\system32\wbengine.exe,-104 (wbengine) - Unknown owner - C:\Windows\system32\wbengine.exe (file missing) O23 - Service: @%Systemroot%\system32\wbem\wmiapsrv.exe,-110 (wmiApSrv) - Unknown owner - C:\Windows\system32\wbem\WmiApSrv.exe (file missing) O23 - Service: @%PROGRAMFILES%\Windows Media Player\wmpnetwk.exe,-101 (WMPNetworkSvc) - Unknown owner - C:\Program Files (x86)\Windows Media Player\wmpnetwk.exe (file missing)

    Read the article

  • Using the West Wind Web Toolkit to set up AJAX and REST Services

    - by Rick Strahl
    I frequently get questions about which option to use for creating AJAX and REST backends for ASP.NET applications. There are many solutions out there to do this actually, but when I have a choice - not surprisingly - I fall back to my own tools in the West Wind West Wind Web Toolkit. I've talked a bunch about the 'in-the-box' solutions in the past so for a change in this post I'll talk about the tools that I use in my own and customer applications to handle AJAX and REST based access to service resources using the West Wind West Wind Web Toolkit. Let me preface this by saying that I like things to be easy. Yes flexible is very important as well but not at the expense of over-complexity. The goal I've had with my tools is make it drop dead easy, with good performance while providing the core features that I'm after, which are: Easy AJAX/JSON Callbacks Ability to return any kind of non JSON content (string, stream, byte[], images) Ability to work with both XML and JSON interchangeably for input/output Access endpoints via POST data, RPC JSON calls, GET QueryString values or Routing interface Easy to use generic JavaScript client to make RPC calls (same syntax, just what you need) Ability to create clean URLS with Routing Ability to use standard ASP.NET HTTP Stack for HTTP semantics It's all about options! In this post I'll demonstrate most of these features (except XML) in a few simple and short samples which you can download. So let's take a look and see how you can build an AJAX callback solution with the West Wind Web Toolkit. Installing the Toolkit Assemblies The easiest and leanest way of using the Toolkit in your Web project is to grab it via NuGet: West Wind Web and AJAX Utilities (Westwind.Web) and drop it into the project by right clicking in your Project and choosing Manage NuGet Packages from anywhere in the Project.   When done you end up with your project looking like this: What just happened? Nuget added two assemblies - Westwind.Web and Westwind.Utilities and the client ww.jquery.js library. It also added a couple of references into web.config: The default namespaces so they can be accessed in pages/views and a ScriptCompressionModule that the toolkit optionally uses to compress script resources served from within the assembly (namely ww.jquery.js and optionally jquery.js). Creating a new Service The West Wind Web Toolkit supports several ways of creating and accessing AJAX services, but for this post I'll stick to the lower level approach that works from any plain HTML page or of course MVC, WebForms, WebPages. There's also a WebForms specific control that makes this even easier but I'll leave that for another post. So, to create a new standalone AJAX/REST service we can create a new HttpHandler in the new project either as a pure class based handler or as a generic .ASHX handler. Both work equally well, but generic handlers don't require any web.config configuration so I'll use that here. In the root of the project add a Generic Handler. I'm going to call this one StockService.ashx. Once the handler has been created, edit the code and remove all of the handler body code. Then change the base class to CallbackHandler and add methods that have a [CallbackMethod] attribute. Here's the modified base handler implementation now looks like with an added HelloWorld method: using System; using Westwind.Web; namespace WestWindWebAjax { /// <summary> /// Handler implements CallbackHandler to provide REST/AJAX services /// </summary> public class SampleService : CallbackHandler { [CallbackMethod] public string HelloWorld(string name) { return "Hello " + name + ". Time is: " + DateTime.Now.ToString(); } } } Notice that the class inherits from CallbackHandler and that the HelloWorld service method is marked up with [CallbackMethod]. We're done here. Services Urlbased Syntax Once you compile, the 'service' is live can respond to requests. All CallbackHandlers support input in GET and POST formats, and can return results as JSON or XML. To check our fancy HelloWorld method we can now access the service like this: http://localhost/WestWindWebAjax/StockService.ashx?Method=HelloWorld&name=Rick which produces a default JSON response - in this case a string (wrapped in quotes as it's JSON): (note by default JSON will be downloaded by most browsers not displayed - various options are available to view JSON right in the browser) If I want to return the same data as XML I can tack on a &format=xml at the end of the querystring which produces: <string>Hello Rick. Time is: 11/1/2011 12:11:13 PM</string> Cleaner URLs with Routing Syntax If you want cleaner URLs for each operation you can also configure custom routes on a per URL basis similar to the way that WCF REST does. To do this you need to add a new RouteHandler to your application's startup code in global.asax.cs one for each CallbackHandler based service you create: protected void Application_Start(object sender, EventArgs e) { CallbackHandlerRouteHandler.RegisterRoutes<StockService>(RouteTable.Routes); } With this code in place you can now add RouteUrl properties to any of your service methods. For the HelloWorld method that doesn't make a ton of sense but here is what a routed clean URL might look like in definition: [CallbackMethod(RouteUrl="stocks/HelloWorld/{name}")] public string HelloWorld(string name) { return "Hello " + name + ". Time is: " + DateTime.Now.ToString(); } The same URL I previously used now becomes a bit shorter and more readable with: http://localhost/WestWindWebAjax/HelloWorld/Rick It's an easy way to create cleaner URLs and still get the same functionality. Calling the Service with $.getJSON() Since the result produced is JSON you can now easily consume this data using jQuery's getJSON method. First we need a couple of scripts - jquery.js and ww.jquery.js in the page: <!DOCTYPE html> <html> <head> <link href="Css/Westwind.css" rel="stylesheet" type="text/css" /> <script src="scripts/jquery.min.js" type="text/javascript"></script> <script src="scripts/ww.jquery.min.js" type="text/javascript"></script> </head> <body> Next let's add a small HelloWorld example form (what else) that has a single textbox to type a name, a button and a div tag to receive the result: <fieldset> <legend>Hello World</legend> Please enter a name: <input type="text" name="txtHello" id="txtHello" value="" /> <input type="button" id="btnSayHello" value="Say Hello (POST)" /> <input type="button" id="btnSayHelloGet" value="Say Hello (GET)" /> <div id="divHelloMessage" class="errordisplay" style="display:none;width: 450px;" > </div> </fieldset> Then to call the HelloWorld method a little jQuery is used to hook the document startup and the button click followed by the $.getJSON call to retrieve the data from the server. <script type="text/javascript"> $(document).ready(function () { $("#btnSayHelloGet").click(function () { $.getJSON("SampleService.ashx", { Method: "HelloWorld", name: $("#txtHello").val() }, function (result) { $("#divHelloMessage") .text(result) .fadeIn(1000); }); });</script> .getJSON() expects a full URL to the endpoint of our service, which is the ASHX file. We can either provide a full URL (SampleService.ashx?Method=HelloWorld&name=Rick) or we can just provide the base URL and an object that encodes the query string parameters for us using an object map that has a property that matches each parameter for the server method. We can also use the clean URL routing syntax, but using the object parameter encoding actually is safer as the parameters will get properly encoded by jQuery. The result returned is whatever the result on the server method is - in this case a string. The string is applied to the divHelloMessage element and we're done. Obviously this is a trivial example, but it demonstrates the basics of getting a JSON response back to the browser. AJAX Post Syntax - using ajaxCallMethod() The previous example allows you basic control over the data that you send to the server via querystring parameters. This works OK for simple values like short strings, numbers and boolean values, but doesn't really work if you need to pass something more complex like an object or an array back up to the server. To handle traditional RPC type messaging where the idea is to map server side functions and results to a client side invokation, POST operations can be used. The easiest way to use this functionality is to use ww.jquery.js and the ajaxCallMethod() function. ww.jquery wraps jQuery's AJAX functions and knows implicitly how to call a CallbackServer method with parameters and parse the result. Let's look at another simple example that posts a simple value but returns something more interesting. Let's start with the service method: [CallbackMethod(RouteUrl="stocks/{symbol}")] public StockQuote GetStockQuote(string symbol) { Response.Cache.SetExpires(DateTime.UtcNow.Add(new TimeSpan(0, 2, 0))); StockServer server = new StockServer(); var quote = server.GetStockQuote(symbol); if (quote == null) throw new ApplicationException("Invalid Symbol passed."); return quote; } This sample utilizes a small StockServer helper class (included in the sample) that downloads a stock quote from Yahoo's financial site via plain HTTP GET requests and formats it into a StockQuote object. Lets create a small HTML block that lets us query for the quote and display it: <fieldset> <legend>Single Stock Quote</legend> Please enter a stock symbol: <input type="text" name="txtSymbol" id="txtSymbol" value="msft" /> <input type="button" id="btnStockQuote" value="Get Quote" /> <div id="divStockDisplay" class="errordisplay" style="display:none; width: 450px;"> <div class="label-left">Company:</div> <div id="stockCompany"></div> <div class="label-left">Last Price:</div> <div id="stockLastPrice"></div> <div class="label-left">Quote Time:</div> <div id="stockQuoteTime"></div> </div> </fieldset> The final result looks something like this:   Let's hook up the button handler to fire the request and fill in the data as shown: $("#btnStockQuote").click(function () { ajaxCallMethod("SampleService.ashx", "GetStockQuote", [$("#txtSymbol").val()], function (quote) { $("#divStockDisplay").show().fadeIn(1000); $("#stockCompany").text(quote.Company + " (" + quote.Symbol + ")"); $("#stockLastPrice").text(quote.LastPrice); $("#stockQuoteTime").text(quote.LastQuoteTime.formatDate("MMM dd, HH:mm EST")); }, onPageError); }); So we point at SampleService.ashx and the GetStockQuote method, passing a single parameter of the input symbol value. Then there are two handlers for success and failure callbacks.  The success handler is the interesting part - it receives the stock quote as a result and assigns its values to various 'holes' in the stock display elements. The data that comes back over the wire is JSON and it looks like this: { "Symbol":"MSFT", "Company":"Microsoft Corpora", "OpenPrice":26.11, "LastPrice":26.01, "NetChange":0.02, "LastQuoteTime":"2011-11-03T02:00:00Z", "LastQuoteTimeString":"Nov. 11, 2011 4:20pm" } which is an object representation of the data. JavaScript can evaluate this JSON string back into an object easily and that's the reslut that gets passed to the success function. The quote data is then applied to existing page content by manually selecting items and applying them. There are other ways to do this more elegantly like using templates, but here we're only interested in seeing how the data is returned. The data in the object is typed - LastPrice is a number and QuoteTime is a date. Note about the date value: JavaScript doesn't have a date literal although the JSON embedded ISO string format used above  ("2011-11-03T02:00:00Z") is becoming fairly standard for JSON serializers. However, JSON parsers don't deserialize dates by default and return them by string. This is why the StockQuote actually returns a string value of LastQuoteTimeString for the same date. ajaxMethodCallback always converts dates properly into 'real' dates and the example above uses the real date value along with a .formatDate() data extension (also in ww.jquery.js) to display the raw date properly. Errors and Exceptions So what happens if your code fails? For example if I pass an invalid stock symbol to the GetStockQuote() method you notice that the code does this: if (quote == null) throw new ApplicationException("Invalid Symbol passed."); CallbackHandler automatically pushes the exception message back to the client so it's easy to pick up the error message. Regardless of what kind of error occurs: Server side, client side, protocol errors - any error will fire the failure handler with an error object parameter. The error is returned to the client via a JSON response in the error callback. In the previous examples I called onPageError which is a generic routine in ww.jquery that displays a status message on the bottom of the screen. But of course you can also take over the error handling yourself: $("#btnStockQuote").click(function () { ajaxCallMethod("SampleService.ashx", "GetStockQuote", [$("#txtSymbol").val()], function (quote) { $("#divStockDisplay").fadeIn(1000); $("#stockCompany").text(quote.Company + " (" + quote.Symbol + ")"); $("#stockLastPrice").text(quote.LastPrice); $("#stockQuoteTime").text(quote.LastQuoteTime.formatDate("MMM dd, hh:mmt")); }, function (error, xhr) { $("#divErrorDisplay").text(error.message).fadeIn(1000); }); }); The error object has a isCallbackError, message and  stackTrace properties, the latter of which is only populated when running in Debug mode, and this object is returned for all errors: Client side, transport and server side errors. Regardless of which type of error you get the same object passed (as well as the XHR instance optionally) which makes for a consistent error retrieval mechanism. Specifying HttpVerbs You can also specify HTTP Verbs that are allowed using the AllowedHttpVerbs option on the CallbackMethod attribute: [CallbackMethod(AllowedHttpVerbs=HttpVerbs.GET | HttpVerbs.POST)] public string HelloWorld(string name) { … } If you're building REST style API's this might be useful to force certain request semantics onto the client calling. For the above if call with a non-allowed HttpVerb the request returns a 405 error response along with a JSON (or XML) error object result. The default behavior is to allow all verbs access (HttpVerbs.All). Passing in object Parameters Up to now the parameters I passed were very simple. But what if you need to send something more complex like an object or an array? Let's look at another example now that passes an object from the client to the server. Keeping with the Stock theme here lets add a method called BuyOrder that lets us buy some shares for a stock. Consider the following service method that receives an StockBuyOrder object as a parameter: [CallbackMethod] public string BuyStock(StockBuyOrder buyOrder) { var server = new StockServer(); var quote = server.GetStockQuote(buyOrder.Symbol); if (quote == null) throw new ApplicationException("Invalid or missing stock symbol."); return string.Format("You're buying {0} shares of {1} ({2}) stock at {3} for a total of {4} on {5}.", buyOrder.Quantity, quote.Company, quote.Symbol, quote.LastPrice.ToString("c"), (quote.LastPrice * buyOrder.Quantity).ToString("c"), buyOrder.BuyOn.ToString("MMM d")); } public class StockBuyOrder { public string Symbol { get; set; } public int Quantity { get; set; } public DateTime BuyOn { get; set; } public StockBuyOrder() { BuyOn = DateTime.Now; } } This is a contrived do-nothing example that simply echoes back what was passed in, but it demonstrates how you can pass complex data to a callback method. On the client side we now have a very simple form that captures the three values on a form: <fieldset> <legend>Post a Stock Buy Order</legend> Enter a symbol: <input type="text" name="txtBuySymbol" id="txtBuySymbol" value="GLD" />&nbsp;&nbsp; Qty: <input type="text" name="txtBuyQty" id="txtBuyQty" value="10" style="width: 50px" />&nbsp;&nbsp; Buy on: <input type="text" name="txtBuyOn" id="txtBuyOn" value="<%= DateTime.Now.ToString("d") %>" style="width: 70px;" /> <input type="button" id="btnBuyStock" value="Buy Stock" /> <div id="divStockBuyMessage" class="errordisplay" style="display:none"></div> </fieldset> The completed form and demo then looks something like this:   The client side code that picks up the input values and assigns them to object properties and sends the AJAX request looks like this: $("#btnBuyStock").click(function () { // create an object map that matches StockBuyOrder signature var buyOrder = { Symbol: $("#txtBuySymbol").val(), Quantity: $("#txtBuyQty").val() * 1, // number Entered: new Date() } ajaxCallMethod("SampleService.ashx", "BuyStock", [buyOrder], function (result) { $("#divStockBuyMessage").text(result).fadeIn(1000); }, onPageError); }); The code creates an object and attaches the properties that match the server side object passed to the BuyStock method. Each property that you want to update needs to be included and the type must match (ie. string, number, date in this case). Any missing properties will not be set but also not cause any errors. Pass POST data instead of Objects In the last example I collected a bunch of values from form variables and stuffed them into object variables in JavaScript code. While that works, often times this isn't really helping - I end up converting my types on the client and then doing another conversion on the server. If lots of input controls are on a page and you just want to pick up the values on the server via plain POST variables - that can be done too - and it makes sense especially if you're creating and filling the client side object only to push data to the server. Let's add another method to the server that once again lets us buy a stock. But this time let's not accept a parameter but rather send POST data to the server. Here's the server method receiving POST data: [CallbackMethod] public string BuyStockPost() { StockBuyOrder buyOrder = new StockBuyOrder(); buyOrder.Symbol = Request.Form["txtBuySymbol"]; ; int qty; int.TryParse(Request.Form["txtBuyQuantity"], out qty); buyOrder.Quantity = qty; DateTime time; DateTime.TryParse(Request.Form["txtBuyBuyOn"], out time); buyOrder.BuyOn = time; // Or easier way yet //FormVariableBinder.Unbind(buyOrder,null,"txtBuy"); var server = new StockServer(); var quote = server.GetStockQuote(buyOrder.Symbol); if (quote == null) throw new ApplicationException("Invalid or missing stock symbol."); return string.Format("You're buying {0} shares of {1} ({2}) stock at {3} for a total of {4} on {5}.", buyOrder.Quantity, quote.Company, quote.Symbol, quote.LastPrice.ToString("c"), (quote.LastPrice * buyOrder.Quantity).ToString("c"), buyOrder.BuyOn.ToString("MMM d")); } Clearly we've made this server method take more code than it did with the object parameter. We've basically moved the parameter assignment logic from the client to the server. As a result the client code to call this method is now a bit shorter since there's no client side shuffling of values from the controls to an object. $("#btnBuyStockPost").click(function () { ajaxCallMethod("SampleService.ashx", "BuyStockPost", [], // Note: No parameters - function (result) { $("#divStockBuyMessage").text(result).fadeIn(1000); }, onPageError, // Force all page Form Variables to be posted { postbackMode: "Post" }); }); The client simply calls the BuyStockQuote method and pushes all the form variables from the page up to the server which parses them instead. The feature that makes this work is one of the options you can pass to the ajaxCallMethod() function: { postbackMode: "Post" }); which directs the function to include form variable POST data when making the service call. Other options include PostNoViewState (for WebForms to strip out WebForms crap vars), PostParametersOnly (default), None. If you pass parameters those are always posted to the server except when None is set. The above code can be simplified a bit by using the FormVariableBinder helper, which can unbind form variables directly into an object: FormVariableBinder.Unbind(buyOrder,null,"txtBuy"); which replaces the manual Request.Form[] reading code. It receives the object to unbind into, a string of properties to skip, and an optional prefix which is stripped off form variables to match property names. The component is similar to the MVC model binder but it's independent of MVC. Returning non-JSON Data CallbackHandler also supports returning non-JSON/XML data via special return types. You can return raw non-JSON encoded strings like this: [CallbackMethod(ReturnAsRawString=true,ContentType="text/plain")] public string HelloWorldNoJSON(string name) { return "Hello " + name + ". Time is: " + DateTime.Now.ToString(); } Calling this method results in just a plain string - no JSON encoding with quotes around the result. This can be useful if your server handling code needs to return a string or HTML result that doesn't fit well for a page or other UI component. Any string output can be returned. You can also return binary data. Stream, byte[] and Bitmap/Image results are automatically streamed back to the client. Notice that you should set the ContentType of the request either on the CallbackMethod attribute or using Response.ContentType. This ensures the Web Server knows how to display your binary response. Using a stream response makes it possible to return any of data. Streamed data can be pretty handy to return bitmap data from a method. The following is a method that returns a stock history graph for a particular stock over a provided number of years: [CallbackMethod(ContentType="image/png",RouteUrl="stocks/history/graph/{symbol}/{years}")] public Stream GetStockHistoryGraph(string symbol, int years = 2,int width = 500, int height=350) { if (width == 0) width = 500; if (height == 0) height = 350; StockServer server = new StockServer(); return server.GetStockHistoryGraph(symbol,"Stock History for " + symbol,width,height,years); } I can now hook this up into the JavaScript code when I get a stock quote. At the end of the process I can assign the URL to the service that returns the image into the src property and so force the image to display. Here's the changed code: $("#btnStockQuote").click(function () { var symbol = $("#txtSymbol").val(); ajaxCallMethod("SampleService.ashx", "GetStockQuote", [symbol], function (quote) { $("#divStockDisplay").fadeIn(1000); $("#stockCompany").text(quote.Company + " (" + quote.Symbol + ")"); $("#stockLastPrice").text(quote.LastPrice); $("#stockQuoteTime").text(quote.LastQuoteTime.formatDate("MMM dd, hh:mmt")); // display a stock chart $("#imgStockHistory").attr("src", "stocks/history/graph/" + symbol + "/2"); },onPageError); }); The resulting output then looks like this: The charting code uses the new ASP.NET 4.0 Chart components via code to display a bar chart of the 2 year stock data as part of the StockServer class which you can find in the sample download. The ability to return arbitrary data from a service is useful as you can see - in this case the chart is clearly associated with the service and it's nice that the graph generation can happen off a handler rather than through a page. Images are common resources, but output can also be PDF reports, zip files for downloads etc. which is becoming increasingly more common to be returned from REST endpoints and other applications. Why reinvent? Obviously the examples I've shown here are pretty basic in terms of functionality. But I hope they demonstrate the core features of AJAX callbacks that you need to work through in most applications which is simple: return data, send back data and potentially retrieve data in various formats. While there are other solutions when it comes down to making AJAX callbacks and servicing REST like requests, I like the flexibility my home grown solution provides. Simply put it's still the easiest solution that I've found that addresses my common use cases: AJAX JSON RPC style callbacks Url based access XML and JSON Output from single method endpoint XML and JSON POST support, querystring input, routing parameter mapping UrlEncoded POST data support on callbacks Ability to return stream/raw string data Essentially ability to return ANYTHING from Service and pass anything All these features are available in various solutions but not together in one place. I've been using this code base for over 4 years now in a number of projects both for myself and commercial work and it's served me extremely well. Besides the AJAX functionality CallbackHandler provides, it's also an easy way to create any kind of output endpoint I need to create. Need to create a few simple routines that spit back some data, but don't want to create a Page or View or full blown handler for it? Create a CallbackHandler and add a method or multiple methods and you have your generic endpoints.  It's a quick and easy way to add small code pieces that are pretty efficient as they're running through a pretty small handler implementation. I can have this up and running in a couple of minutes literally without any setup and returning just about any kind of data. Resources Download the Sample NuGet: Westwind Web and AJAX Utilities (Westwind.Web) ajaxCallMethod() Documentation Using the AjaxMethodCallback WebForms Control West Wind Web Toolkit Home Page West Wind Web Toolkit Source Code © Rick Strahl, West Wind Technologies, 2005-2011Posted in ASP.NET  jQuery  AJAX   Tweet (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();

    Read the article

  • Capturing and Transforming ASP.NET Output with Response.Filter

    - by Rick Strahl
    During one of my Handlers and Modules session at DevConnections this week one of the attendees asked a question that I didn’t have an immediate answer for. Basically he wanted to capture response output completely and then apply some filtering to the output – effectively injecting some additional content into the page AFTER the page had completely rendered. Specifically the output should be captured from anywhere – not just a page and have this code injected into the page. Some time ago I posted some code that allows you to capture ASP.NET Page output by overriding the Render() method, capturing the HtmlTextWriter() and reading its content, modifying the rendered data as text then writing it back out. I’ve actually used this approach on a few occasions and it works fine for ASP.NET pages. But this obviously won’t work outside of the Page class environment and it’s not really generic – you have to create a custom page class in order to handle the output capture. [updated 11/16/2009 – updated ResponseFilterStream implementation and a few additional notes based on comments] Enter Response.Filter However, ASP.NET includes a Response.Filter which can be used – well to filter output. Basically Response.Filter is a stream through which the OutputStream is piped back to the Web Server (indirectly). As content is written into the Response object, the filter stream receives the appropriate Stream commands like Write, Flush and Close as well as read operations although for a Response.Filter that’s uncommon to be hit. The Response.Filter can be programmatically replaced at runtime which allows you to effectively intercept all output generation that runs through ASP.NET. A common Example: Dynamic GZip Encoding A rather common use of Response.Filter hooking up code based, dynamic  GZip compression for requests which is dead simple by applying a GZipStream (or DeflateStream) to Response.Filter. The following generic routines can be used very easily to detect GZip capability of the client and compress response output with a single line of code and a couple of library helper routines: WebUtils.GZipEncodePage(); which is handled with a few lines of reusable code and a couple of static helper methods: /// <summary> ///Sets up the current page or handler to use GZip through a Response.Filter ///IMPORTANT:  ///You have to call this method before any output is generated! /// </summary> public static void GZipEncodePage() {     HttpResponse Response = HttpContext.Current.Response;     if(IsGZipSupported())     {         stringAcceptEncoding = HttpContext.Current.Request.Headers["Accept-Encoding"];         if(AcceptEncoding.Contains("deflate"))         {             Response.Filter = newSystem.IO.Compression.DeflateStream(Response.Filter,                                        System.IO.Compression.CompressionMode.Compress);             Response.AppendHeader("Content-Encoding", "deflate");         }         else        {             Response.Filter = newSystem.IO.Compression.GZipStream(Response.Filter,                                       System.IO.Compression.CompressionMode.Compress);             Response.AppendHeader("Content-Encoding", "gzip");                            }     }     // Allow proxy servers to cache encoded and unencoded versions separately    Response.AppendHeader("Vary", "Content-Encoding"); } /// <summary> /// Determines if GZip is supported /// </summary> /// <returns></returns> public static bool IsGZipSupported() { string AcceptEncoding = HttpContext.Current.Request.Headers["Accept-Encoding"]; if (!string.IsNullOrEmpty(AcceptEncoding) && (AcceptEncoding.Contains("gzip") || AcceptEncoding.Contains("deflate"))) return true; return false; } GZipStream and DeflateStream are streams that are assigned to Response.Filter and by doing so apply the appropriate compression on the active Response. Response.Filter content is chunked So to implement a Response.Filter effectively requires only that you implement a custom stream and handle the Write() method to capture Response output as it’s written. At first blush this seems very simple – you capture the output in Write, transform it and write out the transformed content in one pass. And that indeed works for small amounts of content. But you see, the problem is that output is written in small buffer chunks (a little less than 16k it appears) rather than just a single Write() statement into the stream, which makes perfect sense for ASP.NET to stream data back to IIS in smaller chunks to minimize memory usage en route. Unfortunately this also makes it a more difficult to implement any filtering routines since you don’t directly get access to all of the response content which is problematic especially if those filtering routines require you to look at the ENTIRE response in order to transform or capture the output as is needed for the solution the gentleman in my session asked for. So in order to address this a slightly different approach is required that basically captures all the Write() buffers passed into a cached stream and then making the stream available only when it’s complete and ready to be flushed. As I was thinking about the implementation I also started thinking about the few instances when I’ve used Response.Filter implementations. Each time I had to create a new Stream subclass and create my custom functionality but in the end each implementation did the same thing – capturing output and transforming it. I thought there should be an easier way to do this by creating a re-usable Stream class that can handle stream transformations that are common to Response.Filter implementations. Creating a semi-generic Response Filter Stream Class What I ended up with is a ResponseFilterStream class that provides a handful of Events that allow you to capture and/or transform Response content. The class implements a subclass of Stream and then overrides Write() and Flush() to handle capturing and transformation operations. By exposing events it’s easy to hook up capture or transformation operations via single focused methods. ResponseFilterStream exposes the following events: CaptureStream, CaptureString Captures the output only and provides either a MemoryStream or String with the final page output. Capture is hooked to the Flush() operation of the stream. TransformStream, TransformString Allows you to transform the complete response output with events that receive a MemoryStream or String respectively and can you modify the output then return it back as a return value. The transformed output is then written back out in a single chunk to the response output stream. These events capture all output internally first then write the entire buffer into the response. TransformWrite, TransformWriteString Allows you to transform the Response data as it is written in its original chunk size in the Stream’s Write() method. Unlike TransformStream/TransformString which operate on the complete output, these events only see the current chunk of data written. This is more efficient as there’s no caching involved, but can cause problems due to searched content splitting over multiple chunks. Using this implementation, creating a custom Response.Filter transformation becomes as simple as the following code. To hook up the Response.Filter using the MemoryStream version event: ResponseFilterStream filter = new ResponseFilterStream(Response.Filter); filter.TransformStream += filter_TransformStream; Response.Filter = filter; and the event handler to do the transformation: MemoryStream filter_TransformStream(MemoryStream ms) { Encoding encoding = HttpContext.Current.Response.ContentEncoding; string output = encoding.GetString(ms.ToArray()); output = FixPaths(output); ms = new MemoryStream(output.Length); byte[] buffer = encoding.GetBytes(output); ms.Write(buffer,0,buffer.Length); return ms; } private string FixPaths(string output) { string path = HttpContext.Current.Request.ApplicationPath; // override root path wonkiness if (path == "/") path = ""; output = output.Replace("\"~/", "\"" + path + "/").Replace("'~/", "'" + path + "/"); return output; } The idea of the event handler is that you can do whatever you want to the stream and return back a stream – either the same one that’s been modified or a brand new one – which is then sent back to as the final response. The above code can be simplified even more by using the string version events which handle the stream to string conversions for you: ResponseFilterStream filter = new ResponseFilterStream(Response.Filter); filter.TransformString += filter_TransformString; Response.Filter = filter; and the event handler to do the transformation calling the same FixPaths method shown above: string filter_TransformString(string output) { return FixPaths(output); } The events for capturing output and capturing and transforming chunks work in a very similar way. By using events to handle the transformations ResponseFilterStream becomes a reusable component and we don’t have to create a new stream class or subclass an existing Stream based classed. By the way, the example used here is kind of a cool trick which transforms “~/” expressions inside of the final generated HTML output – even in plain HTML controls not HTML controls – and transforms them into the appropriate application relative path in the same way that ResolveUrl would do. So you can write plain old HTML like this: <a href=”~/default.aspx”>Home</a>  and have it turned into: <a href=”/myVirtual/default.aspx”>Home</a>  without having to use an ASP.NET control like Hyperlink or Image or having to constantly use: <img src=”<%= ResolveUrl(“~/images/home.gif”) %>” /> in MVC applications (which frankly is one of the most annoying things about MVC especially given the path hell that extension-less and endpoint-less URLs impose). I can’t take credit for this idea. While discussing the Response.Filter issues on Twitter a hint from Dylan Beattie who pointed me at one of his examples which does something similar. I thought the idea was cool enough to use an example for future demos of Response.Filter functionality in ASP.NET next I time I do the Modules and Handlers talk (which was great fun BTW). How practical this is is debatable however since there’s definitely some overhead to using a Response.Filter in general and especially on one that caches the output and the re-writes it later. Make sure to test for performance anytime you use Response.Filter hookup and make sure it' doesn’t end up killing perf on you. You’ve been warned :-}. How does ResponseFilterStream work? The big win of this implementation IMHO is that it’s a reusable  component – so for implementation there’s no new class, no subclassing – you simply attach to an event to implement an event handler method with a straight forward signature to retrieve the stream or string you’re interested in. The implementation is based on a subclass of Stream as is required in order to handle the Response.Filter requirements. What’s different than other implementations I’ve seen in various places is that it supports capturing output as a whole to allow retrieving the full response output for capture or modification. The exception are the TransformWrite and TransformWrite events which operate only active chunk of data written by the Response. For captured output, the Write() method captures output into an internal MemoryStream that is cached until writing is complete. So Write() is called when ASP.NET writes to the Response stream, but the filter doesn’t pass on the Write immediately to the filter’s internal stream. The data is cached and only when the Flush() method is called to finalize the Stream’s output do we actually send the cached stream off for transformation (if the events are hooked up) and THEN finally write out the returned content in one big chunk. Here’s the implementation of ResponseFilterStream: /// <summary> /// A semi-generic Stream implementation for Response.Filter with /// an event interface for handling Content transformations via /// Stream or String. /// <remarks> /// Use with care for large output as this implementation copies /// the output into a memory stream and so increases memory usage. /// </remarks> /// </summary> public class ResponseFilterStream : Stream { /// <summary> /// The original stream /// </summary> Stream _stream; /// <summary> /// Current position in the original stream /// </summary> long _position; /// <summary> /// Stream that original content is read into /// and then passed to TransformStream function /// </summary> MemoryStream _cacheStream = new MemoryStream(5000); /// <summary> /// Internal pointer that that keeps track of the size /// of the cacheStream /// </summary> int _cachePointer = 0; /// <summary> /// /// </summary> /// <param name="responseStream"></param> public ResponseFilterStream(Stream responseStream) { _stream = responseStream; } /// <summary> /// Determines whether the stream is captured /// </summary> private bool IsCaptured { get { if (CaptureStream != null || CaptureString != null || TransformStream != null || TransformString != null) return true; return false; } } /// <summary> /// Determines whether the Write method is outputting data immediately /// or delaying output until Flush() is fired. /// </summary> private bool IsOutputDelayed { get { if (TransformStream != null || TransformString != null) return true; return false; } } /// <summary> /// Event that captures Response output and makes it available /// as a MemoryStream instance. Output is captured but won't /// affect Response output. /// </summary> public event Action<MemoryStream> CaptureStream; /// <summary> /// Event that captures Response output and makes it available /// as a string. Output is captured but won't affect Response output. /// </summary> public event Action<string> CaptureString; /// <summary> /// Event that allows you transform the stream as each chunk of /// the output is written in the Write() operation of the stream. /// This means that that it's possible/likely that the input /// buffer will not contain the full response output but only /// one of potentially many chunks. /// /// This event is called as part of the filter stream's Write() /// operation. /// </summary> public event Func<byte[], byte[]> TransformWrite; /// <summary> /// Event that allows you to transform the response stream as /// each chunk of bytep[] output is written during the stream's write /// operation. This means it's possibly/likely that the string /// passed to the handler only contains a portion of the full /// output. Typical buffer chunks are around 16k a piece. /// /// This event is called as part of the stream's Write operation. /// </summary> public event Func<string, string> TransformWriteString; /// <summary> /// This event allows capturing and transformation of the entire /// output stream by caching all write operations and delaying final /// response output until Flush() is called on the stream. /// </summary> public event Func<MemoryStream, MemoryStream> TransformStream; /// <summary> /// Event that can be hooked up to handle Response.Filter /// Transformation. Passed a string that you can modify and /// return back as a return value. The modified content /// will become the final output. /// </summary> public event Func<string, string> TransformString; protected virtual void OnCaptureStream(MemoryStream ms) { if (CaptureStream != null) CaptureStream(ms); } private void OnCaptureStringInternal(MemoryStream ms) { if (CaptureString != null) { string content = HttpContext.Current.Response.ContentEncoding.GetString(ms.ToArray()); OnCaptureString(content); } } protected virtual void OnCaptureString(string output) { if (CaptureString != null) CaptureString(output); } protected virtual byte[] OnTransformWrite(byte[] buffer) { if (TransformWrite != null) return TransformWrite(buffer); return buffer; } private byte[] OnTransformWriteStringInternal(byte[] buffer) { Encoding encoding = HttpContext.Current.Response.ContentEncoding; string output = OnTransformWriteString(encoding.GetString(buffer)); return encoding.GetBytes(output); } private string OnTransformWriteString(string value) { if (TransformWriteString != null) return TransformWriteString(value); return value; } protected virtual MemoryStream OnTransformCompleteStream(MemoryStream ms) { if (TransformStream != null) return TransformStream(ms); return ms; } /// <summary> /// Allows transforming of strings /// /// Note this handler is internal and not meant to be overridden /// as the TransformString Event has to be hooked up in order /// for this handler to even fire to avoid the overhead of string /// conversion on every pass through. /// </summary> /// <param name="responseText"></param> /// <returns></returns> private string OnTransformCompleteString(string responseText) { if (TransformString != null) TransformString(responseText); return responseText; } /// <summary> /// Wrapper method form OnTransformString that handles /// stream to string and vice versa conversions /// </summary> /// <param name="ms"></param> /// <returns></returns> internal MemoryStream OnTransformCompleteStringInternal(MemoryStream ms) { if (TransformString == null) return ms; //string content = ms.GetAsString(); string content = HttpContext.Current.Response.ContentEncoding.GetString(ms.ToArray()); content = TransformString(content); byte[] buffer = HttpContext.Current.Response.ContentEncoding.GetBytes(content); ms = new MemoryStream(); ms.Write(buffer, 0, buffer.Length); //ms.WriteString(content); return ms; } /// <summary> /// /// </summary> public override bool CanRead { get { return true; } } public override bool CanSeek { get { return true; } } /// <summary> /// /// </summary> public override bool CanWrite { get { return true; } } /// <summary> /// /// </summary> public override long Length { get { return 0; } } /// <summary> /// /// </summary> public override long Position { get { return _position; } set { _position = value; } } /// <summary> /// /// </summary> /// <param name="offset"></param> /// <param name="direction"></param> /// <returns></returns> public override long Seek(long offset, System.IO.SeekOrigin direction) { return _stream.Seek(offset, direction); } /// <summary> /// /// </summary> /// <param name="length"></param> public override void SetLength(long length) { _stream.SetLength(length); } /// <summary> /// /// </summary> public override void Close() { _stream.Close(); } /// <summary> /// Override flush by writing out the cached stream data /// </summary> public override void Flush() { if (IsCaptured && _cacheStream.Length > 0) { // Check for transform implementations _cacheStream = OnTransformCompleteStream(_cacheStream); _cacheStream = OnTransformCompleteStringInternal(_cacheStream); OnCaptureStream(_cacheStream); OnCaptureStringInternal(_cacheStream); // write the stream back out if output was delayed if (IsOutputDelayed) _stream.Write(_cacheStream.ToArray(), 0, (int)_cacheStream.Length); // Clear the cache once we've written it out _cacheStream.SetLength(0); } // default flush behavior _stream.Flush(); } /// <summary> /// /// </summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="count"></param> /// <returns></returns> public override int Read(byte[] buffer, int offset, int count) { return _stream.Read(buffer, offset, count); } /// <summary> /// Overriden to capture output written by ASP.NET and captured /// into a cached stream that is written out later when Flush() /// is called. /// </summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="count"></param> public override void Write(byte[] buffer, int offset, int count) { if ( IsCaptured ) { // copy to holding buffer only - we'll write out later _cacheStream.Write(buffer, 0, count); _cachePointer += count; } // just transform this buffer if (TransformWrite != null) buffer = OnTransformWrite(buffer); if (TransformWriteString != null) buffer = OnTransformWriteStringInternal(buffer); if (!IsOutputDelayed) _stream.Write(buffer, offset, buffer.Length); } } The key features are the events and corresponding OnXXX methods that handle the event hookups, and the Write() and Flush() methods of the stream implementation. All the rest of the members tend to be plain jane passthrough stream implementation code without much consequence. I do love the way Action<t> and Func<T> make it so easy to create the event signatures for the various events – sweet. A few Things to consider Performance Response.Filter is not great for performance in general as it adds another layer of indirection to the ASP.NET output pipeline, and this implementation in particular adds a memory hit as it basically duplicates the response output into the cached memory stream which is necessary since you may have to look at the entire response. If you have large pages in particular this can cause potentially serious memory pressure in your server application. So be careful of wholesale adoption of this (or other) Response.Filters. Make sure to do some performance testing to ensure it’s not killing your app’s performance. Response.Filter works everywhere A few questions came up in comments and discussion as to capturing ALL output hitting the site and – yes you can definitely do that by assigning a Response.Filter inside of a module. If you do this however you’ll want to be very careful and decide which content you actually want to capture especially in IIS 7 which passes ALL content – including static images/CSS etc. through the ASP.NET pipeline. So it is important to filter only on what you’re looking for – like the page extension or maybe more effectively the Response.ContentType. Response.Filter Chaining Originally I thought that filter chaining doesn’t work at all due to a bug in the stream implementation code. But it’s quite possible to assign multiple filters to the Response.Filter property. So the following actually works to both compress the output and apply the transformed content: WebUtils.GZipEncodePage(); ResponseFilterStream filter = new ResponseFilterStream(Response.Filter); filter.TransformString += filter_TransformString; Response.Filter = filter; However the following does not work resulting in invalid content encoding errors: ResponseFilterStream filter = new ResponseFilterStream(Response.Filter); filter.TransformString += filter_TransformString; Response.Filter = filter; WebUtils.GZipEncodePage(); In other words multiple Response filters can work together but it depends entirely on the implementation whether they can be chained or in which order they can be chained. In this case running the GZip/Deflate stream filters apparently relies on the original content length of the output and chokes when the content is modified. But if attaching the compression first it works fine as unintuitive as that may seem. Resources Download example code Capture Output from ASP.NET Pages © Rick Strahl, West Wind Technologies, 2005-2010Posted in ASP.NET  

    Read the article

  • Multiple database with Spring+Hibernate+JPA

    - by ziftech
    Hi everybody! I'm trying to configure Spring+Hibernate+JPA for work with two databases (MySQL and MSSQL) my datasource-context.xml: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"> <!-- Data Source config --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${local.jdbc.driver}" p:url="${local.jdbc.url}" p:username="${local.jdbc.username}" p:password="${local.jdbc.password}"> </bean> <bean id="dataSourceRemote" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${remote.jdbc.driver}" p:url="${remote.jdbc.url}" p:username="${remote.jdbc.username}" p:password="${remote.jdbc.password}" /> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entity-manager-factory-ref="entityManagerFactory" /> <!-- JPA config --> <tx:annotation-driven transaction-manager="transactionManager" /> <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"> <property name="persistenceXmlLocations"> <list value-type="java.lang.String"> <value>classpath*:config/persistence.local.xml</value> <value>classpath*:config/persistence.remote.xml</value> </list> </property> <property name="dataSources"> <map> <entry key="localDataSource" value-ref="dataSource" /> <entry key="remoteDataSource" value-ref="dataSourceRemote" /> </map> </property> <property name="defaultDataSource" ref="dataSource" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:showSql="true" p:generateDdl="true"> </bean> </property> <property name="persistenceUnitManager" ref="persistenceUnitManager" /> <property name="persistenceUnitName" value="localjpa"/> </bean> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> </beans> each persistence.xml contains one unit, like this: <persistence-unit name="remote" transaction-type="RESOURCE_LOCAL"> <properties> <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultNamingStrategy" /> <property name="hibernate.dialect" value="${remote.hibernate.dialect}" /> <property name="hibernate.hbm2ddl.auto" value="${remote.hibernate.hbm2ddl.auto}" /> </properties> </persistence-unit> PersistenceUnitManager cause following exception: Cannot resolve reference to bean 'persistenceUnitManager' while setting bean property 'persistenceUnitManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'persistenceUnitManager' defined in class path resource [config/datasource-context.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.util.ArrayList] to required type [java.lang.String] for property 'persistenceXmlLocation'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.util.ArrayList] to required type [java.lang.String] for property 'persistenceXmlLocation': no matching editors or conversion strategy found If left only one persistence.xml without list, every works fine but I need 2 units... I also try to find alternative solution for work with two databases in Spring+Hibernate context, so I would appreciate any solution new error after changing to persistenceXmlLocations No single default persistence unit defined in {classpath:config/persistence.local.xml, classpath:config/persistence.remote.xml} UPDATE: I add persistenceUnitName, it works, but only with one unit, still need help UPDATE: thanks, ChssPly76 I changed config files: datasource-context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${local.jdbc.driver}" p:url="${local.jdbc.url}" p:username="${local.jdbc.username}" p:password="${local.jdbc.password}"> </bean> <bean id="dataSourceRemote" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${remote.jdbc.driver}" p:url="${remote.jdbc.url}" p:username="${remote.jdbc.username}" p:password="${remote.jdbc.password}"> </bean> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"> <property name="defaultPersistenceUnitName" value="pu1" /> </bean> <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"> <property name="persistenceXmlLocation" value="${persistence.xml.location}" /> <property name="defaultDataSource" ref="dataSource" /> <!-- problem --> <property name="dataSources"> <map> <entry key="local" value-ref="dataSource" /> <entry key="remote" value-ref="dataSourceRemote" /> </map> </property> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:showSql="true" p:generateDdl="true"> </bean> </property> <property name="persistenceUnitManager" ref="persistenceUnitManager" /> <property name="persistenceUnitName" value="pu1" /> <property name="dataSource" ref="dataSource" /> </bean> <bean id="entityManagerFactoryRemote" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:showSql="true" p:generateDdl="true"> </bean> </property> <property name="persistenceUnitManager" ref="persistenceUnitManager" /> <property name="persistenceUnitName" value="pu2" /> <property name="dataSource" ref="dataSourceRemote" /> </bean> <tx:annotation-driven /> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entity-manager-factory-ref="entityManagerFactory" /> <bean id="transactionManagerRemote" class="org.springframework.orm.jpa.JpaTransactionManager" p:entity-manager-factory-ref="entityManagerFactoryRemote" /> </beans> persistence.xml <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="pu1" transaction-type="RESOURCE_LOCAL"> <properties> <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultNamingStrategy" /> <property name="hibernate.dialect" value="${local.hibernate.dialect}" /> <property name="hibernate.hbm2ddl.auto" value="${local.hibernate.hbm2ddl.auto}" /> </properties> </persistence-unit> <persistence-unit name="pu2" transaction-type="RESOURCE_LOCAL"> <properties> <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultNamingStrategy" /> <property name="hibernate.dialect" value="${remote.hibernate.dialect}" /> <property name="hibernate.hbm2ddl.auto" value="${remote.hibernate.hbm2ddl.auto}" /> </properties> </persistence-unit> </persistence> Now it builds two entityManagerFactory, but both are for Microsoft SQL Server [main] INFO org.hibernate.ejb.Ejb3Configuration - Processing PersistenceUnitInfo [ name: pu1 ...] [main] INFO org.hibernate.cfg.SettingsFactory - RDBMS: Microsoft SQL Server [main] INFO org.hibernate.ejb.Ejb3Configuration - Processing PersistenceUnitInfo [ name: pu2 ...] [main] INFO org.hibernate.cfg.SettingsFactory - RDBMS: Microsoft SQL Server (but must MySQL) I suggest, that use only dataSource, dataSourceRemote (no substitution) is not worked. That's my last problem

    Read the article

  • Decompiling a *.DLL to assembly for .net in delphi 4

    - by Lex Dean
    I love my Delphi 4 but at the same time I see the need to talk to windows .net This is a recompiled dll that I found on sourceforge.net/projects/delphinet/ (DelphiNet03.zip) by some nice people that fund the dll from some were. The real answer is to make this dll so that fits into Delphi as true Delphi code, and not a dll clip on. So we can make objects that use dot net in Delphi. Because I’m not an assembly freak, I’m freaking out a little with a wee sweek for help! 1/ How do I link the asm code with the data info at the bottom of this code. Can some one show me which calls to look for to make this link to data. 2/ I need to find the beginning of all the procedures and functions, but I cannot find a ‘RET’ statement. And what line is the beginning statement in this code. 3/ How do I identify were the jump statements go to, put them into Delphi format In this code it looks I can do:- jle 402890h \1000:00402854 7e3a add [eax], al \1000:00402856 0000 …………………………………………….. or ch, [edi+3eh] \1000:0040288d 0a6f3e xrefs first: 1000:00402854 number : 1 \; add [eax], al \1000:00402890 0000 //******************************* jle @@21 \\1000:00402854 7e3a add [eax], al \\1000:00402856 0000 …………………………………………….. or ch, [edi+3eh] \1000:0040288d 0a6f3e xrefs first: 1000:00402854 number : 1 \; @@21 add [eax], al \1000:00402890 0000 Is that a correct conversion. I think a xrefs first: 1000:004021d1 number : 1 is the best to follow 4/ I need a good reference on 8086 up assembly code that I can print out and get to learn properly. I found this asm decomplier of http://www.cronos.cc/ that is so similar to Delphi that it only needs a little more convertion to get it into Delphi asm I think. It’s only taken me 3 hours to get the file into TMemo and to write a few lines to chop the line over in a stream and reload the memo. Help please Email: [email protected] xrefs first: 1000:004041ae number : 1 \\; dd 4190h \\1000:00402000 90410000 dd 00h \\1000:00402004 00000000 dec eax \\1000:00402008 48 add [eax], al \\1000:00402009 0000 add [edx], al \\1000:0040200b 0002 add [eax], al \\1000:0040200d 0000 add [eax-2bffffd2h], al \\1000:0040200f 00802e0000d4 adc al, [eax] \\1000:00402015 1200 add [ecx], al \\1000:00402017 0001 add [eax], al \\1000:00402019 0000 add [eax], al \\1000:0040201b 0000 add [eax], al \\1000:0040201d 0000 add [eax], al \\1000:0040201f 0000 add [eax], al \\1000:00402021 0000 add [eax], al \\1000:00402023 0000 add [eax], al \\1000:00402025 0000 add [eax], al \\1000:00402027 0000 add [eax], al \\1000:00402029 0000 add [eax], al \\1000:0040202b 0000 add [eax], al \\1000:0040202d 0000 add [eax], al \\1000:0040202f 0000 add [eax], al \\1000:00402031 0000 add [eax], al \\1000:00402033 0000 add [eax], al \\1000:00402035 0000 add [eax], al \\1000:00402037 0000 add [eax], al \\1000:00402039 0000 add [eax], al \\1000:0040203b 0000 add [eax], al \\1000:0040203d 0000 add [eax], al \\1000:0040203f 0000 add [eax], al \\1000:00402041 0000 add [eax], al \\1000:00402043 0000 add [eax], al \\1000:00402045 0000 add [eax], al \\1000:00402047 0000 add [eax], al \\1000:00402049 0000 add [eax], al \\1000:0040204b 0000 add [eax], al \\1000:0040204d 0000 add [ebx], dl \\1000:0040204f 0013 xor [eax+eax], al \\1000:00402051 300400 or al, [ecx] \\1000:00402054 0a01 add [eax], al \\1000:00402056 0000 add [eax], eax \\1000:00402058 0100 add [ecx], dl \\1000:0040205a 0011 push cs \\1000:0040205c 0e add al, 50h \\1000:0040205d 0450 mov gs, [ecx+05h] \\1000:0040205f 8e6905 push eax \\1000:00402062 50 mov gs, [ecx+2eh] \\1000:00402063 8e692e add eax, f938h \\1000:00402066 0538f90000 add [ebx], al \\1000:0040206b 0003 jc 402070h \\1000:0040206d 7201 add [eax], al \\1000:0040206f 0000 jo 40209bh \\1000:00402071 7028 add al, [eax] \\1000:00402073 0200 add [edx], cl \\1000:00402075 000a sub eax, 36f0408h \\1000:00402077 2d08046f03 add [eax], al \\1000:0040207c 0000 or ch, [ebx] \\1000:0040207e 0a2b push es \\1000:00402080 06 add al, 6fh \\1000:00402081 046f add al, 00h \\1000:00402083 0400 add [edx], cl \\1000:00402085 000a adc eax, [edi] \\1000:00402087 1307 push ss \\1000:00402089 16 adc ecx, [eax] \\1000:0040208a 1308 cmp cl, cl \\1000:0040208c 38c9 add [eax], al \\1000:0040208e 0000 add [ecx], dl \\1000:00402090 0011 pop es \\1000:00402092 07 adc [eax], ecx \\1000:00402093 1108 callf 056f:060a9a08h \\1000:00402095 9a0a066f05 add [eax], al \\1000:0040209a 0000 or cl, [ebx] \\1000:0040209c 0a0b push es \\1000:0040209e 06 outsd \\1000:0040209f 6f push es \\1000:004020a0 06 add [eax], al \\1000:004020a1 0000 or al, [ebx] \\1000:004020a3 0a03 sub [edx], al \\1000:004020a5 2802 add [eax], al \\1000:004020a7 0000 or bh, [ecx] \\1000:004020a9 0a39 movsd \\1000:004020ab a5 add [eax], al \\1000:004020ac 0000 add [edi], al \\1000:004020ae 0007 mov gs, [ecx+0eh] \\1000:004020b0 8e690e add al, 50h \\1000:004020b3 0450 mov gs, [ecx+40h] \\1000:004020b5 8e6940 cwde \\1000:004020b8 98 add [eax], al \\1000:004020b9 0000 add [edi], dl \\1000:004020bb 0017 or al, 16h \\1000:004020bd 0c16 or eax, 9072b2bh \\1000:004020bf 0d2b2b0709 callf 0000:076f9a09h \\1000:004020c4 9a6f070000 or ch, [edi+08h] \\1000:004020c9 0a6f08 add [eax], al \\1000:004020cc 0000 or ch, [eax+ebx] \\1000:004020ce 0a2c18 push cs \\1000:004020d1 0e add al, 50h \\1000:004020d2 0450 or [edx+d72h], ebx \\1000:004020d4 099a720d0000 jo 402104h \\1000:004020da 7028 or [eax], eax \\1000:004020dc 0900 add [edx], cl \\1000:004020de 000a add dl, cs:[esi] \\1000:004020e0 2e0216 or al, 08h \\1000:004020e3 0c08 sub eax, 90c2b02h \\1000:004020e5 2d022b0c09 pop ss \\1000:004020ea 17 pop eax \\1000:004020eb 58 or eax, 50040e09h \\1000:004020ec 0d090e0450 mov gs, [ecx+32h] \\1000:004020f1 8e6932 int 08h \\1000:004020f4 cd08 sub al, 5ch \\1000:004020f6 2c5c push ss \\1000:004020f8 16 adc eax, [ebx+ebp] \\1000:004020f9 13042b dec esi \\1000:004020fc 4e push cs \\1000:004020fd 0e add al, 50h \\1000:004020fe 0450 adc [edx+ebx*4], eax \\1000:00402100 11049a jc 402112h \\1000:00402103 720d add [eax], al \\1000:00402105 0000 jo 402131h \\1000:00402107 7028 or [eax], eax \\1000:00402109 0900 add [edx], cl \\1000:0040210b 000a xor esi, [esi] \\1000:0040210d 3336 pop es \\1000:0040210f 07 adc [edx+ebx*4], eax \\1000:00402110 11049a outsd \\1000:00402113 6f pop es \\1000:00402114 07 add [eax], al \\1000:00402115 0000 or ch, [edi+0ah] \\1000:00402117 0a6f0a add [eax], al \\1000:0040211a 0000 or dl, [ebx] \\1000:0040211c 0a13 push es \\1000:0040211e 06 add eax, 9a041150h \\1000:0040211f 055011049a sub [ebx], cl \\1000:00402124 280b add [eax], al \\1000:00402126 0000 or dl, [edx] \\1000:00402128 0a12 push es \\1000:0040212a 06 adc al, [c28h] \\1000:0040212b 1205280c0000 xrefs first: 1000:00402107 number : 1 \\; or ch, [edx+eax] \\1000:00402131 0a2c02 sub ebx, [esi] \\1000:00402134 2b1e push cs \\1000:00402136 0e add al, 50h \\1000:00402137 0450 adc [edi+eax], eax \\1000:00402139 110407 adc [edx+ebx*4], eax \\1000:0040213c 11049a outsd \\1000:0040213f 6f pop es \\1000:00402140 07 add [eax], al \\1000:00402141 0000 or ah, [edx+58170411h] \\1000:00402143 0aa211041758 adc eax, [ecx+edx] \\1000:00402149 130411 add al, 0eh \\1000:0040214c 040e add al, 50h \\1000:0040214e 0450 mov gs, [ecx+32h] \\1000:00402150 8e6932 test eax, 58170811h \\1000:00402153 a911081758 adc ecx, [eax] \\1000:00402158 1308 adc [eax], ecx \\1000:0040215a 1108 adc [edi], eax \\1000:0040215c 1107 mov gs, [ecx+3fh] \\1000:0040215e 8e693f sub al, ffh \\1000:00402161 2cff db ff \\1000:00402163 ff jmp [edx] \\1000:00402164 ff2a add [eax], al \\1000:00402166 0000 adc esi, [eax] \\1000:00402168 1330 add eax, 8100h \\1000:0040216a 0500810000 add [edx], al \\1000:0040216f 0002 add [eax], al \\1000:00402171 0000 adc [edx+esi*2], eax \\1000:00402173 110472 xor eax, [eax] \\1000:00402176 3300 add [eax+28h], dh \\1000:00402178 007028 add al, [eax] \\1000:0040217b 0200 add [edx], cl \\1000:0040217d 000a sub al, 09h \\1000:0040217f 2c09 add ebp, [eax] \\1000:00402181 0328 or eax, a0a0000h \\1000:00402183 0d00000a0a sub eax, [edi] \\1000:00402188 2b07 add al, 28h \\1000:0040218a 0428 push cs \\1000:0040218c 0e add [eax], al \\1000:0040218d 0000 or cl, [edx] \\1000:0040218f 0a0a push es \\1000:00402191 06 add eax, f6f1717h \\1000:00402192 0517176f0f add [eax], al \\1000:00402197 0000 or cl, [ebx] \\1000:00402199 0a0b push ss \\1000:0040219b 16 lea eax, [edx] \\1000:0040219c 8d02 add [eax], al \\1000:0040219e 0000 add [esi+ecx], ecx \\1000:004021a0 010c0e add al, 2ch \\1000:004021a3 042c push cs \\1000:004021a5 260e add al, 8eh \\1000:004021a7 048e c160d imul edi, [eax+28dh], d160c01h \\1000:004021a9 69b88d020000010c sub edx, [eax] \\1000:004021b3 2b10 or [ecx], cl \\1000:004021b5 0809 push cs \\1000:004021b7 0e add al, 09h \\1000:004021b8 0409 callf 0000:106f9a09h \\1000:004021ba 9a6f100000 or ah, [edx+d581709h] \\1000:004021bf 0aa20917580d or [esi], ecx \\1000:004021c5 090e add al, 8eh \\1000:004021c7 048e imul esi, [edx], 17202e9h \\1000:004021c9 6932e9027201 add [eax], al \\1000:004021cf 0000 jo 4021dah \\1000:004021d1 7007 db 0f \\1000:004021d3 0f add al, 12h \\1000:004021d4 0412 add ch, [eax] \\1000:004021d6 0228 add [eax], eax \\1000:004021d8 0100 xrefs first: 1000:004021d1 number : 1 \\; add [esi], al \\1000:004021da 0006 pop es \\1000:004021dc 07 or [edi+11h], ch \\1000:004021dd 086f11 add [eax], al \\1000:004021e0 0000 or dl, [ebx] \\1000:004021e2 0a13 add al, 11h \\1000:004021e4 0411 add al, 0eh \\1000:004021e6 040e add al, 6fh \\1000:004021e8 046f adc al, [eax] \\1000:004021ea 1200 add [edx], cl \\1000:004021ec 000a adc eax, [511002bh] \\1000:004021ee 13052b001105 sub al, [eax] \\1000:004021f4 2a00 add [eax], al \\1000:004021f6 0000 adc esi, [eax] \\1000:004021f8 1330 add eax, 4e00h \\1000:004021fa 05004e0000 add [ebx], al \\1000:004021ff 0003 add [eax], al \\1000:00402201 0000 adc [ebx], eax \\1000:00402203 1103 outsd \\1000:00402205 6f adc [eax], al \\1000:00402206 1000 add [edx], cl \\1000:00402208 000a or al, [8db8698eh] \\1000:0040220a 0a058e69b88d add al, [eax] \\1000:00402210 0200 add [ecx], al \\1000:00402212 0001 or edx, [esi] \\1000:00402214 0b16 or al, 2bh \\1000:00402216 0c2b db 0f \\1000:00402218 0f pop es \\1000:00402219 07 or [106f9a08h], al \\1000:0040221a 0805089a6f10 add [eax], al \\1000:00402220 0000 or ah, [edx+c581708h] \\1000:00402222 0aa20817580c or [eb32698eh], al \\1000:00402228 08058e6932eb add al, [esi+eax] \\1000:0040222e 020406 lsl edx, [edx] \\1000:00402231 0f0312 add [eax], ebp \\1000:00402234 0128 add [eax], eax \\1000:00402236 0100 add [esi], al \\1000:00402238 0006 push es \\1000:0040223a 06 add al, 07h \\1000:0040223b 0407 outsd \\1000:0040223d 6f adc eax, [eax] \\1000:0040223e 1300 add [edx], cl \\1000:00402240 000a or eax, 6f050309h \\1000:00402242 0d0903056f adc al, 00h \\1000:00402247 1400 add [edx], cl \\1000:00402249 000a adc eax, [ebx+ebp] \\1000:0040224b 13042b add [ecx], dl \\1000:0040224e 0011 add al, 2ah \\1000:00402250 042a add [eax], al \\1000:00402252 0000 adc esi, [eax] \\1000:00402254 1330 add eax, 7600h \\1000:00402256 0500760000 add [eax+eax], al \\1000:0040225b 000400 add [ecx], dl \\1000:0040225e 0011 add al, 72h \\1000:00402260 0472 xor eax, [eax] \\1000:00402262 3300 add [eax+28h], dh \\1000:00402264 007028 add al, [eax] \\1000:00402267 0200 add [edx], cl \\1000:00402269 000a sub al, 09h \\1000:0040226b 2c09 add ebp, [eax] \\1000:0040226d 0328 or eax, a0a0000h \\1000:0040226f 0d00000a0a sub eax, [edi] \\1000:00402274 2b07 add al, 28h \\1000:00402276 0428 push cs \\1000:00402278 0e add [eax], al \\1000:00402279 0000 or cl, [edx] \\1000:0040227b 0a0a push es \\1000:0040227d 06 add eax, f6f1717h \\1000:0040227e 0517176f0f add [eax], al \\1000:00402283 0000 or cl, [ebx] \\1000:00402285 0a0b push cs \\1000:00402287 0e add eax, 8db8698eh \\1000:00402288 058e69b88d add al, [eax] \\1000:0040228d 0200 add [ecx], al \\1000:0040228f 0001 or al, 16h \\1000:00402291 0c16 or eax, 908102bh \\1000:00402293 0d2b100809 push cs \\1000:00402298 0e add eax, 106f9a09h \\1000:00402299 05099a6f10 add [eax], al \\1000:0040229e 0000 or ah, [edx+d581709h] \\1000:004022a0 0aa20917580d or [esi], ecx \\1000:004022a6 090e add eax, e932698eh \\1000:004022a8 058e6932e9 add cl, [esi] \\1000:004022ad 020e add al, 07h \\1000:004022af 0407 db 0f \\1000:004022b1 0f add eax, 1280212h \\1000:004022b2 0512022801 add [eax], al \\1000:004022b7 0000 push es \\1000:004022b9 06 pop es \\1000:004022ba 07 push cs \\1000:004022bb 0e add al, 08h \\1000:004022bc 0408 outsd \\1000:004022be 6f adc eax, [eax] \\1000:004022bf 1300 add [edx], cl \\1000:004022c1 000a adc eax, [ecx+edx] \\1000:004022c3 130411 add al, 14h \\1000:004022c6 0414 push cs \\1000:004022c8 0e add eax, 146fh \\1000:004022c9 056f140000 or dl, [ebx] \\1000:004022ce 0a13 add eax, 511002bh \\1000:004022d0 052b001105 sub al, [eax] \\1000:004022d5 2a00 add [ebx], dl \\1000:004022d7 0013 xor [eax+eax], al \\1000:004022d9 300400 jbe 4022deh \\1000:004022dc 7600 xrefs first: 1000:004022dc number : 1 \\; add fs:[esi+45h], cl \\1000:004034fc 64004e45 push esp \\1000:00403500 54 dec ecx \\1000:00403501 49 xrefs first: 1000:004034b2 number : 1 \\; outsb \\1000:00403502 6e jbe 403574h \\1000:00403503 766f imul esp, [ebp+43h], 6ch \\1000:00403505 6b65436c popad \\1000:00403509 61 jnc 40357fh \\1000:0040350a 7373 dec ebp \\1000:0040350c 4d jz 403578h \\1000:0040350d 657468 outsd \\1000:00403510 6f add fs:[esi+45h], cl \\1000:00403511 64004e45 push esp \\1000:00403515 54 push ebx \\1000:00403516 53 jz 40355fh \\1000:00403517 657445 outsb \\1000:0040351a 6e jnz 40358ah \\1000:0040351b 756d push esi \\1000:0040351d 56 xrefs first: 1000:004034b7 number : 1 \\; popad \\1000:0040351e 61 insb \\1000:0040351f 6c jnz 403587h \\1000:00403520 7565 add [esi+45h], cl \\1000:00403522 004e45 push esp \\1000:00403525 54 inc edi \\1000:00403526 47 db 65 ;'e' \\1000:00403527 65 xrefs first: 1000:004034be number : 1 \\; db 74 ;'t' \\1000:00403528 74 db 50 ;'p' \\1000:00403529 50 db 72 ;'r' \\1000:0040352a 72 db 6f ;'o' \\1000:0040352b 6f db 70 ;'p' \\1000:0040352c 70 db 65 ;'e' \\1000:0040352d 65 db 72 ;'r' \\1000:0040352e 72 db 74 ;'t' \\1000:0040352f 74 db 79 ;'y' \\1000:00403530 79 db 00 \\1000:00403531 00 db 4e ;'n' \\1000:00403532 4e db 45 ;'e' \\1000:00403533 45 db 54 ;'t' \\1000:00403534 54 db 47 ;'g' \\1000:00403535 47 db 65 ;'e' \\1000:00403536 65 db 74 ;'t' \\1000:00403537 74 db 46 ;'f' \\1000:00403538 46 db 69 ;'i' \\1000:00403539 69 db 65 ;'e' \\1000:0040353a 65 db 6c ;'l' \\1000:0040353b 6c db 64 ;'d' \\1000:0040353c 64 db 00 \\1000:0040353d 00 could not fit the rest in because of Stack overflow limitions

    Read the article

  • Slowdowns when reading from an urlconnection's inputstream (even with byte[] and buffers)

    - by user342677
    Ok so after spending two days trying to figure out the problem, and reading about dizillion articles, i finally decided to man up and ask to for some advice(my first time here). Now to the issue at hand - I am writing a program which will parse api data from a game, namely battle logs. There will be A LOT of entries in the database(20+ million) and so the parsing speed for each battle log page matters quite a bit. The pages to be parsed look like this: http://api.erepublik.com/v1/feeds/battle_logs/10000/0. (see source code if using chrome, it doesnt display the page right). It has 1000 hit entries, followed by a little battle info(lastpage will have <1000 obviously). On average, a page contains 175000 characters, UTF-8 encoding, xml format(v 1.0). Program will run locally on a good PC, memory is virtually unlimited(so that creating byte[250000] is quite ok). The format never changes, which is quite convenient. Now, I started off as usual: //global vars,class declaration skipped public WebObject(String url_string, int connection_timeout, int read_timeout, boolean redirects_allowed, String user_agent) throws java.net.MalformedURLException, java.io.IOException { // Open a URL connection java.net.URL url = new java.net.URL(url_string); java.net.URLConnection uconn = url.openConnection(); if (!(uconn instanceof java.net.HttpURLConnection)) { throw new java.lang.IllegalArgumentException("URL protocol must be HTTP"); } conn = (java.net.HttpURLConnection) uconn; conn.setConnectTimeout(connection_timeout); conn.setReadTimeout(read_timeout); conn.setInstanceFollowRedirects(redirects_allowed); conn.setRequestProperty("User-agent", user_agent); } public void executeConnection() throws IOException { try { is = conn.getInputStream(); //global var l = conn.getContentLength(); //global var } catch (Exception e) { //handling code skipped } } //getContentStream and getLength methods which just return'is' and 'l' are skipped Here is where the fun part began. I ran some profiling (using System.currentTimeMillis()) to find out what takes long ,and what doesnt. The call to this method takes only 200ms on avg public InputStream getWebPageAsStream(int battle_id, int page) throws Exception { String url = "http://api.erepublik.com/v1/feeds/battle_logs/" + battle_id + "/" + page; WebObject wobj = new WebObject(url, 10000, 10000, true, "Mozilla/5.0 " + "(Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)"); wobj.executeConnection(); l = wobj.getContentLength(); // global variable return wobj.getContentStream(); //returns 'is' stream } 200ms is quite expected from a network operation, and i am fine with it. BUT when i parse the inputStream in any way(read it into string/use java XML parser/read it into another ByteArrayStream) the process takes over 1000ms! for example, this code takes 1000ms IF i pass the stream i got('is') above from getContentStream() directly to this method: public static Document convertToXML(InputStream is) throws ParserConfigurationException, IOException, SAXException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(is); doc.getDocumentElement().normalize(); return doc; } this code too, takes around 920ms IF the initial InputStream 'is' is passed in(dont read into the code itself - it just extracts the data i need by directly counting the characters, which can be done thanks to the rigid api feed format): public static parsedBattlePage convertBattleToXMLWithoutDOM(InputStream is) throws IOException { // Point A BufferedReader br = new BufferedReader(new InputStreamReader(is)); LinkedList ll = new LinkedList(); String str = br.readLine(); while (str != null) { ll.add(str); str = br.readLine(); } if (((String) ll.get(1)).indexOf("error") != -1) { return new parsedBattlePage(null, null, true, -1); } //Point B Iterator it = ll.iterator(); it.next(); it.next(); it.next(); it.next(); String[][] hits_arr = new String[1000][4]; String t_str = (String) it.next(); String tmp = null; int j = 0; for (int i = 0; t_str.indexOf("time") != -1; i++) { hits_arr[i][0] = t_str.substring(12, t_str.length() - 11); tmp = (String) it.next(); hits_arr[i][1] = tmp.substring(14, tmp.length() - 9); tmp = (String) it.next(); hits_arr[i][2] = tmp.substring(15, tmp.length() - 10); tmp = (String) it.next(); hits_arr[i][3] = tmp.substring(18, tmp.length() - 13); it.next(); it.next(); t_str = (String) it.next(); j++; } String[] b_info_arr = new String[9]; int[] space_nums = {13, 10, 13, 11, 11, 12, 5, 10, 13}; for (int i = 0; i < space_nums.length; i++) { tmp = (String) it.next(); b_info_arr[i] = tmp.substring(space_nums[i] + 4, tmp.length() - space_nums[i] - 1); } //Point C return new parsedBattlePage(hits_arr, b_info_arr, false, j); } I have tried replacing the default BufferedReader with BufferedReader br = new BufferedReader(new InputStreamReader(is), 250000); This didnt change much. My second try was to replace the code between A and B with: Iterator it = IOUtils.lineIterator(is, "UTF-8"); Same result, except this time A-B was 0ms, and B-C was 1000ms, so then every call to it.next() must have been consuming some significant time.(IOUtils is from apache-commons-io library). And here is the culprit - the time taken to parse the stream to string, be it by an iterator or BufferedReader in ALL cases was about 1000ms, while the rest of the code took 0ms(e.g. irrelevant). This means that parsing the stream to LinkedList, or iterating over it, for some reason was eating up a lot of my system resources. question was - why? Is it just the way java is made...no...thats just stupid, so I did another experiment. In my main method I added after the getWebPageAsStream(): //Point A ba = new byte[l]; // 'l' comes from wobj.getContentLength above bytesRead = is.read(ba); //'is' is our URLConnection original InputStream offset = bytesRead; while (bytesRead != -1) { bytesRead = is.read(ba, offset - 1, l - offset); offset += bytesRead; } //Point B InputStream is2 = new ByteArrayInputStream(ba); //Now just working with 'is2' - the "copied" stream The InputStream-byte[] conversion took again 1000ms - this is the way many ppl suggested to read an InputStream, and stil it is slow. And guess what - the 2 parser methods above (convertToXML() and convertBattlePagetoXMLWithoutDOM(), when passed 'is2' instead of 'is' took, in all 4 cases, under 50ms to complete. I read a suggestion that the stream waits for connection to close before unblocking, so i tried using HttpComponentsClient 4.0 (http://hc.apache.org/httpcomponents-client/index.html) instead, but the initial InputStream took just as long to parse. e.g. this code: public InputStream getWebPageAsStream2(int battle_id, int page) throws Exception { String url = "http://api.erepublik.com/v1/feeds/battle_logs/" + battle_id + "/" + page; HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet(url); HttpParams p = new BasicHttpParams(); HttpConnectionParams.setSocketBufferSize(p, 250000); HttpConnectionParams.setStaleCheckingEnabled(p, false); HttpConnectionParams.setConnectionTimeout(p, 5000); httpget.setParams(p); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); l = (int) entity.getContentLength(); return entity.getContent(); } took even longer to process(50ms more for just the network) and the stream parsing times remained the same. Obviously it can be instantiated so as to not create HttpClient and properties every time(faster network time), but the stream issue wont be affected by that. So we come to the center problem - why does the initial URLConnection InputStream(or HttpClient InputStream) take so long to process, while any stream of same size and content created locally is orders of magnitude faster? I mean, the initial response is already somewhere in RAM, and I cant see any good reasong why it is processed so slowly compared to when a same stream is just created from a byte[]. Considering I have to parse million of entries and thousands of pages like that, a total processing time of almost 1.5s/page seems WAY WAY too long. Any ideas? P.S. Please ask in any more code is required - the only thing I do after parsing is make a PreparedStatement and put the entries into JavaDB in packs of 1000+, and the perfomance is ok ~ 200ms/1000entries, prb could be optimized with more cache but I didnt look into it much.

    Read the article

  • Is there a Telecommunications Reference Architecture?

    - by raul.goycoolea
    @font-face { font-family: "Arial"; }@font-face { font-family: "Courier New"; }@font-face { font-family: "Wingdings"; }@font-face { font-family: "Cambria"; }p.MsoNormal, li.MsoNormal, div.MsoNormal { margin: 0cm 0cm 0.0001pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParagraphCxSpFirst { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListParagraphCxSpMiddle { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagraphCxSpLast { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }div.Section1 { page: Section1; }ol { margin-bottom: 0cm; }ul { margin-bottom: 0cm; } Abstract   Reference architecture provides needed architectural information that can be provided in advance to an enterprise to enable consistent architectural best practices. Enterprise Reference Architecture helps business owners to actualize their strategies, vision, objectives, and principles. It evaluates the IT systems, based on Reference Architecture goals, principles, and standards. It helps to reduce IT costs by increasing functionality, availability, scalability, etc. Telecom Reference Architecture provides customers with the flexibility to view bundled service bills online with the provision of multiple services. It provides real-time, flexible billing and charging systems, to handle complex promotions, discounts, and settlements with multiple parties. This paper attempts to describe the Reference Architecture for the Telecom Enterprises. It lays the foundation for a Telecom Reference Architecture by articulating the requirements, drivers, and pitfalls for telecom service providers. It describes generic reference architecture for telecom enterprises and moves on to explain how to achieve Enterprise Reference Architecture by using SOA.   Introduction   A Reference Architecture provides a methodology, set of practices, template, and standards based on a set of successful solutions implemented earlier. These solutions have been generalized and structured for the depiction of both a logical and a physical architecture, based on the harvesting of a set of patterns that describe observations in a number of successful implementations. It helps as a reference for the various architectures that an enterprise can implement to solve various problems. It can be used as the starting point or the point of comparisons for various departments/business entities of a company, or for the various companies for an enterprise. It provides multiple views for multiple stakeholders.   Major artifacts of the Enterprise Reference Architecture are methodologies, standards, metadata, documents, design patterns, etc.   Purpose of Reference Architecture   In most cases, architects spend a lot of time researching, investigating, defining, and re-arguing architectural decisions. It is like reinventing the wheel as their peers in other organizations or even the same organization have already spent a lot of time and effort defining their own architectural practices. This prevents an organization from learning from its own experiences and applying that knowledge for increased effectiveness.   Reference architecture provides missing architectural information that can be provided in advance to project team members to enable consistent architectural best practices.   Enterprise Reference Architecture helps an enterprise to achieve the following at the abstract level:   ·       Reference architecture is more of a communication channel to an enterprise ·       Helps the business owners to accommodate to their strategies, vision, objectives, and principles. ·       Evaluates the IT systems based on Reference Architecture Principles ·       Reduces IT spending through increasing functionality, availability, scalability, etc ·       A Real-time Integration Model helps to reduce the latency of the data updates Is used to define a single source of Information ·       Provides a clear view on how to manage information and security ·       Defines the policy around the data ownership, product boundaries, etc. ·       Helps with cost optimization across project and solution portfolios by eliminating unused or duplicate investments and assets ·       Has a shorter implementation time and cost   Once the reference architecture is in place, the set of architectural principles, standards, reference models, and best practices ensure that the aligned investments have the greatest possible likelihood of success in both the near term and the long term (TCO).     Common pitfalls for Telecom Service Providers   Telecom Reference Architecture serves as the first step towards maturity for a telecom service provider. During the course of our assignments/experiences with telecom players, we have come across the following observations – Some of these indicate a lack of maturity of the telecom service provider:   ·       In markets that are growing and not so mature, it has been observed that telcos have a significant amount of in-house or home-grown applications. In some of these markets, the growth has been so rapid that IT has been unable to cope with business demands. Telcos have shown a tendency to come up with workarounds in their IT applications so as to meet business needs. ·       Even for core functions like provisioning or mediation, some telcos have tried to manage with home-grown applications. ·       Most of the applications do not have the required scalability or maintainability to sustain growth in volumes or functionality. ·       Applications face interoperability issues with other applications in the operator's landscape. Integrating a new application or network element requires considerable effort on the part of the other applications. ·       Application boundaries are not clear, and functionality that is not in the initial scope of that application gets pushed onto it. This results in the development of the multiple, small applications without proper boundaries. ·       Usage of Legacy OSS/BSS systems, poor Integration across Multiple COTS Products and Internal Systems. Most of the Integrations are developed on ad-hoc basis and Point-to-Point Integration. ·       Redundancy of the business functions in different applications • Fragmented data across the different applications and no integrated view of the strategic data • Lot of performance Issues due to the usage of the complex integration across OSS and BSS systems   However, this is where the maturity of the telecom industry as a whole can be of help. The collaborative efforts of telcos to overcome some of these problems have resulted in bodies like the TM Forum. They have come up with frameworks for business processes, data, applications, and technology for telecom service providers. These could be a good starting point for telcos to clean up their enterprise landscape.   Industry Trends in Telecom Reference Architecture   Telecom reference architectures are evolving rapidly because telcos are facing business and IT challenges.   “The reality is that there probably is no killer application, no silver bullet that the telcos can latch onto to carry them into a 21st Century.... Instead, there are probably hundreds – perhaps thousands – of niche applications.... And the only way to find which of these works for you is to try out lots of them, ramp up the ones that work, and discontinue the ones that fail.” – Martin Creaner President & CTO TM Forum.   The following trends have been observed in telecom reference architecture:   ·       Transformation of business structures to align with customer requirements ·       Adoption of more Internet-like technical architectures. The Web 2.0 concept is increasingly being used. ·       Virtualization of the traditional operations support system (OSS) ·       Adoption of SOA to support development of IP-based services ·       Adoption of frameworks like Service Delivery Platforms (SDPs) and IP Multimedia Subsystem ·       (IMS) to enable seamless deployment of various services over fixed and mobile networks ·       Replacement of in-house, customized, and stove-piped OSS/BSS with standards-based COTS products ·       Compliance with industry standards and frameworks like eTOM, SID, and TAM to enable seamless integration with other standards-based products   Drivers of Reference Architecture   The drivers of the Reference Architecture are Reference Architecture Goals, Principles, and Enterprise Vision and Telecom Transformation. The details are depicted below diagram. @font-face { font-family: "Cambria"; }p.MsoNormal, li.MsoNormal, div.MsoNormal { margin: 0cm 0cm 0.0001pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoCaption, li.MsoCaption, div.MsoCaption { margin: 0cm 0cm 10pt; font-size: 9pt; font-family: "Times New Roman"; color: rgb(79, 129, 189); font-weight: bold; }div.Section1 { page: Section1; } Figure 1. Drivers for Reference Architecture @font-face { font-family: "Arial"; }@font-face { font-family: "Courier New"; }@font-face { font-family: "Wingdings"; }@font-face { font-family: "Cambria"; }p.MsoNormal, li.MsoNormal, div.MsoNormal { margin: 0cm 0cm 0.0001pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParagraphCxSpFirst { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListParagraphCxSpMiddle { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagraphCxSpLast { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }div.Section1 { page: Section1; }ol { margin-bottom: 0cm; }ul { margin-bottom: 0cm; } Today’s telecom reference architectures should seamlessly integrate traditional legacy-based applications and transition to next-generation network technologies (e.g., IP multimedia subsystems). This has resulted in new requirements for flexible, real-time billing and OSS/BSS systems and implications on the service provider’s organizational requirements and structure.   Telecom reference architectures are today expected to:   ·       Integrate voice, messaging, email and other VAS over fixed and mobile networks, back end systems ·       Be able to provision multiple services and service bundles • Deliver converged voice, video and data services ·       Leverage the existing Network Infrastructure ·       Provide real-time, flexible billing and charging systems to handle complex promotions, discounts, and settlements with multiple parties. ·       Support charging of advanced data services such as VoIP, On-Demand, Services (e.g.  Video), IMS/SIP Services, Mobile Money, Content Services and IPTV. ·       Help in faster deployment of new services • Serve as an effective platform for collaboration between network IT and business organizations ·       Harness the potential of converging technology, networks, devices and content to develop multimedia services and solutions of ever-increasing sophistication on a single Internet Protocol (IP) ·       Ensure better service delivery and zero revenue leakage through real-time balance and credit management ·       Lower operating costs to drive profitability   Enterprise Reference Architecture   The Enterprise Reference Architecture (RA) fills the gap between the concepts and vocabulary defined by the reference model and the implementation. Reference architecture provides detailed architectural information in a common format such that solutions can be repeatedly designed and deployed in a consistent, high-quality, supportable fashion. This paper attempts to describe the Reference Architecture for the Telecom Application Usage and how to achieve the Enterprise Level Reference Architecture using SOA.   • Telecom Reference Architecture • Enterprise SOA based Reference Architecture   Telecom Reference Architecture   Tele Management Forum’s New Generation Operations Systems and Software (NGOSS) is an architectural framework for organizing, integrating, and implementing telecom systems. NGOSS is a component-based framework consisting of the following elements:   ·       The enhanced Telecom Operations Map (eTOM) is a business process framework. ·       The Shared Information Data (SID) model provides a comprehensive information framework that may be specialized for the needs of a particular organization. ·       The Telecom Application Map (TAM) is an application framework to depict the functional footprint of applications, relative to the horizontal processes within eTOM. ·       The Technology Neutral Architecture (TNA) is an integrated framework. TNA is an architecture that is sustainable through technology changes.   NGOSS Architecture Standards are:   ·       Centralized data ·       Loosely coupled distributed systems ·       Application components/re-use  ·       A technology-neutral system framework with technology specific implementations ·       Interoperability to service provider data/processes ·       Allows more re-use of business components across multiple business scenarios ·       Workflow automation   The traditional operator systems architecture consists of four layers,   ·       Business Support System (BSS) layer, with focus toward customers and business partners. Manages order, subscriber, pricing, rating, and billing information. ·       Operations Support System (OSS) layer, built around product, service, and resource inventories. ·       Networks layer – consists of Network elements and 3rd Party Systems. ·       Integration Layer – to maximize application communication and overall solution flexibility.   Reference architecture for telecom enterprises is depicted below. @font-face { font-family: "Arial"; }@font-face { font-family: "Courier New"; }@font-face { font-family: "Wingdings"; }@font-face { font-family: "Cambria"; }p.MsoNormal, li.MsoNormal, div.MsoNormal { margin: 0cm 0cm 0.0001pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoCaption, li.MsoCaption, div.MsoCaption { margin: 0cm 0cm 10pt; font-size: 9pt; font-family: "Times New Roman"; color: rgb(79, 129, 189); font-weight: bold; }p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParagraphCxSpFirst { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListParagraphCxSpMiddle { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagraphCxSpLast { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }div.Section1 { page: Section1; }ol { margin-bottom: 0cm; }ul { margin-bottom: 0cm; } Figure 2. Telecom Reference Architecture   The major building blocks of any Telecom Service Provider architecture are as follows:   1. Customer Relationship Management   CRM encompasses the end-to-end lifecycle of the customer: customer initiation/acquisition, sales, ordering, and service activation, customer care and support, proactive campaigns, cross sell/up sell, and retention/loyalty.   CRM also includes the collection of customer information and its application to personalize, customize, and integrate delivery of service to a customer, as well as to identify opportunities for increasing the value of the customer to the enterprise.   The key functionalities related to Customer Relationship Management are   ·       Manage the end-to-end lifecycle of a customer request for products. ·       Create and manage customer profiles. ·       Manage all interactions with customers – inquiries, requests, and responses. ·       Provide updates to Billing and other south bound systems on customer/account related updates such as customer/ account creation, deletion, modification, request bills, final bill, duplicate bills, credit limits through Middleware. ·       Work with Order Management System, Product, and Service Management components within CRM. ·       Manage customer preferences – Involve all the touch points and channels to the customer, including contact center, retail stores, dealers, self service, and field service, as well as via any media (phone, face to face, web, mobile device, chat, email, SMS, mail, the customer's bill, etc.). ·       Support single interface for customer contact details, preferences, account details, offers, customer premise equipment, bill details, bill cycle details, and customer interactions.   CRM applications interact with customers through customer touch points like portals, point-of-sale terminals, interactive voice response systems, etc. The requests by customers are sent via fulfillment/provisioning to billing system for ordering processing.   2. Billing and Revenue Management   Billing and Revenue Management handles the collection of appropriate usage records and production of timely and accurate bills – for providing pre-bill usage information and billing to customers; for processing their payments; and for performing payment collections. In addition, it handles customer inquiries about bills, provides billing inquiry status, and is responsible for resolving billing problems to the customer's satisfaction in a timely manner. This process grouping also supports prepayment for services.   The key functionalities provided by these applications are   ·       To ensure that enterprise revenue is billed and invoices delivered appropriately to customers. ·       To manage customers’ billing accounts, process their payments, perform payment collections, and monitor the status of the account balance. ·       To ensure the timely and effective fulfillment of all customer bill inquiries and complaints. ·       Collect the usage records from mediation and ensure appropriate rating and discounting of all usage and pricing. ·       Support revenue sharing; split charging where usage is guided to an account different from the service consumer. ·       Support prepaid and post-paid rating. ·       Send notification on approach / exceeding the usage thresholds as enforced by the subscribed offer, and / or as setup by the customer. ·       Support prepaid, post paid, and hybrid (where some services are prepaid and the rest of the services post paid) customers and conversion from post paid to prepaid, and vice versa. ·       Support different billing function requirements like charge prorating, promotion, discount, adjustment, waiver, write-off, account receivable, GL Interface, late payment fee, credit control, dunning, account or service suspension, re-activation, expiry, termination, contract violation penalty, etc. ·       Initiate direct debit to collect payment against an invoice outstanding. ·       Send notification to Middleware on different events; for example, payment receipt, pre-suspension, threshold exceed, etc.   Billing systems typically get usage data from mediation systems for rating and billing. They get provisioning requests from order management systems and inquiries from CRM systems. Convergent and real-time billing systems can directly get usage details from network elements.   3. Mediation   Mediation systems transform/translate the Raw or Native Usage Data Records into a general format that is acceptable to billing for their rating purposes.   The following lists the high-level roles and responsibilities executed by the Mediation system in the end-to-end solution.   ·       Collect Usage Data Records from different data sources – like network elements, routers, servers – via different protocol and interfaces. ·       Process Usage Data Records – Mediation will process Usage Data Records as per the source format. ·       Validate Usage Data Records from each source. ·       Segregates Usage Data Records coming from each source to multiple, based on the segregation requirement of end Application. ·       Aggregates Usage Data Records based on the aggregation rule if any from different sources. ·       Consolidates multiple Usage Data Records from each source. ·       Delivers formatted Usage Data Records to different end application like Billing, Interconnect, Fraud Management, etc. ·       Generates audit trail for incoming Usage Data Records and keeps track of all the Usage Data Records at various stages of mediation process. ·       Checks duplicate Usage Data Records across files for a given time window.   4. Fulfillment   This area is responsible for providing customers with their requested products in a timely and correct manner. It translates the customer's business or personal need into a solution that can be delivered using the specific products in the enterprise's portfolio. This process informs the customers of the status of their purchase order, and ensures completion on time, as well as ensuring a delighted customer. These processes are responsible for accepting and issuing orders. They deal with pre-order feasibility determination, credit authorization, order issuance, order status and tracking, customer update on customer order activities, and customer notification on order completion. Order management and provisioning applications fall into this category.   The key functionalities provided by these applications are   ·       Issuing new customer orders, modifying open customer orders, or canceling open customer orders; ·       Verifying whether specific non-standard offerings sought by customers are feasible and supportable; ·       Checking the credit worthiness of customers as part of the customer order process; ·       Testing the completed offering to ensure it is working correctly; ·       Updating of the Customer Inventory Database to reflect that the specific product offering has been allocated, modified, or cancelled; ·       Assigning and tracking customer provisioning activities; ·       Managing customer provisioning jeopardy conditions; and ·       Reporting progress on customer orders and other processes to customer.   These applications typically get orders from CRM systems. They interact with network elements and billing systems for fulfillment of orders.   5. Enterprise Management   This process area includes those processes that manage enterprise-wide activities and needs, or have application within the enterprise as a whole. They encompass all business management processes that   ·       Are necessary to support the whole of the enterprise, including processes for financial management, legal management, regulatory management, process, cost, and quality management, etc.;   ·       Are responsible for setting corporate policies, strategies, and directions, and for providing guidelines and targets for the whole of the business, including strategy development and planning for areas, such as Enterprise Architecture, that are integral to the direction and development of the business;   ·       Occur throughout the enterprise, including processes for project management, performance assessments, cost assessments, etc.     (i) Enterprise Risk Management:   Enterprise Risk Management focuses on assuring that risks and threats to the enterprise value and/or reputation are identified, and appropriate controls are in place to minimize or eliminate the identified risks. The identified risks may be physical or logical/virtual. Successful risk management ensures that the enterprise can support its mission critical operations, processes, applications, and communications in the face of serious incidents such as security threats/violations and fraud attempts. Two key areas covered in Risk Management by telecom operators are:   ·       Revenue Assurance: Revenue assurance system will be responsible for identifying revenue loss scenarios across components/systems, and will help in rectifying the problems. The following lists the high-level roles and responsibilities executed by the Revenue Assurance system in the end-to-end solution. o   Identify all usage information dropped when networks are being upgraded. o   Interconnect bill verification. o   Identify where services are routinely provisioned but never billed. o   Identify poor sales policies that are intensifying collections problems. o   Find leakage where usage is sent to error bucket and never billed for. o   Find leakage where field service, CRM, and network build-out are not optimized.   ·       Fraud Management: Involves collecting data from different systems to identify abnormalities in traffic patterns, usage patterns, and subscription patterns to report suspicious activity that might suggest fraudulent usage of resources, resulting in revenue losses to the operator.   The key roles and responsibilities of the system component are as follows:   o   Fraud management system will capture and monitor high usage (over a certain threshold) in terms of duration, value, and number of calls for each subscriber. The threshold for each subscriber is decided by the system and fixed automatically. o   Fraud management will be able to detect the unauthorized access to services for certain subscribers. These subscribers may have been provided unauthorized services by employees. The component will raise the alert to the operator the very first time of such illegal calls or calls which are not billed. o   The solution will be to have an alarm management system that will deliver alarms to the operator/provider whenever it detects a fraud, thus minimizing fraud by catching it the first time it occurs. o   The Fraud Management system will be capable of interfacing with switches, mediation systems, and billing systems   (ii) Knowledge Management   This process focuses on knowledge management, technology research within the enterprise, and the evaluation of potential technology acquisitions.   Key responsibilities of knowledge base management are to   ·       Maintain knowledge base – Creation and updating of knowledge base on ongoing basis. ·       Search knowledge base – Search of knowledge base on keywords or category browse ·       Maintain metadata – Management of metadata on knowledge base to ensure effective management and search. ·       Run report generator. ·       Provide content – Add content to the knowledge base, e.g., user guides, operational manual, etc.   (iii) Document Management   It focuses on maintaining a repository of all electronic documents or images of paper documents relevant to the enterprise using a system.   (iv) Data Management   It manages data as a valuable resource for any enterprise. For telecom enterprises, the typical areas covered are Master Data Management, Data Warehousing, and Business Intelligence. It is also responsible for data governance, security, quality, and database management.   Key responsibilities of Data Management are   ·       Using ETL, extract the data from CRM, Billing, web content, ERP, campaign management, financial, network operations, asset management info, customer contact data, customer measures, benchmarks, process data, e.g., process inputs, outputs, and measures, into Enterprise Data Warehouse. ·       Management of data traceability with source, data related business rules/decisions, data quality, data cleansing data reconciliation, competitors data – storage for all the enterprise data (customer profiles, products, offers, revenues, etc.) ·       Get online update through night time replication or physical backup process at regular frequency. ·       Provide the data access to business intelligence and other systems for their analysis, report generation, and use.   (v) Business Intelligence   It uses the Enterprise Data to provide the various analysis and reports that contain prospects and analytics for customer retention, acquisition of new customers due to the offers, and SLAs. It will generate right and optimized plans – bolt-ons for the customers.   The following lists the high-level roles and responsibilities executed by the Business Intelligence system at the Enterprise Level:   ·       It will do Pattern analysis and reports problem. ·       It will do Data Analysis – Statistical analysis, data profiling, affinity analysis of data, customer segment wise usage patterns on offers, products, service and revenue generation against services and customer segments. ·       It will do Performance (business, system, and forecast) analysis, churn propensity, response time, and SLAs analysis. ·       It will support for online and offline analysis, and report drill down capability. ·       It will collect, store, and report various SLA data. ·       It will provide the necessary intelligence for marketing and working on campaigns, etc., with cost benefit analysis and predictions.   It will advise on customer promotions with additional services based on loyalty and credit history of customer   ·       It will Interface with Enterprise Data Management system for data to run reports and analysis tasks. It will interface with the campaign schedules, based on historical success evidence.   (vi) Stakeholder and External Relations Management   It manages the enterprise's relationship with stakeholders and outside entities. Stakeholders include shareholders, employee organizations, etc. Outside entities include regulators, local community, and unions. Some of the processes within this grouping are Shareholder Relations, External Affairs, Labor Relations, and Public Relations.   (vii) Enterprise Resource Planning   It is used to manage internal and external resources, including tangible assets, financial resources, materials, and human resources. Its purpose is to facilitate the flow of information between all business functions inside the boundaries of the enterprise and manage the connections to outside stakeholders. ERP systems consolidate all business operations into a uniform and enterprise wide system environment.   The key roles and responsibilities for Enterprise System are given below:   ·        It will handle responsibilities such as core accounting, financial, and management reporting. ·       It will interface with CRM for capturing customer account and details. ·       It will interface with billing to capture the billing revenue and other financial data. ·       It will be responsible for executing the dunning process. Billing will send the required feed to ERP for execution of dunning. ·       It will interface with the CRM and Billing through batch interfaces. Enterprise management systems are like horizontals in the enterprise and typically interact with all major telecom systems. E.g., an ERP system interacts with CRM, Fulfillment, and Billing systems for different kinds of data exchanges.   6. External Interfaces/Touch Points   The typical external parties are customers, suppliers/partners, employees, shareholders, and other stakeholders. External interactions from/to a Service Provider to other parties can be achieved by a variety of mechanisms, including:   ·       Exchange of emails or faxes ·       Call Centers ·       Web Portals ·       Business-to-Business (B2B) automated transactions   These applications provide an Internet technology driven interface to external parties to undertake a variety of business functions directly for themselves. These can provide fully or partially automated service to external parties through various touch points.   Typical characteristics of these touch points are   ·       Pre-integrated self-service system, including stand-alone web framework or integration front end with a portal engine ·       Self services layer exposing atomic web services/APIs for reuse by multiple systems across the architectural environment ·       Portlets driven connectivity exposing data and services interoperability through a portal engine or web application   These touch points mostly interact with the CRM systems for requests, inquiries, and responses.   7. Middleware   The component will be primarily responsible for integrating the different systems components under a common platform. It should provide a Standards-Based Platform for building Service Oriented Architecture and Composite Applications. The following lists the high-level roles and responsibilities executed by the Middleware component in the end-to-end solution.   ·       As an integration framework, covering to and fro interfaces ·       Provide a web service framework with service registry. ·       Support SOA framework with SOA service registry. ·       Each of the interfaces from / to Middleware to other components would handle data transformation, translation, and mapping of data points. ·       Receive data from the caller / activate and/or forward the data to the recipient system in XML format. ·       Use standard XML for data exchange. ·       Provide the response back to the service/call initiator. ·       Provide a tracking until the response completion. ·       Keep a store transitional data against each call/transaction. ·       Interface through Middleware to get any information that is possible and allowed from the existing systems to enterprise systems; e.g., customer profile and customer history, etc. ·       Provide the data in a common unified format to the SOA calls across systems, and follow the Enterprise Architecture directive. ·       Provide an audit trail for all transactions being handled by the component.   8. Network Elements   The term Network Element means a facility or equipment used in the provision of a telecommunications service. Such terms also includes features, functions, and capabilities that are provided by means of such facility or equipment, including subscriber numbers, databases, signaling systems, and information sufficient for billing and collection or used in the transmission, routing, or other provision of a telecommunications service.   Typical network elements in a GSM network are Home Location Register (HLR), Intelligent Network (IN), Mobile Switching Center (MSC), SMS Center (SMSC), and network elements for other value added services like Push-to-talk (PTT), Ring Back Tone (RBT), etc.   Network elements are invoked when subscribers use their telecom devices for any kind of usage. These elements generate usage data and pass it on to downstream systems like mediation and billing system for rating and billing. They also integrate with provisioning systems for order/service fulfillment.   9. 3rd Party Applications   3rd Party systems are applications like content providers, payment gateways, point of sale terminals, and databases/applications maintained by the Government.   Depending on applicability and the type of functionality provided by 3rd party applications, the integration with different telecom systems like CRM, provisioning, and billing will be done.   10. Service Delivery Platform   A service delivery platform (SDP) provides the architecture for the rapid deployment, provisioning, execution, management, and billing of value added telecom services. SDPs are based on the concept of SOA and layered architecture. They support the delivery of voice, data services, and content in network and device-independent fashion. They allow application developers to aggregate network capabilities, services, and sources of content. SDPs typically contain layers for web services exposure, service application development, and network abstraction.   SOA Reference Architecture   SOA concept is based on the principle of developing reusable business service and building applications by composing those services, instead of building monolithic applications in silos. It’s about bridging the gap between business and IT through a set of business-aligned IT services, using a set of design principles, patterns, and techniques.   In an SOA, resources are made available to participants in a value net, enterprise, line of business (typically spanning multiple applications within an enterprise or across multiple enterprises). It consists of a set of business-aligned IT services that collectively fulfill an organization’s business processes and goals. We can choreograph these services into composite applications and invoke them through standard protocols. SOA, apart from agility and reusability, enables:   ·       The business to specify processes as orchestrations of reusable services ·       Technology agnostic business design, with technology hidden behind service interface ·       A contractual-like interaction between business and IT, based on service SLAs ·       Accountability and governance, better aligned to business services ·       Applications interconnections untangling by allowing access only through service interfaces, reducing the daunting side effects of change ·       Reduced pressure to replace legacy and extended lifetime for legacy applications, through encapsulation in services   ·       A Cloud Computing paradigm, using web services technologies, that makes possible service outsourcing on an on-demand, utility-like, pay-per-usage basis   The following section represents the Reference Architecture of logical view for the Telecom Solution. The new custom built application needs to align with this logical architecture in the long run to achieve EA benefits.   Packaged implementation applications, such as ERP billing applications, need to expose their functions as service providers (as other applications consume) and interact with other applications as service consumers.   COT applications need to expose services through wrappers such as adapters to utilize existing resources and at the same time achieve Enterprise Architecture goal and objectives.   The following are the various layers for Enterprise level deployment of SOA. This diagram captures the abstract view of Enterprise SOA layers and important components of each layer. Layered architecture means decomposition of services such that most interactions occur between adjacent layers. However, there is no strict rule that top layers should not directly communicate with bottom layers.   The diagram below represents the important logical pieces that would result from overall SOA transformation. @font-face { font-family: "Arial"; }@font-face { font-family: "Courier New"; }@font-face { font-family: "Wingdings"; }@font-face { font-family: "Cambria"; }p.MsoNormal, li.MsoNormal, div.MsoNormal { margin: 0cm 0cm 0.0001pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoCaption, li.MsoCaption, div.MsoCaption { margin: 0cm 0cm 10pt; font-size: 9pt; font-family: "Times New Roman"; color: rgb(79, 129, 189); font-weight: bold; }p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParagraphCxSpFirst { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListParagraphCxSpMiddle { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagraphCxSpLast { margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: "Times New Roman"; }div.Section1 { page: Section1; }ol { margin-bottom: 0cm; }ul { margin-bottom: 0cm; } Figure 3. Enterprise SOA Reference Architecture 1.          Operational System Layer: This layer consists of all packaged applications like CRM, ERP, custom built applications, COTS based applications like Billing, Revenue Management, Fulfilment, and the Enterprise databases that are essential and contribute directly or indirectly to the Enterprise OSS/BSS Transformation.   ERP holds the data of Asset Lifecycle Management, Supply Chain, and Advanced Procurement and Human Capital Management, etc.   CRM holds the data related to Order, Sales, and Marketing, Customer Care, Partner Relationship Management, Loyalty, etc.   Content Management handles Enterprise Search and Query. Billing application consists of the following components:   ·       Collections Management, Customer Billing Management, Invoices, Real-Time Rating, Discounting, and Applying of Charges ·       Enterprise databases will hold both the application and service data, whether structured or unstructured.   MDM - Master data majorly consists of Customer, Order, Product, and Service Data.     2.          Enterprise Component Layer:   This layer consists of the Application Services and Common Services that are responsible for realizing the functionality and maintaining the QoS of the exposed services. This layer uses container-based technologies such as application servers to implement the components, workload management, high availability, and load balancing.   Application Services: This Service Layer enables application, technology, and database abstraction so that the complex accessing logic is hidden from the other service layers. This is a basic service layer, which exposes application functionalities and data as reusable services. The three types of the Application access services are:   ·       Application Access Service: This Service Layer exposes application level functionalities as a reusable service between BSS to BSS and BSS to OSS integration. This layer is enabled using disparate technology such as Web Service, Integration Servers, and Adaptors, etc.   ·       Data Access Service: This Service Layer exposes application data services as a reusable reference data service. This is done via direct interaction with application data. and provides the federated query.   ·       Network Access Service: This Service Layer exposes provisioning layer as a reusable service from OSS to OSS integration. This integration service emphasizes the need for high performance, stateless process flows, and distributed design.   Common Services encompasses management of structured, semi-structured, and unstructured data such as information services, portal services, interaction services, infrastructure services, and security services, etc.   3.          Integration Layer:   This consists of service infrastructure components like service bus, service gateway for partner integration, service registry, service repository, and BPEL processor. Service bus will carry the service invocation payloads/messages between consumers and providers. The other important functions expected from it are itinerary based routing, distributed caching of routing information, transformations, and all qualities of service for messaging-like reliability, scalability, and availability, etc. Service registry will hold all contracts (wsdl) of services, and it helps developers to locate or discover service during design time or runtime.   • BPEL processor would be useful in orchestrating the services to compose a complex business scenario or process. • Workflow and business rules management are also required to support manual triggering of certain activities within business process. based on the rules setup and also the state machine information. Application, data, and service mediation layer typically forms the overall composite application development framework or SOA Framework.   4.          Business Process Layer: These are typically the intermediate services layer and represent Shared Business Process Services. At Enterprise Level, these services are from Customer Management, Order Management, Billing, Finance, and Asset Management application domains.   5.          Access Layer: This layer consists of portals for Enterprise and provides a single view of Enterprise information management and dashboard services.   6.          Channel Layer: This consists of various devices; applications that form part of extended enterprise; browsers through which users access the applications.   7.          Client Layer: This designates the different types of users accessing the enterprise applications. The type of user typically would be an important factor in determining the level of access to applications.   8.          Vertical pieces like management, monitoring, security, and development cut across all horizontal layers Management and monitoring involves all aspects of SOA-like services, SLAs, and other QoS lifecycle processes for both applications and services surrounding SOA governance.     9.          EA Governance, Reference Architecture, Roadmap, Principles, and Best Practices:   EA Governance is important in terms of providing the overall direction to SOA implementation within the enterprise. This involves board-level involvement, in addition to business and IT executives. At a high level, this involves managing the SOA projects implementation, managing SOA infrastructure, and controlling the entire effort through all fine-tuned IT processes in accordance with COBIT (Control Objectives for Information Technology).   Devising tools and techniques to promote reuse culture, and the SOA way of doing things needs competency centers to be established in addition to training the workforce to take up new roles that are suited to SOA journey.   Conclusions   Reference Architectures can serve as the basis for disparate architecture efforts throughout the organization, even if they use different tools and technologies. Reference architectures provide best practices and approaches in the independent way a vendor deals with technology and standards. Reference Architectures model the abstract architectural elements for an enterprise independent of the technologies, protocols, and products that are used to implement an SOA. Telecom enterprises today are facing significant business and technology challenges due to growing competition, a multitude of services, and convergence. Adopting architectural best practices could go a long way in meeting these challenges. The use of SOA-based architecture for communication to each of the external systems like Billing, CRM, etc., in OSS/BSS system has made the architecture very loosely coupled, with greater flexibility. Any change in the external systems would be absorbed at the Integration Layer without affecting the rest of the ecosystem. The use of a Business Process Management (BPM) tool makes the management and maintenance of the business processes easy, with better performance in terms of lead time, quality, and cost. Since the Architecture is based on standards, it will lower the cost of deploying and managing OSS/BSS applications over their lifecycles.

    Read the article

  • WMI Remote Process Starting

    - by Goober
    Scenario I've written a WMI Wrapper that seems to be quite sufficient, however whenever I run the code to start a remote process on a server, I see the process name appear in the task manager but the process itself does not start like it should (as in, I don't see the command line log window of the process that prints out what it's doing etc.) The process I am trying to start is just a C# application executable that I have written. Below is my WMI Wrapper Code and the code I am using to start running the process. Question Is the process actually running? - Even if it is only displaying the process name in the task manager and not actually launching the application to the users window? Code To Start The Process IPHostEntry hostEntry = Dns.GetHostEntry("InsertServerName"); WMIWrapper wrapper = new WMIWrapper("Insert User Name", "Insert Password", hostEntry.HostName); List<Process> processes = wrapper.GetProcesses(); foreach (Process process in processes) { if (process.Caption.Equals("MyAppName.exe")) { Console.WriteLine(process.Caption); Console.WriteLine(process.CommandLine); int processId; wrapper.StartProcess("E:\\MyData\\Data\\MyAppName.exe", out processId); Console.WriteLine(processId.ToString()); } } Console.ReadLine(); WMI Wrapper Code using System; using System.Collections.Generic; using System.Management; using System.Runtime.InteropServices; using Common.WMI.Objects; using System.Net; namespace Common.WMIWrapper { public class WMIWrapper : IDisposable { #region Constructor /// <summary> /// Creates a new instance of the wrapper /// </summary> /// <param jobName="username"></param> /// <param jobName="password"></param> /// <param jobName="server"></param> public WMIWrapper(string server) { Initialise(server); } /// <summary> /// Creates a new instance of the wrapper /// </summary> /// <param jobName="username"></param> /// <param jobName="password"></param> /// <param jobName="server"></param> public WMIWrapper(string username, string password, string server) { Initialise(username, password, server); } #endregion #region Destructor /// <summary> /// Clean up unmanaged references /// </summary> ~WMIWrapper() { Dispose(false); } #endregion #region Initialise /// <summary> /// Initialise the WMI Connection (local machine) /// </summary> /// <param name="server"></param> private void Initialise(string server) { m_server = server; // set connection options m_connectOptions = new ConnectionOptions(); IPHostEntry host = Dns.GetHostEntry(Environment.MachineName); } /// <summary> /// Initialise the WMI connection /// </summary> /// <param jobName="username">Username to connect to server with</param> /// <param jobName="password">Password to connect to server with</param> /// <param jobName="server">Server to connect to</param> private void Initialise(string username, string password, string server) { m_server = server; // set connection options m_connectOptions = new ConnectionOptions(); IPHostEntry host = Dns.GetHostEntry(Environment.MachineName); if (host.HostName.Equals(server, StringComparison.OrdinalIgnoreCase)) return; m_connectOptions.Username = username; m_connectOptions.Password = password; m_connectOptions.Impersonation = ImpersonationLevel.Impersonate; m_connectOptions.EnablePrivileges = true; } #endregion /// <summary> /// Return a list of available wmi namespaces /// </summary> /// <returns></returns> public List<String> GetWMINamespaces() { ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root", this.Server), this.ConnectionOptions); List<String> wmiNamespaceList = new List<String>(); ManagementClass wmiNamespaces = new ManagementClass(wmiScope, new ManagementPath("__namespace"), null); ; foreach (ManagementObject ns in wmiNamespaces.GetInstances()) wmiNamespaceList.Add(ns["Name"].ToString()); return wmiNamespaceList; } /// <summary> /// Return a list of available classes in a namespace /// </summary> /// <param jobName="wmiNameSpace">Namespace to get wmi classes for</param> /// <returns>List of classes in the requested namespace</returns> public List<String> GetWMIClassList(string wmiNameSpace) { ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, wmiNameSpace), this.ConnectionOptions); List<String> wmiClasses = new List<String>(); ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery("SELECT * FROM meta_Class"), null); foreach (ManagementClass wmiClass in wmiSearcher.Get()) wmiClasses.Add(wmiClass["__CLASS"].ToString()); return wmiClasses; } /// <summary> /// Get a list of wmi properties for the specified class /// </summary> /// <param jobName="wmiNameSpace">WMI Namespace</param> /// <param jobName="wmiClass">WMI Class</param> /// <returns>List of properties for the class</returns> public List<String> GetWMIClassPropertyList(string wmiNameSpace, string wmiClass) { List<String> wmiClassProperties = new List<string>(); ManagementClass managementClass = GetWMIClass(wmiNameSpace, wmiClass); foreach (PropertyData property in managementClass.Properties) wmiClassProperties.Add(property.Name); return wmiClassProperties; } /// <summary> /// Returns a list of methods for the class /// </summary> /// <param jobName="wmiNameSpace"></param> /// <param jobName="wmiClass"></param> /// <returns></returns> public List<String> GetWMIClassMethodList(string wmiNameSpace, string wmiClass) { List<String> wmiClassMethods = new List<string>(); ManagementClass managementClass = GetWMIClass(wmiNameSpace, wmiClass); foreach (MethodData method in managementClass.Methods) wmiClassMethods.Add(method.Name); return wmiClassMethods; } /// <summary> /// Retrieve the specified management class /// </summary> /// <param jobName="wmiNameSpace">Namespace of the class</param> /// <param jobName="wmiClass">Type of the class</param> /// <returns></returns> public ManagementClass GetWMIClass(string wmiNameSpace, string wmiClass) { ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, wmiNameSpace), this.ConnectionOptions); ManagementClass managementClass = null; ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery(String.Format("SELECT * FROM meta_Class WHERE __CLASS = '{0}'", wmiClass)), null); foreach (ManagementClass wmiObject in wmiSearcher.Get()) managementClass = wmiObject; return managementClass; } /// <summary> /// Get an instance of the specficied class /// </summary> /// <param jobName="wmiNameSpace">Namespace of the classes</param> /// <param jobName="wmiClass">Type of the classes</param> /// <returns>Array of management classes</returns> public ManagementObject[] GetWMIClassObjects(string wmiNameSpace, string wmiClass) { ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, wmiNameSpace), this.ConnectionOptions); List<ManagementObject> wmiClasses = new List<ManagementObject>(); ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery(String.Format("SELECT * FROM {0}", wmiClass)), null); foreach (ManagementObject wmiObject in wmiSearcher.Get()) wmiClasses.Add(wmiObject); return wmiClasses.ToArray(); } /// <summary> /// Get a full list of services /// </summary> /// <returns></returns> public List<Service> GetServices() { return GetService(null); } /// <summary> /// Get a list of services /// </summary> /// <returns></returns> public List<Service> GetService(string name) { ManagementObject[] services = GetWMIClassObjects("CIMV2", "WIN32_Service"); List<Service> serviceList = new List<Service>(); for (int i = 0; i < services.Length; i++) { ManagementObject managementObject = services[i]; Service service = new Service(managementObject); service.Status = (string)managementObject["Status"]; service.Name = (string)managementObject["Name"]; service.DisplayName = (string)managementObject["DisplayName"]; service.PathName = (string)managementObject["PathName"]; service.ProcessId = (uint)managementObject["ProcessId"]; service.Started = (bool)managementObject["Started"]; service.StartMode = (string)managementObject["StartMode"]; service.ServiceType = (string)managementObject["ServiceType"]; service.InstallDate = (string)managementObject["InstallDate"]; service.Description = (string)managementObject["Description"]; service.Caption = (string)managementObject["Caption"]; if (String.IsNullOrEmpty(name) || name.Equals(service.Name, StringComparison.OrdinalIgnoreCase)) serviceList.Add(service); } return serviceList; } /// <summary> /// Get a list of processes /// </summary> /// <returns></returns> public List<Process> GetProcesses() { return GetProcess(null); } /// <summary> /// Get a list of processes /// </summary> /// <returns></returns> public List<Process> GetProcess(uint? processId) { ManagementObject[] processes = GetWMIClassObjects("CIMV2", "WIN32_Process"); List<Process> processList = new List<Process>(); for (int i = 0; i < processes.Length; i++) { ManagementObject managementObject = processes[i]; Process process = new Process(managementObject); process.Priority = (uint)managementObject["Priority"]; process.ProcessId = (uint)managementObject["ProcessId"]; process.Status = (string)managementObject["Status"]; DateTime createDate; if (ConvertFromWmiDate((string)managementObject["CreationDate"], out createDate)) process.CreationDate = createDate.ToString("dd-MMM-yyyy HH:mm:ss"); process.Caption = (string)managementObject["Caption"]; process.CommandLine = (string)managementObject["CommandLine"]; process.Description = (string)managementObject["Description"]; process.ExecutablePath = (string)managementObject["ExecutablePath"]; process.ExecutionState = (string)managementObject["ExecutionState"]; process.MaximumWorkingSetSize = (UInt32?)managementObject ["MaximumWorkingSetSize"]; process.MinimumWorkingSetSize = (UInt32?)managementObject["MinimumWorkingSetSize"]; process.KernelModeTime = (UInt64)managementObject["KernelModeTime"]; process.ThreadCount = (UInt32)managementObject["ThreadCount"]; process.UserModeTime = (UInt64)managementObject["UserModeTime"]; process.VirtualSize = (UInt64)managementObject["VirtualSize"]; process.WorkingSetSize = (UInt64)managementObject["WorkingSetSize"]; if (processId == null || process.ProcessId == processId.Value) processList.Add(process); } return processList; } /// <summary> /// Start the specified process /// </summary> /// <param jobName="commandLine"></param> /// <returns></returns> public bool StartProcess(string command, out int processId) { processId = int.MaxValue; ManagementClass processClass = GetWMIClass("CIMV2", "WIN32_Process"); object[] objectsIn = new object[4]; objectsIn[0] = command; processClass.InvokeMethod("Create", objectsIn); if (objectsIn[3] == null) return false; processId = int.Parse(objectsIn[3].ToString()); return true; } /// <summary> /// Schedule a process on the remote machine /// </summary> /// <param name="command"></param> /// <param name="scheduleTime"></param> /// <param name="jobName"></param> /// <returns></returns> public bool ScheduleProcess(string command, DateTime scheduleTime, out string jobName) { jobName = String.Empty; ManagementClass scheduleClass = GetWMIClass("CIMV2", "Win32_ScheduledJob"); object[] objectsIn = new object[7]; objectsIn[0] = command; objectsIn[1] = String.Format("********{0:00}{1:00}{2:00}.000000+060", scheduleTime.Hour, scheduleTime.Minute, scheduleTime.Second); objectsIn[5] = true; scheduleClass.InvokeMethod("Create", objectsIn); if (objectsIn[6] == null) return false; UInt32 scheduleid = (uint)objectsIn[6]; jobName = scheduleid.ToString(); return true; } /// <summary> /// Returns the current time on the remote server /// </summary> /// <returns></returns> public DateTime Now() { ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, "CIMV2"), this.ConnectionOptions); ManagementClass managementClass = null; ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery(String.Format("SELECT * FROM Win32_LocalTime")), null); DateTime localTime = DateTime.MinValue; foreach (ManagementObject time in wmiSearcher.Get()) { UInt32 day = (UInt32)time["Day"]; UInt32 month = (UInt32)time["Month"]; UInt32 year = (UInt32)time["Year"]; UInt32 hour = (UInt32)time["Hour"]; UInt32 minute = (UInt32)time["Minute"]; UInt32 second = (UInt32)time["Second"]; localTime = new DateTime((int)year, (int)month, (int)day, (int)hour, (int)minute, (int)second); }; return localTime; } /// <summary> /// Converts a wmi date into a proper date /// </summary> /// <param jobName="wmiDate">Wmi formatted date</param> /// <returns>Date time object</returns> private static bool ConvertFromWmiDate(string wmiDate, out DateTime properDate) { properDate = DateTime.MinValue; string properDateString; // check if string is populated if (String.IsNullOrEmpty(wmiDate)) return false; wmiDate = wmiDate.Trim().ToLower().Replace("*", "0"); string[] months = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; try { properDateString = String.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}", wmiDate.Substring(6, 2), months[int.Parse(wmiDate.Substring(4, 2)) - 1], wmiDate.Substring(0, 4), wmiDate.Substring(8, 2), wmiDate.Substring(10, 2), wmiDate.Substring(12, 2), wmiDate.Substring(15, 6)); } catch (InvalidCastException) { return false; } catch (ArgumentOutOfRangeException) { return false; } // try and parse the new date if (!DateTime.TryParse(properDateString, out properDate)) return false; // true if conversion successful return true; } private bool m_disposed; #region IDisposable Members /// <summary> /// Managed dispose /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Dispose of managed and unmanaged objects /// </summary> /// <param jobName="disposing"></param> public void Dispose(bool disposing) { if (disposing) { m_connectOptions = null; } } #endregion #region Properties private ConnectionOptions m_connectOptions; /// <summary> /// Gets or sets the management scope /// </summary> private ConnectionOptions ConnectionOptions { get { return m_connectOptions; } set { m_connectOptions = value; } } private String m_server; /// <summary> /// Gets or sets the server to connect to /// </summary> public String Server { get { return m_server; } set { m_server = value; } } #endregion } }

    Read the article

  • Sensible Way to Pass Web Data in XML to a SQL Server Database

    - by Emtucifor
    After exploring several different ways to pass web data to a database for update purposes, I'm wondering if XML might be a good strategy. The database is currently SQL 2000. In a few months it will move to SQL 2005 and I will be able to change things if needed, but I need a SQL 2000 solution now. First of all, the database in question uses the EAV model. I know that this kind of database is generally highly frowned on, so for the purposes of this question, please just accept that this is not going to change. The current update method has the web server inserting values (that have all been converted first to their correct underlying types, then to sql_variant) to a temp table. A stored procedure is then run which expects the temp table to exist and it takes care of updating, inserting, or deleting things as needed. So far, only a single element has needed to be updated at a time. But now, there is a requirement to be able to edit multiple elements at once, and also to support hierarchical elements, each of which can have its own list of attributes. Here's some example XML I hand-typed to demonstrate what I'm thinking of. Note that in this database the Entity is Element and an ID of 0 signifies "create" aka an insert of a new item. <Elements> <Element ID="1234"> <Attr ID="221">Value</Attr> <Attr ID="225">287</Attr> <Attr ID="234"> <Element ID="99825"> <Attr ID="7">Value1</Attr> <Attr ID="8">Value2</Attr> <Attr ID="9" Action="delete" /> </Element> <Element ID="99826" Action="delete" /> <Element ID="0" Type="24"> <Attr ID="7">Value4</Attr> <Attr ID="8">Value5</Attr> <Attr ID="9">Value6</Attr> </Element> <Element ID="0" Type="24"> <Attr ID="7">Value7</Attr> <Attr ID="8">Value8</Attr> <Attr ID="9">Value9</Attr> </Element> </Attr> <Rel ID="3827" Action="delete" /> <Rel ID="2284" Role="parent"> <Element ID="3827" /> <Element ID="3829" /> <Attr ID="665">1</Attr> </Rel> <Rel ID="0" Type="23" Role="child"> <Element ID="3830" /> <Attr ID="67" </Rel> </Element> <Element ID="0" Type="87"> <Attr ID="221">Value</Attr> <Attr ID="225">569</Attr> <Attr ID="234"> <Element ID="0" Type="24"> <Attr ID="7">Value10</Attr> <Attr ID="8">Value11</Attr> <Attr ID="9">Value12</Attr> </Element> </Attr> </Element> <Element ID="1235" Action="delete" /> </Elements> Some Attributes are straight value types, such as AttrID 221. But AttrID 234 is a special "multi-value" type that can have a list of elements underneath it, and each one can have one or more values. Types only need to be presented when a new item is created, since the ElementID fully implies the type if it already exists. I'll probably support only passing in changed items (as detected by javascript). And there may be an Action="Delete" on Attr elements as well, since NULLs are treated as "unselected"--sometimes it's very important to know if a Yes/No question has intentionally been answered No or if no one's bothered to say Yes yet. There is also a different kind of data, a Relationship. At this time, those are updated through individual AJAX calls as things are edited in the UI, but I'd like to include those so that changes to relationships can be canceled (right now, once you change it, it's done). So those are really elements, too, but they are called Rel instead of Element. Relationships are implemented as ElementID1 and ElementID2, so the RelID 2284 in the XML above is in the database as: ElementID 2284 ElementID1 1234 ElementID2 3827 Having multiple children in one relationship isn't currently supported, but it would be nice later. Does this strategy and the example XML make sense? Is there a more sensible way? I'm just looking for some broad critique to help save me from going down a bad path. Any aspect that you'd like to comment on would be helpful. The web language happens to be Classic ASP, but that could change to ASP.Net at some point. A persistence engine like Linq or nHibernate is probably not acceptable right now--I just want to get this already working application enhanced without a huge amount of development time. I'll choose the answer that shows experience and has a balance of good warnings about what not to do, confirmations of what I'm planning to do, and recommendations about something else to do. I'll make it as objective as possible. P.S. I'd like to handle unicode characters as well as very long strings (10k +). UPDATE I have had this working for some time and I used the ADO Recordset Save-To-Stream trick to make creating the XML really easy. The result seems to be fairly fast, though if speed ever becomes a problem I may revisit this. In the meantime, my code works to handle any number of elements and attributes on the page at once, including updating, deleting, and creating new items all in one go. I settled on a scheme like so for all my elements: Existing data elements Example: input name e12345_a678 (element 12345, attribute 678), the input value is the value of the attribute. New elements Javascript copies a hidden template of the set of HTML elements needed for the type into the correct location on the page, increments a counter to get a new ID for this item, and prepends the number to the names of the form items. var newid = 0; function metadataAdd(reference, nameid, value) { var t = document.createElement('input'); t.setAttribute('name', nameid); t.setAttribute('id', nameid); t.setAttribute('type', 'hidden'); t.setAttribute('value', value); reference.appendChild(t); } function multiAdd(target, parentelementid, attrid, elementtypeid) { var proto = document.getElementById('a' + attrid + '_proto'); var instance = document.createElement('p'); target.parentNode.parentNode.insertBefore(instance, target.parentNode); var thisid = ++newid; instance.innerHTML = proto.innerHTML.replace(/{prefix}/g, 'n' + thisid + '_'); instance.id = 'n' + thisid; instance.className += ' new'; metadataAdd(instance, 'n' + thisid + '_p', parentelementid); metadataAdd(instance, 'n' + thisid + '_c', attrid); metadataAdd(instance, 'n' + thisid + '_t', elementtypeid); return false; } Example: Template input name _a678 becomes n1_a678 (a new element, the first one on the page, attribute 678). all attributes of this new element are tagged with the same prefix of n1. The next new item will be n2, and so on. Some hidden form inputs are created: n1_t, value is the elementtype of the element to be created n1_p, value is the parent id of the element (if it is a relationship) n1_c, value is the child id of the element (if it is a relationship) Deleting elements A hidden input is created in the form e12345_t with value set to 0. The existing controls displaying that attribute's values are disabled so they are not included in the form post. So "set type to 0" is treated as delete. With this scheme, every item on the page has a unique name and can be distinguished properly, and every action can be represented properly. When the form is posted, here's a sample of building one of the two recordsets used (classic ASP code): Set Data = Server.CreateObject("ADODB.Recordset") Data.Fields.Append "ElementID", adInteger, 4, adFldKeyColumn Data.Fields.Append "AttrID", adInteger, 4, adFldKeyColumn Data.Fields.Append "Value", adLongVarWChar, 2147483647, adFldIsNullable Or adFldMayBeNull Data.CursorLocation = adUseClient Data.CursorType = adOpenDynamic Data.Open This is the recordset for values, the other is for the elements themselves. I step through the posted form and for the element recordset use a Scripting.Dictionary populated with instances of a custom Class that has the properties I need, so that I can add the values piecemeal, since they don't always come in order. New elements are added as negative to distinguish them from regular elements (rather than requiring a separate column to indicate if it is new or addresses an existing element). I use regular expression to tear apart the form keys: "^(e|n)([0-9]{1,10})_(a|p|t|c)([0-9]{0,10})$" Then, adding an attribute looks like this. Data.AddNew ElementID.Value = DataID AttrID.Value = Integerize(Matches(0).SubMatches(3)) AttrValue.Value = Request.Form(Key) Data.Update ElementID, AttrID, and AttrValue are references to the fields of the recordset. This method is hugely faster than using Data.Fields("ElementID").Value each time. I loop through the Dictionary of element updates and ignore any that don't have all the proper information, adding the good ones to the recordset. Then I call my data-updating stored procedure like so: Set Cmd = Server.CreateObject("ADODB.Command") With Cmd Set .ActiveConnection = MyDBConn .CommandType = adCmdStoredProc .CommandText = "DataPost" .Prepared = False .Parameters.Append .CreateParameter("@ElementMetadata", adLongVarWChar, adParamInput, 2147483647, XMLFromRecordset(Element)) .Parameters.Append .CreateParameter("@ElementData", adLongVarWChar, adParamInput, 2147483647, XMLFromRecordset(Data)) End With Result.Open Cmd ' previously created recordset object with options set Here's the function that does the xml conversion: Private Function XMLFromRecordset(Recordset) Dim Stream Set Stream = Server.CreateObject("ADODB.Stream") Stream.Open Recordset.Save Stream, adPersistXML Stream.Position = 0 XMLFromRecordset = Stream.ReadText End Function Just in case the web page needs to know, the SP returns a recordset of any new elements, showing their page value and their created value (so I can see that n1 is now e12346 for example). Here are some key snippets from the stored procedure. Note this is SQL 2000 for now, though I'll be able to switch to 2005 soon: CREATE PROCEDURE [dbo].[DataPost] @ElementMetaData ntext, @ElementData ntext AS DECLARE @hdoc int --- snip --- EXEC sp_xml_preparedocument @hdoc OUTPUT, @ElementMetaData, '<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema" />' INSERT #ElementMetadata (ElementID, ElementTypeID, ElementID1, ElementID2) SELECT * FROM OPENXML(@hdoc, '/xml/rs:data/rs:insert/z:row', 0) WITH ( ElementID int, ElementTypeID int, ElementID1 int, ElementID2 int ) ORDER BY ElementID -- orders negative items (new elements) first so they begin counting at 1 for later ID calculation EXEC sp_xml_removedocument @hdoc --- snip --- UPDATE E SET E.ElementTypeID = M.ElementTypeID FROM Element E INNER JOIN #ElementMetadata M ON E.ElementID = M.ElementID WHERE E.ElementID >= 1 AND M.ElementTypeID >= 1 The following query does the correlation of the negative new element ids to the newly inserted ones: UPDATE #ElementMetadata -- Correlate the new ElementIDs with the input rows SET NewElementID = Scope_Identity() - @@RowCount + DataID WHERE ElementID < 0 Other set-based queries do all the other work of validating that the attributes are allowed, are the correct data type, and inserting, updating, and deleting elements and attributes. I hope this brief run-down is useful to others some day! Converting ADO Recordsets to an XML stream was a huge winner for me as it saved all sorts of time and had a namespace and schema already defined that made the results come out correctly. Using a flatter XML format with 2 inputs was also much easier than sticking to some ideal about having everything in a single XML stream.

    Read the article

  • Sensible Way to Pass Web Data to Sql Server Database

    - by Emtucifor
    After exploring several different ways to pass web data to a database for update purposes, I'm wondering if XML might be a good strategy. The database is currently SQL 2000. In a few months it will move to SQL 2005 and I will be able to change things if needed, but I need a SQL 2000 solution now. First of all, the database in question uses the EAV model. I know that this kind of database is generally highly frowned on, so for the purposes of this question, please just accept that this is not going to change. The current update method has the web server inserting values (that have all been converted first to their correct underlying types, then to sql_variant) to a temp table. A stored procedure is then run which expects the temp table to exist and it takes care of updating, inserting, or deleting things as needed. So far, only a single element has needed to be updated at a time. But now, there is a requirement to be able to edit multiple elements at once, and also to support hierarchical elements, each of which can have its own list of attributes. Here's some example XML I hand-typed to demonstrate what I'm thinking of. Note that in this database the Entity is Element and an ID of 0 signifies "create" aka an insert of a new item. <Elements> <Element ID="1234"> <Attr ID="221">Value</Attr> <Attr ID="225">287</Attr> <Attr ID="234"> <Element ID="99825"> <Attr ID="7">Value1</Attr> <Attr ID="8">Value2</Attr> <Attr ID="9" Action="delete" /> </Element> <Element ID="99826" Action="delete" /> <Element ID="0" Type="24"> <Attr ID="7">Value4</Attr> <Attr ID="8">Value5</Attr> <Attr ID="9">Value6</Attr> </Element> <Element ID="0" Type="24"> <Attr ID="7">Value7</Attr> <Attr ID="8">Value8</Attr> <Attr ID="9">Value9</Attr> </Element> </Attr> <Rel ID="3827" Action="delete" /> <Rel ID="2284" Role="parent"> <Element ID="3827" /> <Element ID="3829" /> <Attr ID="665">1</Attr> </Rel> <Rel ID="0" Type="23" Role="child"> <Element ID="3830" /> <Attr ID="67" </Rel> </Element> <Element ID="0" Type="87"> <Attr ID="221">Value</Attr> <Attr ID="225">569</Attr> <Attr ID="234"> <Element ID="0" Type="24"> <Attr ID="7">Value10</Attr> <Attr ID="8">Value11</Attr> <Attr ID="9">Value12</Attr> </Element> </Attr> </Element> <Element ID="1235" Action="delete" /> </Elements> Some Attributes are straight value types, such as AttrID 221. But AttrID 234 is a special "multi-value" type that can have a list of elements underneath it, and each one can have one or more values. Types only need to be presented when a new item is created, since the ElementID fully implies the type if it already exists. I'll probably support only passing in changed items (as detected by javascript). And there may be an Action="Delete" on Attr elements as well, since NULLs are treated as "unselected"--sometimes it's very important to know if a Yes/No question has intentionally been answered No or if no one's bothered to say Yes yet. There is also a different kind of data, a Relationship. At this time, those are updated through individual AJAX calls as things are edited in the UI, but I'd like to include those so that changes to relationships can be canceled (right now, once you change it, it's done). So those are really elements, too, but they are called Rel instead of Element. Relationships are implemented as ElementID1 and ElementID2, so the RelID 2284 in the XML above is in the database as: ElementID 2284 ElementID1 1234 ElementID2 3827 Having multiple children in one relationship isn't currently supported, but it would be nice later. Does this strategy and the example XML make sense? Is there a more sensible way? I'm just looking for some broad critique to help save me from going down a bad path. Any aspect that you'd like to comment on would be helpful. The web language happens to be Classic ASP, but that could change to ASP.Net at some point. A persistence engine like Linq or nHibernate is probably not acceptable right now--I just want to get this already working application enhanced without a huge amount of development time. I'll choose the answer that shows experience and has a balance of good warnings about what not to do, confirmations of what I'm planning to do, and recommendations about something else to do. I'll make it as objective as possible. P.S. I'd like to handle unicode characters as well as very long strings (10k +). UPDATE I have had this working for some time and I used the ADO Recordset Save-To-Stream trick to make creating the XML really easy. The result seems to be fairly fast, though if speed ever becomes a problem I may revisit this. In the meantime, my code works to handle any number of elements and attributes on the page at once, including updating, deleting, and creating new items all in one go. I settled on a scheme like so for all my elements: Existing data elements Example: input name e12345_a678 (element 12345, attribute 678), the input value is the value of the attribute. New elements Javascript copies a hidden template of the set of HTML elements needed for the type into the correct location on the page, increments a counter to get a new ID for this item, and prepends the number to the names of the form items. var newid = 0; function metadataAdd(reference, nameid, value) { var t = document.createElement('input'); t.setAttribute('name', nameid); t.setAttribute('id', nameid); t.setAttribute('type', 'hidden'); t.setAttribute('value', value); reference.appendChild(t); } function multiAdd(target, parentelementid, attrid, elementtypeid) { var proto = document.getElementById('a' + attrid + '_proto'); var instance = document.createElement('p'); target.parentNode.parentNode.insertBefore(instance, target.parentNode); var thisid = ++newid; instance.innerHTML = proto.innerHTML.replace(/{prefix}/g, 'n' + thisid + '_'); instance.id = 'n' + thisid; instance.className += ' new'; metadataAdd(instance, 'n' + thisid + '_p', parentelementid); metadataAdd(instance, 'n' + thisid + '_c', attrid); metadataAdd(instance, 'n' + thisid + '_t', elementtypeid); return false; } Example: Template input name _a678 becomes n1_a678 (a new element, the first one on the page, attribute 678). all attributes of this new element are tagged with the same prefix of n1. The next new item will be n2, and so on. Some hidden form inputs are created: n1_t, value is the elementtype of the element to be created n1_p, value is the parent id of the element (if it is a relationship) n1_c, value is the child id of the element (if it is a relationship) Deleting elements A hidden input is created in the form e12345_t with value set to 0. The existing controls displaying that attribute's values are disabled so they are not included in the form post. So "set type to 0" is treated as delete. With this scheme, every item on the page has a unique name and can be distinguished properly, and every action can be represented properly. When the form is posted, here's a sample of building one of the two recordsets used (classic ASP code): Set Data = Server.CreateObject("ADODB.Recordset") Data.Fields.Append "ElementID", adInteger, 4, adFldKeyColumn Data.Fields.Append "AttrID", adInteger, 4, adFldKeyColumn Data.Fields.Append "Value", adLongVarWChar, 2147483647, adFldIsNullable Or adFldMayBeNull Data.CursorLocation = adUseClient Data.CursorType = adOpenDynamic Data.Open This is the recordset for values, the other is for the elements themselves. I step through the posted form and for the element recordset use a Scripting.Dictionary populated with instances of a custom Class that has the properties I need, so that I can add the values piecemeal, since they don't always come in order. New elements are added as negative to distinguish them from regular elements (rather than requiring a separate column to indicate if it is new or addresses an existing element). I use regular expression to tear apart the form keys: "^(e|n)([0-9]{1,10})_(a|p|t|c)([0-9]{0,10})$" Then, adding an attribute looks like this. Data.AddNew ElementID.Value = DataID AttrID.Value = Integerize(Matches(0).SubMatches(3)) AttrValue.Value = Request.Form(Key) Data.Update ElementID, AttrID, and AttrValue are references to the fields of the recordset. This method is hugely faster than using Data.Fields("ElementID").Value each time. I loop through the Dictionary of element updates and ignore any that don't have all the proper information, adding the good ones to the recordset. Then I call my data-updating stored procedure like so: Set Cmd = Server.CreateObject("ADODB.Command") With Cmd Set .ActiveConnection = MyDBConn .CommandType = adCmdStoredProc .CommandText = "DataPost" .Prepared = False .Parameters.Append .CreateParameter("@ElementMetadata", adLongVarWChar, adParamInput, 2147483647, XMLFromRecordset(Element)) .Parameters.Append .CreateParameter("@ElementData", adLongVarWChar, adParamInput, 2147483647, XMLFromRecordset(Data)) End With Result.Open Cmd ' previously created recordset object with options set Here's the function that does the xml conversion: Private Function XMLFromRecordset(Recordset) Dim Stream Set Stream = Server.CreateObject("ADODB.Stream") Stream.Open Recordset.Save Stream, adPersistXML Stream.Position = 0 XMLFromRecordset = Stream.ReadText End Function Just in case the web page needs to know, the SP returns a recordset of any new elements, showing their page value and their created value (so I can see that n1 is now e12346 for example). Here are some key snippets from the stored procedure. Note this is SQL 2000 for now, though I'll be able to switch to 2005 soon: CREATE PROCEDURE [dbo].[DataPost] @ElementMetaData ntext, @ElementData ntext AS DECLARE @hdoc int --- snip --- EXEC sp_xml_preparedocument @hdoc OUTPUT, @ElementMetaData, '<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema" />' INSERT #ElementMetadata (ElementID, ElementTypeID, ElementID1, ElementID2) SELECT * FROM OPENXML(@hdoc, '/xml/rs:data/rs:insert/z:row', 0) WITH ( ElementID int, ElementTypeID int, ElementID1 int, ElementID2 int ) ORDER BY ElementID -- orders negative items (new elements) first so they begin counting at 1 for later ID calculation EXEC sp_xml_removedocument @hdoc --- snip --- UPDATE E SET E.ElementTypeID = M.ElementTypeID FROM Element E INNER JOIN #ElementMetadata M ON E.ElementID = M.ElementID WHERE E.ElementID >= 1 AND M.ElementTypeID >= 1 The following query does the correlation of the negative new element ids to the newly inserted ones: UPDATE #ElementMetadata -- Correlate the new ElementIDs with the input rows SET NewElementID = Scope_Identity() - @@RowCount + DataID WHERE ElementID < 0 Other set-based queries do all the other work of validating that the attributes are allowed, are the correct data type, and inserting, updating, and deleting elements and attributes. I hope this brief run-down is useful to others some day! Converting ADO Recordsets to an XML stream was a huge winner for me as it saved all sorts of time and had a namespace and schema already defined that made the results come out correctly. Using a flatter XML format with 2 inputs was also much easier than sticking to some ideal about having everything in a single XML stream.

    Read the article

  • ffmpeg - How to determine if -movflags faststart is enabled? PHP

    - by IIIOXIII
    While I am able to encode an mp4 file which I can plan on my local windows machine, I am having trouble encoding files to mp4 which are readable when streaming by safari, etc. After a bit of reading, I believe my issue is that I must move the metadata from the end of the file to the beginning in order for the converted mp4 files to be streamable. To that end, I am trying to find out if the build of ffmpeg that I am currently using is able to use the -movflags faststart option through php - as my current outputted mp4 files are not working when streamed online. This is the way I am now echoing the -help, -formats, -codecs, but I am not seeing anything about -movflags faststart in any of the lists: exec($ffmpegPath." -help", $codecArr); for($ii=0;$ii<count($codecArr);$ii++){ echo $codecArr[$ii].'</br>'; } Is there a similar method of determining if -movflags fastart is available to my ffmpeg build? Any other way? Should it be listed with any of the previously suggested commands? -help/-formats? Can someone that knows it is enabled in their version of ffmpeg check to see if it is listed under -help or -formats, etc.? TIA. EDIT: COMPLETE CONSOLE OUTPUT FOR BOTH THE CONVERSION COMMAND AND -MOVFLAGS COMMAND BELOW: COMMAND: ffmpeg_new -i C:\vidtests\Wildlife.wmv -s 640x480 C:\vidtests\Wildlife.mp4 OUTPUT: ffmpeg version N-54207-ge59fb3f Copyright (c) 2000-2013 the FFmpeg developers built on Jun 25 2013 21:55:00 with gcc 4.7.3 (GCC) configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-av isynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enab le-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetyp e --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --ena ble-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libsp eex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo- amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs -- enable-libxvid --enable-zlib libavutil 52. 37.101 / 52. 37.101 libavcodec 55. 17.100 / 55. 17.100 libavformat 55. 10.100 / 55. 10.100 libavdevice 55. 2.100 / 55. 2.100 libavfilter 3. 77.101 / 3. 77.101 libswscale 2. 3.100 / 2. 3.100 libswresample 0. 17.102 / 0. 17.102 libpostproc 52. 3.100 / 52. 3.100 [asf @ 00000000002ed760] Stream #0: not enough frames to estimate rate; consider increasing probesize Guessed Channel Layout for Input Stream #0.0 : stereo Input #0, asf, from 'C:\vidtests\Wildlife.wmv' : Metadata: SfOriginalFPS : 299700 WMFSDKVersion : 11.0.6001.7000 WMFSDKNeeded : 0.0.0.0000 comment : Footage: Small World Productions, Inc; Tourism New Zealand | Producer: Gary F. Spradling | Music: Steve Ball title : Wildlife in HD copyright : -¬ 2008 Microsoft Corporation IsVBR : 0 DeviceConformanceTemplate: AP@L3 Duration: 00:00:30.09, start: 0.000000, bitrate: 6977 kb/s Stream #0:0(eng): Audio: wmav2 (a[1][0][0] / 0x0161), 44100 Hz, stereo, fltp , 192 kb/s Stream #0:1(eng): Video: vc1 (Advanced) (WVC1 / 0x31435657), yuv420p, 1280x7 20, 5942 kb/s, 29.97 tbr, 1k tbn, 1k tbc [libx264 @ 00000000002e6980] using cpu capabilities: MMX2 SSE2Fast SSSE3 Cache64 [libx264 @ 00000000002e6980] profile High, level 3.0 [libx264 @ 00000000002e6980] 264 - core 133 r2334 a3ac64b - H.264/MPEG-4 AVC cod ec - Copyleft 2003-2013 - http://www.videolan.org/x264.html - options: cabac=1 r ef=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed _ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pski p=1 chroma_qp_offset=-2 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 deci mate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_ adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=2 5 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.6 0 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 Output #0, mp4, to 'C:\vidtests\Wildlife.mp4': Metadata: SfOriginalFPS : 299700 WMFSDKVersion : 11.0.6001.7000 WMFSDKNeeded : 0.0.0.0000 comment : Footage: Small World Productions, Inc; Tourism New Zealand | Producer: Gary F. Spradling | Music: Steve Ball title : Wildlife in HD copyright : -¬ 2008 Microsoft Corporation IsVBR : 0 DeviceConformanceTemplate: AP@L3 encoder : Lavf55.10.100 Stream #0:0(eng): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 6 40x480, q=-1--1, 30k tbn, 29.97 tbc Stream #0:1(eng): Audio: aac (libvo_aacenc) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, s16, 128 kb/s Stream mapping: Stream #0:1 -> #0:0 (vc1 -> libx264) Stream #0:0 -> #0:1 (wmav2 -> libvo_aacenc) Press [q] to stop, [?] for help frame= 53 fps= 49 q=29.0 size= 0kB time=00:00:00.13 bitrate= 2.9kbits/ frame= 63 fps= 40 q=29.0 size= 0kB time=00:00:00.46 bitrate= 0.8kbits/ frame= 74 fps= 35 q=29.0 size= 0kB time=00:00:00.83 bitrate= 0.5kbits/ frame= 85 fps= 32 q=29.0 size= 0kB time=00:00:01.20 bitrate= 0.3kbits/ frame= 95 fps= 30 q=29.0 size= 0kB time=00:00:01.53 bitrate= 0.3kbits/ frame= 107 fps= 28 q=29.0 size= 0kB time=00:00:01.93 bitrate= 0.2kbits/ Queue input is backward in time [mp4 @ 00000000003ef800] Non-monotonous DTS in output stream 0:1; previous: 7616 , current: 7063; changing to 7617. This may result in incorrect timestamps in th e output file. frame= 118 fps= 28 q=29.0 size= 113kB time=00:00:02.30 bitrate= 402.6kbits/ frame= 129 fps= 26 q=29.0 size= 219kB time=00:00:02.66 bitrate= 670.7kbits/ frame= 141 fps= 26 q=29.0 size= 264kB time=00:00:03.06 bitrate= 704.2kbits/ frame= 152 fps= 25 q=29.0 size= 328kB time=00:00:03.43 bitrate= 782.2kbits/ frame= 163 fps= 25 q=29.0 size= 431kB time=00:00:03.80 bitrate= 928.1kbits/ frame= 174 fps= 24 q=29.0 size= 568kB time=00:00:04.17 bitrate=1116.3kbits/ frame= 190 fps= 25 q=29.0 size= 781kB time=00:00:04.70 bitrate=1359.9kbits/ frame= 204 fps= 25 q=29.0 size= 1006kB time=00:00:05.17 bitrate=1593.1kbits/ frame= 218 fps= 25 q=29.0 size= 1058kB time=00:00:05.63 bitrate=1536.8kbits/ frame= 229 fps= 25 q=29.0 size= 1093kB time=00:00:06.00 bitrate=1490.9kbits/ frame= 239 fps= 24 q=29.0 size= 1118kB time=00:00:06.33 bitrate=1444.4kbits/ frame= 251 fps= 24 q=29.0 size= 1150kB time=00:00:06.74 bitrate=1397.9kbits/ frame= 265 fps= 24 q=29.0 size= 1234kB time=00:00:07.20 bitrate=1402.3kbits/ frame= 278 fps= 25 q=29.0 size= 1332kB time=00:00:07.64 bitrate=1428.3kbits/ frame= 294 fps= 25 q=29.0 size= 1403kB time=00:00:08.17 bitrate=1405.7kbits/ frame= 308 fps= 25 q=29.0 size= 1547kB time=00:00:08.64 bitrate=1466.4kbits/ frame= 323 fps= 25 q=29.0 size= 1595kB time=00:00:09.14 bitrate=1429.5kbits/ frame= 337 fps= 25 q=29.0 size= 1702kB time=00:00:09.60 bitrate=1450.7kbits/ frame= 351 fps= 25 q=29.0 size= 1755kB time=00:00:10.07 bitrate=1427.1kbits/ frame= 365 fps= 25 q=29.0 size= 1820kB time=00:00:10.54 bitrate=1414.1kbits/ frame= 381 fps= 25 q=29.0 size= 1852kB time=00:00:11.07 bitrate=1369.6kbits/ frame= 396 fps= 26 q=29.0 size= 1893kB time=00:00:11.57 bitrate=1339.5kbits/ frame= 409 fps= 26 q=29.0 size= 1923kB time=00:00:12.01 bitrate=1311.8kbits/ frame= 421 fps= 25 q=29.0 size= 1967kB time=00:00:12.41 bitrate=1298.3kbits/ frame= 434 fps= 25 q=29.0 size= 1998kB time=00:00:12.84 bitrate=1274.0kbits/ frame= 445 fps= 25 q=29.0 size= 2018kB time=00:00:13.21 bitrate=1251.3kbits/ frame= 458 fps= 25 q=29.0 size= 2048kB time=00:00:13.64 bitrate=1229.5kbits/ frame= 471 fps= 25 q=29.0 size= 2067kB time=00:00:14.08 bitrate=1202.3kbits/ frame= 484 fps= 25 q=29.0 size= 2189kB time=00:00:14.51 bitrate=1235.5kbits/ frame= 497 fps= 25 q=29.0 size= 2260kB time=00:00:14.94 bitrate=1238.3kbits/ frame= 509 fps= 25 q=29.0 size= 2311kB time=00:00:15.34 bitrate=1233.3kbits/ frame= 523 fps= 25 q=29.0 size= 2429kB time=00:00:15.81 bitrate=1258.1kbits/ frame= 535 fps= 25 q=29.0 size= 2541kB time=00:00:16.21 bitrate=1283.5kbits/ frame= 548 fps= 25 q=29.0 size= 2718kB time=00:00:16.64 bitrate=1337.5kbits/ frame= 560 fps= 25 q=29.0 size= 2845kB time=00:00:17.05 bitrate=1367.1kbits/ frame= 571 fps= 25 q=29.0 size= 2965kB time=00:00:17.41 bitrate=1394.6kbits/ frame= 580 fps= 25 q=29.0 size= 3025kB time=00:00:17.71 bitrate=1398.7kbits/ frame= 588 fps= 25 q=29.0 size= 3098kB time=00:00:17.98 bitrate=1411.1kbits/ frame= 597 fps= 25 q=29.0 size= 3183kB time=00:00:18.28 bitrate=1426.1kbits/ frame= 606 fps= 24 q=29.0 size= 3279kB time=00:00:18.58 bitrate=1445.2kbits/ frame= 616 fps= 24 q=29.0 size= 3441kB time=00:00:18.91 bitrate=1489.9kbits/ frame= 626 fps= 24 q=29.0 size= 3650kB time=00:00:19.25 bitrate=1553.0kbits/ frame= 638 fps= 24 q=29.0 size= 3826kB time=00:00:19.65 bitrate=1594.7kbits/ frame= 649 fps= 24 q=29.0 size= 3950kB time=00:00:20.02 bitrate=1616.3kbits/ frame= 660 fps= 24 q=29.0 size= 4067kB time=00:00:20.38 bitrate=1634.1kbits/ frame= 669 fps= 24 q=29.0 size= 4121kB time=00:00:20.68 bitrate=1631.8kbits/ frame= 682 fps= 24 q=29.0 size= 4274kB time=00:00:21.12 bitrate=1657.9kbits/ frame= 696 fps= 24 q=29.0 size= 4446kB time=00:00:21.58 bitrate=1687.1kbits/ frame= 709 fps= 24 q=29.0 size= 4590kB time=00:00:22.02 bitrate=1707.3kbits/ frame= 719 fps= 24 q=29.0 size= 4772kB time=00:00:22.35 bitrate=1748.5kbits/ frame= 732 fps= 24 q=29.0 size= 4852kB time=00:00:22.78 bitrate=1744.3kbits/ frame= 744 fps= 24 q=29.0 size= 4973kB time=00:00:23.18 bitrate=1756.9kbits/ frame= 756 fps= 24 q=29.0 size= 5099kB time=00:00:23.59 bitrate=1770.8kbits/ frame= 768 fps= 24 q=29.0 size= 5149kB time=00:00:23.99 bitrate=1758.4kbits/ frame= 780 fps= 24 q=29.0 size= 5227kB time=00:00:24.39 bitrate=1755.7kbits/ frame= 797 fps= 24 q=29.0 size= 5377kB time=00:00:24.95 bitrate=1765.0kbits/ frame= 813 fps= 24 q=29.0 size= 5507kB time=00:00:25.49 bitrate=1769.5kbits/ frame= 828 fps= 24 q=29.0 size= 5634kB time=00:00:25.99 bitrate=1775.5kbits/ frame= 843 fps= 24 q=29.0 size= 5701kB time=00:00:26.49 bitrate=1762.9kbits/ frame= 859 fps= 24 q=29.0 size= 5830kB time=00:00:27.02 bitrate=1767.0kbits/ frame= 872 fps= 24 q=29.0 size= 5926kB time=00:00:27.46 bitrate=1767.7kbits/ frame= 888 fps= 24 q=29.0 size= 6014kB time=00:00:27.99 bitrate=1759.7kbits/ frame= 900 fps= 24 q=29.0 size= 6332kB time=00:00:28.39 bitrate=1826.9kbits/ frame= 901 fps= 24 q=-1.0 Lsize= 6717kB time=00:00:30.10 bitrate=1828.0kbits /s video:6211kB audio:472kB subtitle:0 global headers:0kB muxing overhead 0.513217% [libx264 @ 00000000002e6980] frame I:8 Avg QP:21.77 size: 39744 [libx264 @ 00000000002e6980] frame P:433 Avg QP:25.69 size: 11490 [libx264 @ 00000000002e6980] frame B:460 Avg QP:29.25 size: 2319 [libx264 @ 00000000002e6980] consecutive B-frames: 5.4% 78.6% 2.7% 13.3% [libx264 @ 00000000002e6980] mb I I16..4: 21.8% 48.8% 29.5% [libx264 @ 00000000002e6980] mb P I16..4: 0.7% 4.0% 1.3% P16..4: 37.1% 22.2 % 15.5% 0.0% 0.0% skip:19.2% [libx264 @ 00000000002e6980] mb B I16..4: 0.1% 0.5% 0.2% B16..8: 43.5% 7.0 % 2.1% direct: 2.2% skip:44.5% L0:36.4% L1:52.7% BI:10.9% [libx264 @ 00000000002e6980] 8x8 transform intra:62.8% inter:56.2% [libx264 @ 00000000002e6980] coded y,uvDC,uvAC intra: 74.2% 78.8% 44.0% inter: 2 3.6% 14.5% 1.0% [libx264 @ 00000000002e6980] i16 v,h,dc,p: 48% 24% 9% 20% [libx264 @ 00000000002e6980] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 16% 17% 15% 7% 8% 11% 8% 10% 8% [libx264 @ 00000000002e6980] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 19% 17% 15% 7% 10% 11% 8% 7% 7% [libx264 @ 00000000002e6980] i8c dc,h,v,p: 53% 21% 18% 7% [libx264 @ 00000000002e6980] Weighted P-Frames: Y:0.7% UV:0.0% [libx264 @ 00000000002e6980] ref P L0: 62.4% 19.0% 12.0% 6.6% 0.0% [libx264 @ 00000000002e6980] ref B L0: 90.5% 8.9% 0.7% [libx264 @ 00000000002e6980] ref B L1: 97.9% 2.1% [libx264 @ 00000000002e6980] kb/s:1692.37 AND THE –MOVFLAGS COMMAND: C:\XSITE\SITE>ffmpeg_new -i C:\vidtests\Wildlife.mp4 -movflags faststart C:\vidtests\Wildlife_fs.mp4 AND THE –MOVFLAGS OUTPUT ffmpeg version N-54207-ge59fb3f Copyright (c) 2000-2013 the FFmpeg developers built on Jun 25 2013 21:55:00 with gcc 4.7.3 (GCC) configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-av isynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enab le-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetyp e --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --ena ble-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libsp eex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo- amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs -- enable-libxvid --enable-zlib libavutil 52. 37.101 / 52. 37.101 libavcodec 55. 17.100 / 55. 17.100 libavformat 55. 10.100 / 55. 10.100 libavdevice 55. 2.100 / 55. 2.100 libavfilter 3. 77.101 / 3. 77.101 libswscale 2. 3.100 / 2. 3.100 libswresample 0. 17.102 / 0. 17.102 libpostproc 52. 3.100 / 52. 3.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\vidtests\Wildlife.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 title : Wildlife in HD encoder : Lavf55.10.100 comment : Footage: Small World Productions, Inc; Tourism New Zealand | Producer: Gary F. Spradling | Music: Steve Ball copyright : -¬ 2008 Microsoft Corporation Duration: 00:00:30.13, start: 0.036281, bitrate: 1826 kb/s Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x480, 1692 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc Metadata: handler_name : VideoHandler Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 12 8 kb/s Metadata: handler_name : SoundHandler [libx264 @ 0000000004360620] using cpu capabilities: MMX2 SSE2Fast SSSE3 Cache64 [libx264 @ 0000000004360620] profile High, level 3.0 [libx264 @ 0000000004360620] 264 - core 133 r2334 a3ac64b - H.264/MPEG-4 AVC cod ec - Copyleft 2003-2013 - http://www.videolan.org/x264.html - options: cabac=1 r ef=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed _ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pski p=1 chroma_qp_offset=-2 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 deci mate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_ adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=2 5 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.6 0 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 Output #0, mp4, to 'C:\vidtests\Wildlife_fs.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 title : Wildlife in HD copyright : -¬ 2008 Microsoft Corporation comment : Footage: Small World Productions, Inc; Tourism New Zealand | Producer: Gary F. Spradling | Music: Steve Ball encoder : Lavf55.10.100 Stream #0:0(eng): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 6 40x480, q=-1--1, 30k tbn, 29.97 tbc Metadata: handler_name : VideoHandler Stream #0:1(eng): Audio: aac (libvo_aacenc) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, s16, 128 kb/s Metadata: handler_name : SoundHandler Stream mapping: Stream #0:0 -> #0:0 (h264 -> libx264) Stream #0:1 -> #0:1 (aac -> libvo_aacenc) Press [q] to stop, [?] for help frame= 52 fps=0.0 q=29.0 size= 29kB time=00:00:01.76 bitrate= 133.9kbits/ frame= 63 fps= 60 q=29.0 size= 104kB time=00:00:02.14 bitrate= 397.2kbits/ frame= 74 fps= 47 q=29.0 size= 176kB time=00:00:02.51 bitrate= 573.2kbits/ frame= 87 fps= 41 q=29.0 size= 265kB time=00:00:02.93 bitrate= 741.2kbits/ frame= 101 fps= 37 q=29.0 size= 358kB time=00:00:03.39 bitrate= 862.8kbits/ frame= 113 fps= 34 q=29.0 size= 437kB time=00:00:03.79 bitrate= 943.7kbits/ frame= 125 fps= 33 q=29.0 size= 520kB time=00:00:04.20 bitrate=1012.2kbits/ frame= 138 fps= 32 q=29.0 size= 606kB time=00:00:04.64 bitrate=1069.8kbits/ frame= 151 fps= 31 q=29.0 size= 696kB time=00:00:05.06 bitrate=1124.3kbits/ frame= 163 fps= 30 q=29.0 size= 780kB time=00:00:05.47 bitrate=1166.4kbits/ frame= 176 fps= 30 q=29.0 size= 919kB time=00:00:05.90 bitrate=1273.9kbits/ frame= 196 fps= 31 q=29.0 size= 994kB time=00:00:06.57 bitrate=1237.4kbits/ frame= 213 fps= 31 q=29.0 size= 1097kB time=00:00:07.13 bitrate=1258.8kbits/ frame= 225 fps= 30 q=29.0 size= 1204kB time=00:00:07.53 bitrate=1309.8kbits/ frame= 236 fps= 30 q=29.0 size= 1323kB time=00:00:07.91 bitrate=1369.4kbits/ frame= 249 fps= 29 q=29.0 size= 1451kB time=00:00:08.34 bitrate=1424.6kbits/ frame= 263 fps= 29 q=29.0 size= 1574kB time=00:00:08.82 bitrate=1461.3kbits/ frame= 278 fps= 29 q=29.0 size= 1610kB time=00:00:09.30 bitrate=1416.9kbits/ frame= 296 fps= 30 q=29.0 size= 1655kB time=00:00:09.91 bitrate=1368.0kbits/ frame= 313 fps= 30 q=29.0 size= 1697kB time=00:00:10.48 bitrate=1326.4kbits/ frame= 330 fps= 30 q=29.0 size= 1737kB time=00:00:11.05 bitrate=1286.5kbits/ frame= 345 fps= 30 q=29.0 size= 1776kB time=00:00:11.54 bitrate=1260.4kbits/ frame= 361 fps= 30 q=29.0 size= 1813kB time=00:00:12.07 bitrate=1230.3kbits/ frame= 377 fps= 30 q=29.0 size= 1847kB time=00:00:12.59 bitrate=1201.4kbits/ frame= 395 fps= 30 q=29.0 size= 1880kB time=00:00:13.22 bitrate=1165.0kbits/ frame= 410 fps= 30 q=29.0 size= 1993kB time=00:00:13.72 bitrate=1190.2kbits/ frame= 424 fps= 30 q=29.0 size= 2080kB time=00:00:14.18 bitrate=1201.4kbits/ frame= 439 fps= 30 q=29.0 size= 2166kB time=00:00:14.67 bitrate=1209.4kbits/ frame= 455 fps= 30 q=29.0 size= 2262kB time=00:00:15.21 bitrate=1217.5kbits/ frame= 469 fps= 30 q=29.0 size= 2341kB time=00:00:15.68 bitrate=1223.0kbits/ frame= 484 fps= 30 q=29.0 size= 2430kB time=00:00:16.19 bitrate=1229.1kbits/ frame= 500 fps= 30 q=29.0 size= 2523kB time=00:00:16.71 bitrate=1236.3kbits/ frame= 515 fps= 30 q=29.0 size= 2607kB time=00:00:17.21 bitrate=1240.4kbits/ frame= 531 fps= 30 q=29.0 size= 2681kB time=00:00:17.73 bitrate=1238.2kbits/ frame= 546 fps= 30 q=29.0 size= 2758kB time=00:00:18.24 bitrate=1238.2kbits/ frame= 561 fps= 30 q=29.0 size= 2824kB time=00:00:18.75 bitrate=1233.4kbits/ frame= 576 fps= 30 q=29.0 size= 2955kB time=00:00:19.25 bitrate=1256.8kbits/ frame= 586 fps= 29 q=29.0 size= 3061kB time=00:00:19.59 bitrate=1279.6kbits/ frame= 598 fps= 29 q=29.0 size= 3217kB time=00:00:19.99 bitrate=1318.4kbits/ frame= 610 fps= 29 q=29.0 size= 3354kB time=00:00:20.39 bitrate=1347.2kbits/ frame= 622 fps= 29 q=29.0 size= 3483kB time=00:00:20.78 bitrate=1372.6kbits/ frame= 634 fps= 29 q=29.0 size= 3593kB time=00:00:21.19 bitrate=1388.6kbits/ frame= 648 fps= 29 q=29.0 size= 3708kB time=00:00:21.66 bitrate=1402.3kbits/ frame= 661 fps= 29 q=29.0 size= 3811kB time=00:00:22.08 bitrate=1413.5kbits/ frame= 674 fps= 29 q=29.0 size= 3978kB time=00:00:22.53 bitrate=1446.3kbits/ frame= 690 fps= 29 q=29.0 size= 4133kB time=00:00:23.05 bitrate=1468.4kbits/ frame= 706 fps= 29 q=29.0 size= 4263kB time=00:00:23.58 bitrate=1480.4kbits/ frame= 721 fps= 29 q=29.0 size= 4391kB time=00:00:24.08 bitrate=1493.8kbits/ frame= 735 fps= 29 q=29.0 size= 4524kB time=00:00:24.55 bitrate=1509.4kbits/ frame= 748 fps= 29 q=29.0 size= 4661kB time=00:00:24.98 bitrate=1528.2kbits/ frame= 763 fps= 29 q=29.0 size= 4835kB time=00:00:25.50 bitrate=1553.1kbits/ frame= 778 fps= 29 q=29.0 size= 4993kB time=00:00:25.99 bitrate=1573.6kbits/ frame= 795 fps= 29 q=29.0 size= 5149kB time=00:00:26.56 bitrate=1588.1kbits/ frame= 814 fps= 29 q=29.0 size= 5258kB time=00:00:27.18 bitrate=1584.4kbits/ frame= 833 fps= 29 q=29.0 size= 5368kB time=00:00:27.82 bitrate=1580.2kbits/ frame= 851 fps= 29 q=29.0 size= 5469kB time=00:00:28.43 bitrate=1575.9kbits/ frame= 870 fps= 29 q=29.0 size= 5567kB time=00:00:29.05 bitrate=1569.5kbits/ frame= 889 fps= 29 q=29.0 size= 5688kB time=00:00:29.70 bitrate=1568.4kbits/ Starting second pass: moving header on top of the file frame= 902 fps= 28 q=-1.0 Lsize= 6109kB time=00:00:30.14 bitrate=1659.8kbits /s dup=1 drop=0 video:5602kB audio:472kB subtitle:0 global headers:0kB muxing overhead 0.566600% [libx264 @ 0000000004360620] frame I:8 Avg QP:20.52 size: 39667 [libx264 @ 0000000004360620] frame P:419 Avg QP:25.06 size: 10524 [libx264 @ 0000000004360620] frame B:475 Avg QP:29.03 size: 2123 [libx264 @ 0000000004360620] consecutive B-frames: 3.2% 79.6% 0.3% 16.9% [libx264 @ 0000000004360620] mb I I16..4: 20.7% 52.3% 26.9% [libx264 @ 0000000004360620] mb P I16..4: 0.7% 4.2% 1.1% P16..4: 39.4% 21.4 % 13.8% 0.0% 0.0% skip:19.3% [libx264 @ 0000000004360620] mb B I16..4: 0.1% 0.9% 0.3% B16..8: 41.8% 6.4 % 1.7% direct: 1.7% skip:47.1% L0:36.4% L1:53.3% BI:10.3% [libx264 @ 0000000004360620] 8x8 transform intra:65.7% inter:58.8% [libx264 @ 0000000004360620] coded y,uvDC,uvAC intra: 71.2% 76.6% 35.7% inter: 2 0.7% 13.0% 0.5% [libx264 @ 0000000004360620] i16 v,h,dc,p: 48% 24% 8% 20% [libx264 @ 0000000004360620] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 17% 18% 15% 6% 8% 11% 8% 10% 8% [libx264 @ 0000000004360620] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 19% 16% 15% 7% 10% 11% 8% 8% 7% [libx264 @ 0000000004360620] i8c dc,h,v,p: 51% 22% 19% 9% [libx264 @ 0000000004360620] Weighted P-Frames: Y:0.7% UV:0.0% [libx264 @ 0000000004360620] ref P L0: 63.4% 19.7% 11.0% 5.9% 0.0% [libx264 @ 0000000004360620] ref B L0: 90.7% 8.7% 0.7% [libx264 @ 0000000004360620] ref B L1: 98.4% 1.6% [libx264 @ 0000000004360620] kb/s:1524.54

    Read the article

  • Template inheritence c++

    - by Chris Condy
    I have made a template singleton class, I have also made a data structure that is templated. My question is; how do I make my templated data structure inherit from a singleton so you can only have one float type of this structure? I have tested both seperate and have found no problems. Code provided under... (That is the problem) template <class Type> class AbstractRManagers : public Singleton<AbstractRManagers<Type> > The problem is the code above doesn't work I get alot of errors. I cant get it to no matter what I do template a templated singleton class... I was asking for maybe advice or maybe if the code above is incorrect guidence? #ifndef SINGLETON_H #define SINGLETON_H template <class Type> class Singleton { public: virtual ~Singleton(); Singleton(); static Type* m_instance; }; template <class Type> Type* Singleton<Type>::m_instance = 0; #include "Singleton.cpp" #endif #ifndef SINGLETON_CPP #define SINGLETON_CPP #include "Singleton.h" template <class Type> Singleton<Type>::Singleton() { } template <class Type> Singleton<Type>::~Singleton() { } template <class Type> Type* Singleton<Type>::getInstance() { if(m_instance==nullptr) { m_instance = new Type; } return m_instance; } #endif #ifndef ABSTRACTRMANAGERS_H #define ABSTRACTRMANAGERS_H #include <vector> #include <map> #include <stack> #include "Singleton.h" template <class Type> class AbstractRManagers : public Singleton<AbstractRManagers<Type> > { public: virtual ~AbstractRManagers(); int insert(Type* type, std::string name); Type* remove(int i); Type* remove(std::string name); Type* get(int i); Type* getS(std::string name); int get(std::string name); int get(Type* i); bool check(std::string name); int resourceSize(); protected: private: std::vector<Type*> m_resources; std::map<std::string,int> m_map; std::stack<int> m_freePos; }; #include "AbstractRManagers.cpp" #endif #ifndef ABSTRACTRMANAGERS_CPP #define ABSTRACTRMANAGERS_CPP #include "AbstractRManagers.h" template <class Type> int AbstractRManagers<Type>::insert(Type* type, std::string name) { int i=0; if(!check(name)) { if(m_freePos.empty()) { m_resources.push_back(type); i = m_resources.size()-1; m_map[name] = i; } else { i = m_freePos.top(); m_freePos.pop(); m_resources[i] = type; m_map[name] = i; } } else i = -1; return i; } template <class Type> int AbstractRManagers<Type>::resourceSize() { return m_resources.size(); } template <class Type> bool AbstractRManagers<Type>::check(std::string name) { std::map<std::string,int>::iterator it; it = m_map.find(name); if(it==m_map.end()) return false; return true; } template <class Type> Type* AbstractRManagers<Type>::remove(std::string name) { Type* temp = m_resources[m_map[name]]; if(temp!=NULL) { std::map<std::string,int>::iterator it; it = m_map[name]; m_resources[m_map[name]] = NULL; m_freePos.push(m_map[name]); delete (*it).second; delete (*it).first; return temp; } return NULL; } template <class Type> Type* AbstractRManagers<Type>::remove(int i) { if((i < m_resources.size())&&(i > 0)) { Type* temp = m_resources[i]; m_resources[i] = NULL; m_freePos.push(i); std::map<std::string,int>::iterator it; for(it=m_map.begin();it!=m_map.end();it++) { if((*it).second == i) { delete (*it).second; delete (*it).first; return temp; } } return temp; } return NULL; } template <class Type> int AbstractRManagers<Type>::get(Type* i) { for(int i2=0;i2<m_resources.size();i2++) { if(i == m_resources[i2]) { return i2; } } return -1; } template <class Type> Type* AbstractRManagers<Type>::get(int i) { if((i < m_resources.size())&&(i >= 0)) { return m_resources[i]; } return NULL; } template <class Type> Type* AbstractRManagers<Type>::getS(std::string name) { return m_resources[m_map[name]]; } template <class Type> int AbstractRManagers<Type>::get(std::string name) { return m_map[name]; } template <class Type> AbstractRManagers<Type>::~AbstractRManagers() { } #endif #include "AbstractRManagers.h" struct b { float x; }; int main() { b* a = new b(); AbstractRManagers<b>::getInstance()->insert(a,"a"); return 0; } This program produces next errors when compiled : 1> main.cpp 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::stack<_Ty,_Container> &,const std::stack<_Ty,_Container> &)' : could not deduce template argument for 'const std::stack<_Ty,_Container> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\stack(166) : see declaration of 'std::operator <' 1> c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(124) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const' 1> with 1> [ 1> _Ty=std::string 1> ] 1> c:\program files\microsoft visual studio 10.0\vc\include\map(71) : see reference to class template instantiation 'std::less<_Ty>' being compiled 1> with 1> [ 1> _Ty=std::string 1> ] 1> c:\program files\microsoft visual studio 10.0\vc\include\xtree(451) : see reference to class template instantiation 'std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,_Mfl>' being compiled 1> with 1> [ 1> _Kty=std::string, 1> _Ty=int, 1> _Pr=std::less<std::string>, 1> _Alloc=std::allocator<std::pair<const std::string,int>>, 1> _Mfl=false 1> ] 1> c:\program files\microsoft visual studio 10.0\vc\include\xtree(520) : see reference to class template instantiation 'std::_Tree_nod<_Traits>' being compiled 1> with 1> [ 1> _Traits=std::_Tmap_traits<std::string,int,std::less<std::string>,std::allocator<std::pair<const std::string,int>>,false> 1> ] 1> c:\program files\microsoft visual studio 10.0\vc\include\xtree(659) : see reference to class template instantiation 'std::_Tree_val<_Traits>' being compiled 1> with 1> [ 1> _Traits=std::_Tmap_traits<std::string,int,std::less<std::string>,std::allocator<std::pair<const std::string,int>>,false> 1> ] 1> c:\program files\microsoft visual studio 10.0\vc\include\map(81) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled 1> with 1> [ 1> _Traits=std::_Tmap_traits<std::string,int,std::less<std::string>,std::allocator<std::pair<const std::string,int>>,false> 1> ] 1> c:\users\chris\desktop\311\ideas\idea1\idea1\abstractrmanagers.h(28) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled 1> with 1> [ 1> _Kty=std::string, 1> _Ty=int 1> ] 1> c:\users\chris\desktop\311\ideas\idea1\idea1\abstractrmanagers.h(30) : see reference to class template instantiation 'AbstractRManagers<Type>' being compiled 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::stack<_Ty,_Container> &,const std::stack<_Ty,_Container> &)' : could not deduce template argument for 'const std::stack<_Ty,_Container> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\stack(166) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::stack<_Ty,_Container> &,const std::stack<_Ty,_Container> &)' : could not deduce template argument for 'const std::stack<_Ty,_Container> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\stack(166) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::deque<_Ty,_Alloc> &,const std::deque<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::deque<_Ty,_Alloc> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\deque(1725) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::deque<_Ty,_Alloc> &,const std::deque<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::deque<_Ty,_Alloc> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\deque(1725) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::deque<_Ty,_Alloc> &,const std::deque<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::deque<_Ty,_Alloc> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\deque(1725) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\xtree(1885) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\xtree(1885) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\xtree(1885) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\vector(1502) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\vector(1502) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\vector(1502) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::unique_ptr<_Ty,_Dx> &,const std::unique_ptr<_Ty2,_Dx2> &)' : could not deduce template argument for 'const std::unique_ptr<_Ty,_Dx> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\memory(2582) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::unique_ptr<_Ty,_Dx> &,const std::unique_ptr<_Ty2,_Dx2> &)' : could not deduce template argument for 'const std::unique_ptr<_Ty,_Dx> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\memory(2582) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::unique_ptr<_Ty,_Dx> &,const std::unique_ptr<_Ty2,_Dx2> &)' : could not deduce template argument for 'const std::unique_ptr<_Ty,_Dx> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\memory(2582) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(1356) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(1356) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(1356) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(1179) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(1179) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(1179) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\utility(318) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\utility(318) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string' 1> c:\program files\microsoft visual studio 10.0\vc\include\utility(318) : see declaration of 'std::operator <' 1>c:\program files\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2676: binary '<' : 'const std::string' does not define this operator or a conversion to a type acceptable to the predefined operator ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    Read the article

  • Compile error C++: could not deduce template argument for 'T'

    - by OneShot
    I'm trying to read binary data to load structs back into memory so I can edit them and save them back to the .dat file. readVector() attempts to read the file, and return the vectors that were serialized. But i'm getting this compile error when I try and run it. What am I doing wrong with my templates? ***** EDIT ************** Code: // Project 5.cpp : main project file. #include "stdafx.h" #include <iostream> #include <fstream> #include <string> #include <vector> #include <algorithm> using namespace System; using namespace std; #pragma hdrstop int checkCommand (string line); template<typename T> void writeVector(ofstream &out, const vector<T> &vec); template<typename T> vector<T> readVector(ifstream &in); struct InventoryItem { string Item; string Description; int Quantity; int wholesaleCost; int retailCost; int dateAdded; } ; int main(void) { cout << "Welcome to the Inventory Manager extreme! [Version 1.0]" << endl; ifstream in("data.dat"); vector<InventoryItem> structList; readVector<InventoryItem>( in ); while (1) { string line = ""; cout << endl; cout << "Commands: " << endl; cout << "1: Add a new record " << endl; cout << "2: Display a record " << endl; cout << "3: Edit a current record " << endl; cout << "4: Exit the program " << endl; cout << endl; cout << "Enter a command 1-4: "; getline(cin , line); int rValue = checkCommand(line); if (rValue == 1) { cout << "You've entered a invalid command! Try Again." << endl; } else if (rValue == 2){ cout << "Error calling command!" << endl; } else if (!rValue) { break; } } system("pause"); return 0; } int checkCommand (string line) { int intReturn = atoi(line.c_str()); int status = 3; switch (intReturn) { case 1: break; case 2: break; case 3: break; case 4: status = 0; break; default: status = 1; break; } return status; } template<typename T> void writeVector(ofstream &out, const vector<T> &vec) { out << vec.size(); for(vector<T>::const_iterator i = vec.begin(); i != vec.end(); i++) { out << *i; } } ostream& operator<<(std::ostream &strm, const InventoryItem &i) { return strm << i.Item << " (" << i.Description << ")"; } template<typename T> vector<T> readVector(ifstream &in) { size_t size; in >> size; vector<T> vec; vec.reserve(size); for(int i = 0; i < size; i++) { T tmp; in >> tmp; vec.push_back(tmp); } return vec; } Compiler errors: 1>------ Build started: Project: Project 5, Configuration: Debug Win32 ------ 1>Compiling... 1>Project 5.cpp 1>.\Project 5.cpp(124) : warning C4018: '<' : signed/unsigned mismatch 1> .\Project 5.cpp(40) : see reference to function template instantiation 'std::vector<_Ty> readVector<InventoryItem>(std::ifstream &)' being compiled 1> with 1> [ 1> _Ty=InventoryItem 1> ] 1>.\Project 5.cpp(127) : error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'InventoryItem' (or there is no acceptable conversion) 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(1144): could be 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,signed char *)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(1146): or 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,signed char &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(1148): or 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,unsigned char *)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(1150): or 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,unsigned char &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(155): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::basic_istream<_Elem,_Traits> &(__cdecl *)(std::basic_istream<_Elem,_Traits> &))' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(161): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::basic_ios<_Elem,_Traits> &(__cdecl *)(std::basic_ios<_Elem,_Traits> &))' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(168): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::ios_base &(__cdecl *)(std::ios_base &))' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(175): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::_Bool &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(194): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(short &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(228): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(unsigned short &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(247): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(int &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(273): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(unsigned int &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(291): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(long &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(309): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(__w64 unsigned long &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(329): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(__int64 &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(348): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(unsigned __int64 &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(367): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(float &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(386): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(double &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(404): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(long double &)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(422): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(void *&)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(441): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::basic_streambuf<_Elem,_Traits> *)' 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits<char> 1> ] 1> while trying to match the argument list '(std::ifstream, InventoryItem)' 1>Build log was saved at "file://c:\Users\Owner\Documents\Visual Studio 2008\Projects\Project 5\Project 5\Debug\BuildLog.htm" 1>Project 5 - 1 error(s), 1 warning(s) ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== Oh my god...I fixed that error I think and now I got another one. Will you PLEASE just help me on this one too! What the heck does this mean ??

    Read the article

  • Steganography Experiment - Trouble hiding message bits in DCT coefficients

    - by JohnHankinson
    I have an application requiring me to be able to embed loss-less data into an image. As such I've been experimenting with steganography, specifically via modification of DCT coefficients as the method I select, apart from being loss-less must also be relatively resilient against format conversion, scaling/DSP etc. From the research I've done thus far this method seems to be the best candidate. I've seen a number of papers on the subject which all seem to neglect specific details (some neglect to mention modification of 0 coefficients, or modification of AC coefficient etc). After combining the findings and making a few modifications of my own which include: 1) Using a more quantized version of the DCT matrix to ensure we only modify coefficients that would still be present should the image be JPEG'ed further or processed (I'm using this in place of simply following a zig-zag pattern). 2) I'm modifying bit 4 instead of the LSB and then based on what the original bit value was adjusting the lower bits to minimize the difference. 3) I'm only modifying the blue channel as it should be the least visible. This process must modify the actual image and not the DCT values stored in file (like jsteg) as there is no guarantee the file will be a JPEG, it may also be opened and re-saved at a later stage in a different format. For added robustness I've included the message multiple times and use the bits that occur most often, I had considered using a QR code as the message data or simply applying the reed-solomon error correction, but for this simple application and given that the "message" in question is usually going to be between 10-32 bytes I have plenty of room to repeat it which should provide sufficient redundancy to recover the true bits. No matter what I do I don't seem to be able to recover the bits at the decode stage. I've tried including / excluding various checks (even if it degrades image quality for the time being). I've tried using fixed point vs. double arithmetic, moving the bit to encode, I suspect that the message bits are being lost during the IDCT back to image. Any thoughts or suggestions on how to get this working would be hugely appreciated. (PS I am aware that the actual DCT/IDCT could be optimized from it's naive On4 operation using row column algorithm, or an FDCT like AAN, but for now it just needs to work :) ) Reference Papers: http://www.lokminglui.com/dct.pdf http://arxiv.org/ftp/arxiv/papers/1006/1006.1186.pdf Code for the Encode/Decode process in C# below: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing.Imaging; using System.Drawing; namespace ImageKey { public class Encoder { public const int HIDE_BIT_POS = 3; // use bit position 4 (1 << 3). public const int HIDE_COUNT = 16; // Number of times to repeat the message to avoid error. // JPEG Standard Quantization Matrix. // (to get higher quality multiply by (100-quality)/50 .. // for lower than 50 multiply by 50/quality. Then round to integers and clip to ensure only positive integers. public static double[] Q = {16,11,10,16,24,40,51,61, 12,12,14,19,26,58,60,55, 14,13,16,24,40,57,69,56, 14,17,22,29,51,87,80,62, 18,22,37,56,68,109,103,77, 24,35,55,64,81,104,113,92, 49,64,78,87,103,121,120,101, 72,92,95,98,112,100,103,99}; // Maximum qauality quantization matrix (if all 1's doesn't modify coefficients at all). public static double[] Q2 = {1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1}; public static Bitmap Encode(Bitmap b, string key) { Bitmap response = new Bitmap(b.Width, b.Height, PixelFormat.Format32bppArgb); uint imgWidth = ((uint)b.Width) & ~((uint)7); // Maximum usable X resolution (divisible by 8). uint imgHeight = ((uint)b.Height) & ~((uint)7); // Maximum usable Y resolution (divisible by 8). // Start be transferring the unmodified image portions. // As we'll be using slightly less width/height for the encoding process we'll need the edges to be populated. for (int y = 0; y < b.Height; y++) for (int x = 0; x < b.Width; x++) { if( (x >= imgWidth && x < b.Width) || (y>=imgHeight && y < b.Height)) response.SetPixel(x, y, b.GetPixel(x, y)); } // Setup the counters and byte data for the message to encode. StringBuilder sb = new StringBuilder(); for(int i=0;i<HIDE_COUNT;i++) sb.Append(key); byte[] codeBytes = System.Text.Encoding.ASCII.GetBytes(sb.ToString()); int bitofs = 0; // Current bit position we've encoded too. int totalBits = (codeBytes.Length * 8); // Total number of bits to encode. for (int y = 0; y < imgHeight; y += 8) { for (int x = 0; x < imgWidth; x += 8) { int[] redData = GetRedChannelData(b, x, y); int[] greenData = GetGreenChannelData(b, x, y); int[] blueData = GetBlueChannelData(b, x, y); int[] newRedData; int[] newGreenData; int[] newBlueData; if (bitofs < totalBits) { double[] redDCT = DCT(ref redData); double[] greenDCT = DCT(ref greenData); double[] blueDCT = DCT(ref blueData); int[] redDCTI = Quantize(ref redDCT, ref Q2); int[] greenDCTI = Quantize(ref greenDCT, ref Q2); int[] blueDCTI = Quantize(ref blueDCT, ref Q2); int[] blueDCTC = Quantize(ref blueDCT, ref Q); HideBits(ref blueDCTI, ref blueDCTC, ref bitofs, ref totalBits, ref codeBytes); double[] redDCT2 = DeQuantize(ref redDCTI, ref Q2); double[] greenDCT2 = DeQuantize(ref greenDCTI, ref Q2); double[] blueDCT2 = DeQuantize(ref blueDCTI, ref Q2); newRedData = IDCT(ref redDCT2); newGreenData = IDCT(ref greenDCT2); newBlueData = IDCT(ref blueDCT2); } else { newRedData = redData; newGreenData = greenData; newBlueData = blueData; } MapToRGBRange(ref newRedData); MapToRGBRange(ref newGreenData); MapToRGBRange(ref newBlueData); for(int dy=0;dy<8;dy++) { for(int dx=0;dx<8;dx++) { int col = (0xff<<24) + (newRedData[dx+(dy*8)]<<16) + (newGreenData[dx+(dy*8)]<<8) + (newBlueData[dx+(dy*8)]); response.SetPixel(x+dx,y+dy,Color.FromArgb(col)); } } } } if (bitofs < totalBits) throw new Exception("Failed to encode data - insufficient cover image coefficients"); return (response); } public static void HideBits(ref int[] DCTMatrix, ref int[] CMatrix, ref int bitofs, ref int totalBits, ref byte[] codeBytes) { int tempValue = 0; for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { if ( (u != 0 || v != 0) && CMatrix[v+(u*8)] != 0 && DCTMatrix[v+(u*8)] != 0) { if (bitofs < totalBits) { tempValue = DCTMatrix[v + (u * 8)]; int bytePos = (bitofs) >> 3; int bitPos = (bitofs) % 8; byte mask = (byte)(1 << bitPos); byte value = (byte)((codeBytes[bytePos] & mask) >> bitPos); // 0 or 1. if (value == 0) { int a = DCTMatrix[v + (u * 8)] & (1 << HIDE_BIT_POS); if (a != 0) DCTMatrix[v + (u * 8)] |= (1 << HIDE_BIT_POS) - 1; DCTMatrix[v + (u * 8)] &= ~(1 << HIDE_BIT_POS); } else if (value == 1) { int a = DCTMatrix[v + (u * 8)] & (1 << HIDE_BIT_POS); if (a == 0) DCTMatrix[v + (u * 8)] &= ~((1 << HIDE_BIT_POS) - 1); DCTMatrix[v + (u * 8)] |= (1 << HIDE_BIT_POS); } if (DCTMatrix[v + (u * 8)] != 0) bitofs++; else DCTMatrix[v + (u * 8)] = tempValue; } } } } } public static void MapToRGBRange(ref int[] data) { for(int i=0;i<data.Length;i++) { data[i] += 128; if(data[i] < 0) data[i] = 0; else if(data[i] > 255) data[i] = 255; } } public static int[] GetRedChannelData(Bitmap b, int sx, int sy) { int[] data = new int[8 * 8]; for (int y = sy; y < (sy + 8); y++) { for (int x = sx; x < (sx + 8); x++) { uint col = (uint)b.GetPixel(x,y).ToArgb(); data[(x - sx) + ((y - sy) * 8)] = (int)((col >> 16) & 0xff) - 128; } } return (data); } public static int[] GetGreenChannelData(Bitmap b, int sx, int sy) { int[] data = new int[8 * 8]; for (int y = sy; y < (sy + 8); y++) { for (int x = sx; x < (sx + 8); x++) { uint col = (uint)b.GetPixel(x, y).ToArgb(); data[(x - sx) + ((y - sy) * 8)] = (int)((col >> 8) & 0xff) - 128; } } return (data); } public static int[] GetBlueChannelData(Bitmap b, int sx, int sy) { int[] data = new int[8 * 8]; for (int y = sy; y < (sy + 8); y++) { for (int x = sx; x < (sx + 8); x++) { uint col = (uint)b.GetPixel(x, y).ToArgb(); data[(x - sx) + ((y - sy) * 8)] = (int)((col >> 0) & 0xff) - 128; } } return (data); } public static int[] Quantize(ref double[] DCTMatrix, ref double[] Q) { int[] DCTMatrixOut = new int[8*8]; for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { DCTMatrixOut[v + (u * 8)] = (int)Math.Round(DCTMatrix[v + (u * 8)] / Q[v + (u * 8)]); } } return(DCTMatrixOut); } public static double[] DeQuantize(ref int[] DCTMatrix, ref double[] Q) { double[] DCTMatrixOut = new double[8*8]; for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { DCTMatrixOut[v + (u * 8)] = (double)DCTMatrix[v + (u * 8)] * Q[v + (u * 8)]; } } return(DCTMatrixOut); } public static double[] DCT(ref int[] data) { double[] DCTMatrix = new double[8 * 8]; for (int v = 0; v < 8; v++) { for (int u = 0; u < 8; u++) { double cu = 1; if (u == 0) cu = (1.0 / Math.Sqrt(2.0)); double cv = 1; if (v == 0) cv = (1.0 / Math.Sqrt(2.0)); double sum = 0.0; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { double s = data[x + (y * 8)]; double dctVal = Math.Cos((2 * y + 1) * v * Math.PI / 16) * Math.Cos((2 * x + 1) * u * Math.PI / 16); sum += s * dctVal; } } DCTMatrix[u + (v * 8)] = (0.25 * cu * cv * sum); } } return (DCTMatrix); } public static int[] IDCT(ref double[] DCTMatrix) { int[] Matrix = new int[8 * 8]; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { double sum = 0; for (int v = 0; v < 8; v++) { for (int u = 0; u < 8; u++) { double cu = 1; if (u == 0) cu = (1.0 / Math.Sqrt(2.0)); double cv = 1; if (v == 0) cv = (1.0 / Math.Sqrt(2.0)); double idctVal = (cu * cv) / 4.0 * Math.Cos((2 * y + 1) * v * Math.PI / 16) * Math.Cos((2 * x + 1) * u * Math.PI / 16); sum += (DCTMatrix[u + (v * 8)] * idctVal); } } Matrix[x + (y * 8)] = (int)Math.Round(sum); } } return (Matrix); } } public class Decoder { public static string Decode(Bitmap b, int expectedLength) { expectedLength *= Encoder.HIDE_COUNT; uint imgWidth = ((uint)b.Width) & ~((uint)7); // Maximum usable X resolution (divisible by 8). uint imgHeight = ((uint)b.Height) & ~((uint)7); // Maximum usable Y resolution (divisible by 8). // Setup the counters and byte data for the message to decode. byte[] codeBytes = new byte[expectedLength]; byte[] outBytes = new byte[expectedLength / Encoder.HIDE_COUNT]; int bitofs = 0; // Current bit position we've decoded too. int totalBits = (codeBytes.Length * 8); // Total number of bits to decode. for (int y = 0; y < imgHeight; y += 8) { for (int x = 0; x < imgWidth; x += 8) { int[] blueData = ImageKey.Encoder.GetBlueChannelData(b, x, y); double[] blueDCT = ImageKey.Encoder.DCT(ref blueData); int[] blueDCTI = ImageKey.Encoder.Quantize(ref blueDCT, ref Encoder.Q2); int[] blueDCTC = ImageKey.Encoder.Quantize(ref blueDCT, ref Encoder.Q); if (bitofs < totalBits) GetBits(ref blueDCTI, ref blueDCTC, ref bitofs, ref totalBits, ref codeBytes); } } bitofs = 0; for (int i = 0; i < (expectedLength / Encoder.HIDE_COUNT) * 8; i++) { int bytePos = (bitofs) >> 3; int bitPos = (bitofs) % 8; byte mask = (byte)(1 << bitPos); List<int> values = new List<int>(); int zeroCount = 0; int oneCount = 0; for (int j = 0; j < Encoder.HIDE_COUNT; j++) { int val = (codeBytes[bytePos + ((expectedLength / Encoder.HIDE_COUNT) * j)] & mask) >> bitPos; values.Add(val); if (val == 0) zeroCount++; else oneCount++; } if (oneCount >= zeroCount) outBytes[bytePos] |= mask; bitofs++; values.Clear(); } return (System.Text.Encoding.ASCII.GetString(outBytes)); } public static void GetBits(ref int[] DCTMatrix, ref int[] CMatrix, ref int bitofs, ref int totalBits, ref byte[] codeBytes) { for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { if ((u != 0 || v != 0) && CMatrix[v + (u * 8)] != 0 && DCTMatrix[v + (u * 8)] != 0) { if (bitofs < totalBits) { int bytePos = (bitofs) >> 3; int bitPos = (bitofs) % 8; byte mask = (byte)(1 << bitPos); int value = DCTMatrix[v + (u * 8)] & (1 << Encoder.HIDE_BIT_POS); if (value != 0) codeBytes[bytePos] |= mask; bitofs++; } } } } } } } UPDATE: By switching to using a QR Code as the source message and swapping a pair of coefficients in each block instead of bit manipulation I've been able to get the message to survive the transform. However to get the message to come through without corruption I have to adjust both coefficients as well as swap them. For example swapping (3,4) and (4,3) in the DCT matrix and then respectively adding 8 and subtracting 8 as an arbitrary constant seems to work. This survives a re-JPEG'ing of 96 but any form of scaling/cropping destroys the message again. I was hoping that by operating on mid to low frequency values that the message would be preserved even under some light image manipulation.

    Read the article

  • Silverlight Recruiting Application Part 6 - Adding an Interview Scheduling Module/View

    Between the last post and this one I went ahead and carried the ideas for the Jobs module and view into the Applicants module and view- they're both doing more or less the same thing, except with different objects being at their core.  Made for an easy cut-and-paste operation with a few items being switched from one to another.  Now that we have the ability to add postings and applicants, wouldn't it be nice if we could schedule an interview?  Of course it would! Scheduling Module I think you get the drift from previous posts that these project structures start looking somewhat similar.  The interview scheduling module is no different than the rest- it gets a SchedulingModule.cs file at the root that inherits from IModule, and there is a single SchedulerView.xsml and SchedulerViewModel.cs setup for our V+VM.  We have one unique concern as we enter into this- RadScheduler deals with AppointmentsSource, not ItemsSource, so there are some special considerations to take into account when planning this module. First, I need something which inherits from AppointmentBase.  This is the core of the RadScheduler appointment, and if you are planning to do any form of custom appointment, you'll want it to inherit from this.  Then you can add-on functionality as needed.  Here is my addition to the mix, the InterviewAppointment: 01.public class InterviewAppointment : AppointmentBase 02.{ 03.    private int _applicantID; 04.    public int ApplicantID 05.    { 06.        get { return this._applicantID; } 07.        set 08.        { 09.            if (_applicantID != value) 10.            { 11.                _applicantID = value; 12.                OnPropertyChanged("ApplicantID"); 13.            } 14.        } 15.    } 16.   17.    private int _postingID; 18.    public int PostingID 19.    { 20.        get { return _postingID; } 21.        set 22.        { 23.            if (_postingID != value) 24.            { 25.                _postingID = value; 26.                OnPropertyChanged("PostingID"); 27.            } 28.        } 29.    } 30.   31.    private string _body; 32.    public string Body 33.    { 34.        get { return _body; } 35.        set 36.        { 37.            if (_body != value) 38.            { 39.                _body = value; 40.                OnPropertyChanged("Body"); 41.            } 42.        } 43.    } 44.   45.    private int _interviewID; 46.    public int InterviewID 47.    { 48.        get { return _interviewID; } 49.        set 50.        { 51.            if (_interviewID != value) 52.            { 53.                _interviewID = value; 54.                OnPropertyChanged("InterviewID"); 55.            } 56.        } 57.    } 58.   59.    public override IAppointment Copy() 60.    { 61.        IAppointment appointment = new InterviewAppointment(); 62.        appointment.CopyFrom(this);             63.        return appointment; 64.    } 65.   66.    public override void CopyFrom(IAppointment other) 67.    {             68.        base.CopyFrom(other); 69.        var appointment = other as InterviewAppointment; 70.        if (appointment != null) 71.        { 72.            ApplicantID = appointment.ApplicantID; 73.            PostingID = appointment.PostingID; 74.            Body = appointment.Body; 75.            InterviewID = appointment.InterviewID; 76.        } 77.    } 78.} Nothing too exciting going on here, we just make sure that our custom fields are persisted (specifically set in CopyFrom at the bottom) and notifications are fired- otherwise this ends up exactly like the standard appointment as far as interactions, etc.  But if we've got custom appointment items... that also means we need to customize what our appointment dialog window will look like. Customizing the Edit Appointment Dialog This initially sounds a lot more intimidating than it really is.  The first step here depends on what you're dealing with for theming, but for ease of everything I went ahead and extracted my templates in Blend for RadScheduler so I could modify it as I pleased.  For the faint of heart, the RadScheduler template is a few thousand lines of goodness since there are some very complex things going on in that control.  I've gone ahead and trimmed down the template parts I don't need as much as possible, so what is left is all that is relevant to the Edit Appointment Dialog.  Here's the resulting Xaml, with line numbers, so I can explain further: 001.<UserControl.Resources> 002.    <!-- begin Necessary Windows 7 Theme Resources for EditAppointmentTemplate --> 003.    <helpers:DataContextProxy x:Key="DataContextProxy" /> 004.       005.    <telerik:Windows7Theme x:Key="Theme" /> 006.    <SolidColorBrush x:Key="DialogWindowBackground" 007.                     Color="White" /> 008.    <SolidColorBrush x:Key="CategorySelectorBorderBrush" 009.                     Color="#FFB1B1B1" /> 010.    <LinearGradientBrush x:Key="RadToolBar_InnerBackground" 011.                         EndPoint="0.5,1" 012.                         StartPoint="0.5,0"> 013.        <GradientStop Color="#FFFDFEFF" 014.                      Offset="0" /> 015.        <GradientStop Color="#FFDDE9F7" 016.                      Offset="1" /> 017.        <GradientStop Color="#FFE6F0FA" 018.                      Offset="0.5" /> 019.        <GradientStop Color="#FFDCE6F4" 020.                      Offset="0.5" /> 021.    </LinearGradientBrush> 022.    <Style x:Key="FormElementTextBlockStyle" 023.           TargetType="TextBlock"> 024.        <Setter Property="HorizontalAlignment" 025.                Value="Right" /> 026.        <Setter Property="VerticalAlignment" 027.                Value="Top" /> 028.        <Setter Property="Margin" 029.                Value="15, 15, 0, 2" /> 030.    </Style> 031.    <Style x:Key="FormElementStyle" 032.           TargetType="FrameworkElement"> 033.        <Setter Property="Margin" 034.                Value="10, 10, 0, 2" /> 035.    </Style> 036.    <SolidColorBrush x:Key="GenericShallowBorderBrush" 037.                     Color="#FF979994" /> 038.    <telerik:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 039.    <telerikScheduler:ImportanceToBooleanConverter x:Key="ImportanceToBooleanConverter" /> 040.    <telerikScheduler:NullToVisibilityConverter x:Key="NullToVisibilityConverter" /> 041.    <telerikScheduler:InvertedNullToVisibilityConverter x:Key="InvertedNullToVisibilityConverter" /> 042.    <scheduler:ResourcesSeparatorConverter x:Key="ResourcesSeparatorConverter" /> 043.    <DataTemplate x:Key="IconDataEditTemplate"> 044.        <Image Source="/Telerik.Windows.Controls.Scheduler;component/Themes/Office/Images/cal.png" 045.               Margin="3,3,0,0" 046.               Width="16" 047.               Height="16" /> 048.    </DataTemplate> 049.    <DataTemplate x:Key="SingleSelectionTemplate"> 050.        <Grid VerticalAlignment="Stretch" 051.              HorizontalAlignment="Stretch"> 052.            <Grid.RowDefinitions> 053.                <RowDefinition Height="Auto" /> 054.            </Grid.RowDefinitions> 055.            <Grid.ColumnDefinitions> 056.                <ColumnDefinition Width="Auto" 057.                                  MinWidth="84" /> 058.                <ColumnDefinition Width="Auto" 059.                                  MinWidth="200" /> 060.            </Grid.ColumnDefinitions> 061.            <TextBlock x:Name="SelectionNameLabel" 062.                       Margin="0,13,4,2" 063.                       Text="{Binding ResourceType.DisplayName}" 064.                       Style="{StaticResource FormElementTextBlockStyle}" 065.                       Grid.Column="0" /> 066.            <telerikInput:RadComboBox ItemsSource="{Binding ResourceItems}" 067.                                      Width="185" 068.                                      Margin="5,10,20,2" 069.                                      HorizontalAlignment="Left" 070.                                      Grid.Column="1" 071.                                      ClearSelectionButtonVisibility="Visible" 072.                                      ClearSelectionButtonContent="Clear All" 073.                                      DisplayMemberPath="Resource.DisplayName" 074.                                      telerik:StyleManager.Theme="{StaticResource Theme}" 075.                                      SelectedItem="{Binding SelectedItem, Mode=TwoWay}" /> 076.        </Grid> 077.    </DataTemplate> 078.    <DataTemplate x:Key="MultipleSelectionTemplate"> 079.        <Grid VerticalAlignment="Stretch" 080.              HorizontalAlignment="Stretch"> 081.            <Grid.RowDefinitions> 082.                <RowDefinition Height="Auto" /> 083.            </Grid.RowDefinitions> 084.            <Grid.ColumnDefinitions> 085.                <ColumnDefinition Width="Auto" 086.                                  MinWidth="84" /> 087.                <ColumnDefinition Width="Auto" 088.                                  MinWidth="200" /> 089.            </Grid.ColumnDefinitions> 090.            <TextBlock x:Name="SelectionNameLabel" 091.                       Grid.Column="0" 092.                       Text="{Binding ResourceType.DisplayName}" 093.                       Margin="0,13,4,2" 094.                       Style="{StaticResource FormElementTextBlockStyle}" /> 095.            <telerikInput:RadComboBox Grid.Column="1" 096.                                      Width="185" 097.                                      HorizontalAlignment="Left" 098.                                      Margin="5,10,20,2" 099.                                      ItemsSource="{Binding ResourceItems}" 100.                                      SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}" 101.                                      ClearSelectionButtonVisibility="Visible" 102.                                      ClearSelectionButtonContent="Clear All" 103.                                      telerik:StyleManager.Theme="{StaticResource Theme}"> 104.                <telerikInput:RadComboBox.ItemTemplate> 105.                    <DataTemplate> 106.                        <Grid HorizontalAlignment="Stretch" 107.                              VerticalAlignment="Stretch"> 108.                            <CheckBox VerticalAlignment="Center" 109.                                      HorizontalContentAlignment="Stretch" 110.                                      VerticalContentAlignment="Center" 111.                                      IsChecked="{Binding IsChecked, Mode=TwoWay}" 112.                                      Content="{Binding Resource.DisplayName}"> 113.                                <CheckBox.ContentTemplate> 114.                                    <DataTemplate> 115.                                        <TextBlock HorizontalAlignment="Stretch" 116.                                                   VerticalAlignment="Stretch" 117.                                                   Text="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" /> 118.                                    </DataTemplate> 119.                                </CheckBox.ContentTemplate> 120.                            </CheckBox> 121.                        </Grid> 122.                    </DataTemplate> 123.                </telerikInput:RadComboBox.ItemTemplate> 124.            </telerikInput:RadComboBox> 125.        </Grid> 126.    </DataTemplate> 127.    <scheduler:ResourceTypeTemplateSelector x:Key="ItemTemplateSelector" 128.                                            MultipleSelectionTemplate="{StaticResource MultipleSelectionTemplate}" 129.                                            SingleSelectionTemplate="{StaticResource SingleSelectionTemplate}" /> 130.    <!-- end Necessary Windows 7 Theme Resources for EditAppointmentTemplate -->  131.       132.    <ControlTemplate x:Key="EditAppointmentTemplate" 133.                     TargetType="telerikScheduler:AppointmentDialogWindow"> 134.        <StackPanel Background="{TemplateBinding Background}" 135.                    UseLayoutRounding="True"> 136.            <StackPanel Grid.Row="0" 137.                        Orientation="Horizontal" 138.                        Background="{StaticResource RadToolBar_InnerBackground}" 139.                        Grid.ColumnSpan="2" 140.                        Height="0"> 141.                <!-- Recurrence buttons --> 142.                <Border Margin="1,1,0,0" 143.                        Background="#50000000" 144.                        HorizontalAlignment="Left" 145.                        VerticalAlignment="Center" 146.                        Width="2" 147.                        Height="16"> 148.                    <Border Margin="0,0,1,1" 149.                            Background="#80FFFFFF" 150.                            HorizontalAlignment="Left" 151.                            Width="1" /> 152.                </Border> 153.                <Border Margin="1,1,0,0" 154.                        Background="#50000000" 155.                        HorizontalAlignment="Left" 156.                        VerticalAlignment="Center" 157.                        Width="2" 158.                        Height="16"> 159.                    <Border Margin="0,0,1,1" 160.                            Background="#80FFFFFF" 161.                            HorizontalAlignment="Left" 162.                            Width="1" /> 163.                </Border> 164.                <TextBlock telerik:LocalizationManager.ResourceKey="ShowAs" 165.                           VerticalAlignment="Center" 166.                           Margin="5,0,0,0" /> 167.                <telerikInput:RadComboBox ItemsSource="{TemplateBinding TimeMarkers}" 168.                                          Width="100" 169.                                          Height="20" 170.                                          VerticalAlignment="Center" 171.                                          Margin="5,0,0,0" 172.                                          ClearSelectionButtonVisibility="Visible" 173.                                          ClearSelectionButtonContent="Clear" 174.                                          SelectedItem="{Binding TimeMarker,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" 175.                                          telerik:StyleManager.Theme="{StaticResource Theme}"> 176.                    <telerikInput:RadComboBox.ItemTemplate> 177.                        <DataTemplate> 178.                            <StackPanel Orientation="Horizontal"> 179.                                <Rectangle Fill="{Binding TimeMarkerBrush}" 180.                                           Margin="2" 181.                                           Width="12" 182.                                           Height="12" /> 183.                                <TextBlock Text="{Binding TimeMarkerName}" 184.                                           Margin="2" /> 185.                            </StackPanel> 186.                        </DataTemplate> 187.                    </telerikInput:RadComboBox.ItemTemplate> 188.                </telerikInput:RadComboBox> 189.                <telerik:RadToggleButton x:Name="High" 190.                                         BorderThickness="0" 191.                                         Background="{StaticResource RadToolBar_InnerBackground}" 192.                                         DataContext="{TemplateBinding EditedAppointment}" 193.                                         telerik:StyleManager.Theme="{StaticResource Theme}" 194.                                         IsChecked="{Binding Importance,Mode=TwoWay, Converter={StaticResource ImportanceToBooleanConverter},ConverterParameter=High}" 195.                                         Margin="2,2,0,2" 196.                                         Width="23" 197.                                         Height="23" 198.                                         HorizontalContentAlignment="Center" 199.                                         ToolTipService.ToolTip="High importance" 200.                                         CommandParameter="High" 201.                                         Command="telerikScheduler:RadSchedulerCommands.SetAppointmentImportance"> 202.                    <StackPanel HorizontalAlignment="Center"> 203.                        <Path Stretch="Fill" 204.                              Height="10" 205.                              HorizontalAlignment="Center" 206.                              VerticalAlignment="Top" 207.                              Width="5.451" 208.                              Data="M200.39647,58.840393 C200.39337,58.336426 201.14566,57.683922 202.56244,57.684292 C204.06589,57.684685 204.73764,58.357765 204.72783,58.992363 C205.04649,61.795574 203.04713,64.181099 202.47388,66.133446 C201.93753,64.154961 199.9471,61.560352 200.39647,58.840393 z"> 209.                            <Path.Fill> 210.                                <LinearGradientBrush EndPoint="1.059,0.375" 211.                                                     StartPoint="-0.457,0.519"> 212.                                    <GradientStop Color="#FFFF0606" 213.                                                  Offset="0.609" /> 214.                                    <GradientStop Color="#FFBF0303" 215.                                                  Offset="0.927" /> 216.                                </LinearGradientBrush> 217.                            </Path.Fill> 218.                        </Path> 219.                        <Ellipse Height="3" 220.                                 HorizontalAlignment="Center" 221.                                 Margin="0,-1,0,0" 222.                                 VerticalAlignment="Top" 223.                                 Width="3"> 224.                            <Ellipse.Fill> 225.                                <RadialGradientBrush> 226.                                    <GradientStop Color="#FFFF0606" 227.                                                  Offset="0" /> 228.                                    <GradientStop Color="#FFBF0303" 229.                                                  Offset="1" /> 230.                                </RadialGradientBrush> 231.                            </Ellipse.Fill> 232.                        </Ellipse> 233.                    </StackPanel> 234.                </telerik:RadToggleButton> 235.                <telerik:RadToggleButton x:Name="Low" 236.                                         HorizontalContentAlignment="Center" 237.                                         BorderThickness="0" 238.                                         Background="{StaticResource RadToolBar_InnerBackground}" 239.                                         DataContext="{TemplateBinding EditedAppointment}" 240.                                         IsChecked="{Binding Importance,Mode=TwoWay, Converter={StaticResource ImportanceToBooleanConverter},ConverterParameter=Low}" 241.                                         Margin="0,2,0,2" 242.                                         Width="23" 243.                                         Height="23" 244.                                         ToolTipService.ToolTip="Low importance" 245.                                         CommandParameter="Low" 246.                                         telerik:StyleManager.Theme="{StaticResource Theme}" 247.                                         Command="telerikScheduler:RadSchedulerCommands.SetAppointmentImportance"> 248.                    <Path Stretch="Fill" 249.                          Height="12" 250.                          HorizontalAlignment="Center" 251.                          VerticalAlignment="Top" 252.                          Width="9" 253.                          Data="M222.40353,60.139881 L226.65768,60.139843 L226.63687,67.240196 L229.15347,67.240196 L224.37816,71.394943 L219.65274,67.240196 L222.37572,67.219345 z" 254.                          Stroke="#FF0365A7"> 255.                        <Path.Fill> 256.                            <LinearGradientBrush EndPoint="1.059,0.375" 257.                                                 StartPoint="-0.457,0.519"> 258.                                <GradientStop Color="#FFBBE4FF" /> 259.                                <GradientStop Color="#FF024572" 260.                                              Offset="0.836" /> 261.                                <GradientStop Color="#FF43ADF4" 262.                                              Offset="0.466" /> 263.                            </LinearGradientBrush> 264.                        </Path.Fill> 265.                    </Path> 266.                </telerik:RadToggleButton> 267.            </StackPanel > 268.            <Border DataContext="{TemplateBinding EditedAppointment}" 269.                    Background="{Binding Category.CategoryBrush}" 270.                    Visibility="{Binding Category,Converter={StaticResource NullToVisibilityConverter}}" 271.                    CornerRadius="3" 272.                    Height="20" 273.                    Margin="5,10,5,0"> 274.                <TextBlock Text="{Binding Category.DisplayName}" 275.                           VerticalAlignment="Center" 276.                           Margin="5,0,0,0" /> 277.            </Border> 278.            <Grid VerticalAlignment="Stretch" 279.                  HorizontalAlignment="Stretch" 280.                  DataContext="{TemplateBinding EditedAppointment}" 281.                  Background="{TemplateBinding Background}"> 282.                <Grid.RowDefinitions> 283.                    <RowDefinition Height="Auto" /> 284.                    <RowDefinition Height="Auto" /> 285.                    <RowDefinition Height="Auto" /> 286.                    <RowDefinition Height="Auto" /> 287.                    <RowDefinition Height="Auto" /> 288.                    <RowDefinition Height="Auto" /> 289.                    <RowDefinition Height="Auto" /> 290.                    <RowDefinition Height="Auto" /> 291.                    <RowDefinition Height="Auto" /> 292.                    <RowDefinition Height="Auto" /> 293.                </Grid.RowDefinitions> 294.                <Grid.ColumnDefinitions> 295.                    <ColumnDefinition Width="Auto" 296.                                      MinWidth="100" /> 297.                    <ColumnDefinition Width="Auto" 298.                                      MinWidth="200" /> 299.                </Grid.ColumnDefinitions> 300.                <!-- Subject --> 301.                <TextBlock x:Name="SubjectLabel" 302.                           Grid.Row="0" 303.                           Grid.Column="0" 304.                           Margin="0,15,0,2" 305.                           telerik:LocalizationManager.ResourceKey="Subject" 306.                           Style="{StaticResource FormElementTextBlockStyle}" /> 307.                <TextBox x:Name="Subject" 308.                         Grid.Row="0" 309.                         Grid.Column="1" 310.                         MinHeight="22" 311.                         Padding="4 2" 312.                         Width="340" 313.                         HorizontalAlignment="Left" 314.                         Text="{Binding Subject, Mode=TwoWay}" 315.                         MaxLength="255" 316.                         telerik:StyleManager.Theme="{StaticResource Theme}" 317.                         Margin="10,12,20,2" /> 318.                <!-- Description --> 319.                <TextBlock x:Name="DescriptionLabel" 320.                           Grid.Row="1" 321.                           Grid.Column="0" 322.                           Margin="0,13,0,2" 323.                           telerik:LocalizationManager.ResourceKey="Body" 324.                           Style="{StaticResource FormElementTextBlockStyle}" /> 325.                <TextBox x:Name="Body" 326.                         VerticalAlignment="top" 327.                         Grid.Row="1" 328.                         Grid.Column="1" 329.                         Height="Auto" 330.                         MaxHeight="82" 331.                         Width="340" 332.                         HorizontalAlignment="Left" 333.                         MinHeight="22" 334.                         Padding="4 2" 335.                         TextWrapping="Wrap" 336.                         telerik:StyleManager.Theme="{StaticResource Theme}" 337.                         Text="{Binding Body, Mode=TwoWay}" 338.                         AcceptsReturn="true" 339.                         Margin="10,10,20,2" 340.                         HorizontalScrollBarVisibility="Auto" 341.                         VerticalScrollBarVisibility="Auto" /> 342.                <!-- Start/End date --> 343.                <TextBlock x:Name="StartDateLabel" 344.                           Grid.Row="2" 345.                           Grid.Column="0" 346.                           Margin="0,13,0,2" 347.                           telerik:LocalizationManager.ResourceKey="StartTime" 348.                           Style="{StaticResource FormElementTextBlockStyle}" /> 349.                <telerikScheduler:DateTimePicker x:Name="StartDateTime" 350.                                                 Height="22" 351.                                                 Grid.Row="2" 352.                                                 Grid.Column="1" 353.                                                 HorizontalAlignment="Left" 354.                                                 Margin="10,10,20,2" 355.                                                 Style="{StaticResource FormElementStyle}" 356.                                                 SelectedDateTime="{Binding Start, Mode=TwoWay}" 357.                                                 telerikScheduler:StartEndDatePicker.EndPicker="{Binding ElementName=EndDateTime}" 358.                                                 IsTabStop="False" 359.                                                 IsEnabled="False" /> 360.                <TextBlock x:Name="EndDateLabel" 361.                           Grid.Row="3" 362.                           Grid.Column="0" 363.                           Margin="0,13,0,2" 364.                           telerik:LocalizationManager.ResourceKey="EndTime" 365.                           Style="{StaticResource FormElementTextBlockStyle}" /> 366.                <telerikScheduler:DateTimePicker x:Name="EndDateTime" 367.                                                 Height="22" 368.                                                 Grid.Row="3" 369.                                                 Grid.Column="1" 370.                                                 HorizontalAlignment="Left" 371.                                                 Margin="10,10,20,2" 372.                                                 Style="{StaticResource FormElementStyle}" 373.                                                 IsTabStop="False" 374.                                                 IsEnabled="False" 375.                                                 SelectedDateTime="{Binding End, Mode=TwoWay}" /> 376.                <!-- Is-all-day selector --> 377.                <CheckBox x:Name="AllDayEventCheckbox" 378.                          IsChecked="{Binding IsAllDayEvent, Mode=TwoWay}" 379.                          Grid.Row="4" 380.                          Grid.Column="1" 381.                          Margin="10,10,20,2" 382.                          HorizontalAlignment="Left" 383.                          telerik:StyleManager.Theme="{StaticResource Theme}" 384.                          telerik:LocalizationManager.ResourceKey="AllDayEvent"> 385.                    <telerik:CommandManager.InputBindings> 386.                        <telerik:InputBindingCollection> 387.                            <telerik:MouseBinding Command="telerikScheduler:RadSchedulerCommands.ChangeTimePickersVisibility" 388.                                                  Gesture="LeftClick" /> 389.                        </telerik:InputBindingCollection> 390.                    </telerik:CommandManager.InputBindings> 391.                </CheckBox> 392.                <Grid Grid.Row="5" 393.                      Grid.ColumnSpan="2"> 394.                    <Grid.ColumnDefinitions> 395.                        <ColumnDefinition Width="Auto" 396.                                          MinWidth="100" /> 397.                        <ColumnDefinition Width="Auto" 398.                                          MinWidth="200" /> 399.                    </Grid.ColumnDefinitions> 400.                    <Grid.RowDefinitions> 401.                        <RowDefinition Height="Auto" /> 402.                        <RowDefinition Height="Auto" /> 403.                    </Grid.RowDefinitions> 404.                    <TextBlock Text="Applicant" 405.                               Margin="0,13,0,2" 406.                               Style="{StaticResource FormElementTextBlockStyle}" /> 407.                    <telerikInput:RadComboBox IsEditable="False" 408.                                              Grid.Column="1" 409.                                              Height="24" 410.                                              VerticalAlignment="Center" 411.                                              ItemsSource="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.ApplicantList}" 412.                                              SelectedValue="{Binding ApplicantID, Mode=TwoWay}" 413.                                              SelectedValuePath="ApplicantID" 414.                                              DisplayMemberPath="FirstName" /> 415.                       416.                    <TextBlock Text="Job" 417.                               Margin="0,13,0,2" 418.                               Grid.Row="1" 419.                               Style="{StaticResource FormElementTextBlockStyle}" /> 420.                    <telerikInput:RadComboBox IsEditable="False" 421.                                              Grid.Column="1" 422.                                              Grid.Row="1" 423.                                              Height="24" 424.                                              VerticalAlignment="Center" 425.                                              ItemsSource="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.JobsList}" 426.                                              SelectedValue="{Binding PostingID, Mode=TwoWay}" 427.                                              SelectedValuePath="PostingID" 428.                                              DisplayMemberPath="JobTitle"/> 429.                </Grid> 430.                    <!-- Resources --> 431.                <Grid x:Name="ResourcesLayout" 432.                      Grid.Row="7" 433.                      Grid.Column="0" 434.                      Grid.ColumnSpan="2" 435.                      MaxHeight="130" 436.                      Margin="20,5,20,0"> 437.                    <Border Margin="0" 438.                            BorderThickness="1" 439.                            BorderBrush="{StaticResource GenericShallowBorderBrush}" 440.                            Visibility="{Binding ElementName=ResourcesScrollViewer, Path=ComputedVerticalScrollBarVisibility}"></Border> 441.                    <ScrollViewer x:Name="ResourcesScrollViewer" 442.                                  IsTabStop="false" 443.                                  Grid.Row="6" 444.                                  Grid.Column="0" 445.                                  Grid.ColumnSpan="2" 446.                                  Margin="1" 447.                                  telerik:StyleManager.Theme="{StaticResource Theme}" 448.                                  VerticalScrollBarVisibility="Auto"> 449.                        <scheduler:ResourcesItemsControl x:Name="PART_Resources" 450.                                                         HorizontalAlignment="Left" 451.                                                         Padding="0,2,0,5" 452.                                                         IsTabStop="false" 453.                                                         ItemsSource="{TemplateBinding ResourceTypeModels}" 454.                                                         ItemTemplateSelector="{StaticResource ItemTemplateSelector}" /> 455.                    </ScrollViewer> 456.                </Grid> 457.                <StackPanel x:Name="FooterControls" 458.                            Margin="5 10 10 10" 459.                            Grid.Row="8" 460.                            Grid.Column="1" 461.                            HorizontalAlignment="Left" 462.                            Orientation="Horizontal"> 463.                    <telerik:RadButton x:Name="OKButton" 464.                                       Margin="5" 465.                                       Padding="10 0" 466.                                       MinWidth="80" 467.                                       Command="telerikScheduler:RadSchedulerCommands.SaveAppointment" 468.                                       telerik:StyleManager.Theme="{StaticResource Theme}" 469.                                       telerikNavigation:RadWindow.ResponseButton="Accept" 470.                                       telerik:LocalizationManager.ResourceKey="SaveAndCloseCommandText"> 471.                    </telerik:RadButton> 472.                    <telerik:RadButton x:Name="CancelButton" 473.                                       Margin="5" 474.                                       Padding="10 0" 475.                                       MinWidth="80" 476.                                       telerik:LocalizationManager.ResourceKey="Cancel" 477.                                       telerik:StyleManager.Theme="{StaticResource Theme}" 478.                                       telerikNavigation:RadWindow.ResponseButton="Cancel" 479.                                       Command="telerik:WindowCommands.Close"> 480.                    </telerik:RadButton> 481.                </StackPanel> 482.            </Grid> 483.            <vsm:VisualStateManager.VisualStateGroups> 484.                <vsm:VisualStateGroup x:Name="RecurrenceRuleState"> 485.                    <vsm:VisualState x:Name="RecurrenceRuleIsNull"> 486.                        <Storyboard> 487.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="StartDateTime" 488.                                                           Storyboard.TargetProperty="IsEnabled" 489.                                                           Duration="0"> 490.                                <DiscreteObjectKeyFrame KeyTime="0" 491.                                                        Value="True" /> 492.                            </ObjectAnimationUsingKeyFrames> 493.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="EndDateTime" 494.                                                           Storyboard.TargetProperty="IsEnabled" 495.                                                           Duration="0"> 496.                                <DiscreteObjectKeyFrame KeyTime="0" 497.                                                        Value="True" /> 498.                            </ObjectAnimationUsingKeyFrames> 499.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="AllDayEventCheckbox" 500.                                                           Storyboard.TargetProperty="IsEnabled" 501.                                                           Duration="0"> 502.                                <DiscreteObjectKeyFrame KeyTime="0" 503.                                                        Value="True" /> 504.                            </ObjectAnimationUsingKeyFrames> 505.                        </Storyboard> 506.                    </vsm:VisualState> 507.                    <vsm:VisualState x:Name="RecurrenceRuleIsNotNull"> 508.                        <Storyboard> 509.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="StartDateTime" 510.                                                           Storyboard.TargetProperty="IsEnabled" 511.                                                           Duration="0"> 512.                                <DiscreteObjectKeyFrame KeyTime="0" 513.                                                        Value="False" /> 514.                            </ObjectAnimationUsingKeyFrames> 515.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="EndDateTime" 516.                                                           Storyboard.TargetProperty="IsEnabled" 517.                                                           Duration="0"> 518.                                <DiscreteObjectKeyFrame KeyTime="0" 519.                                                        Value="False" /> 520.                            </ObjectAnimationUsingKeyFrames> 521.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="AllDayEventCheckbox" 522.                                                           Storyboard.TargetProperty="IsEnabled" 523.                                                           Duration="0"> 524.                                <DiscreteObjectKeyFrame KeyTime="0" 525.                                                        Value="False" /> 526.                            </ObjectAnimationUsingKeyFrames> 527.                        </Storyboard> 528.                    </vsm:VisualState> 529.                </vsm:VisualStateGroup> 530.            </vsm:VisualStateManager.VisualStateGroups> 531.        </StackPanel> 532.    </ControlTemplate> 533.    <DataTemplate x:Key="AppointmentDialogWindowHeaderDataTemplate"> 534.        <StackPanel Orientation="Horizontal" 535.                    MaxWidth="400"> 536.            <TextBlock telerik:LocalizationManager.ResourceKey="Event" 537.                       Visibility="{Binding Appointment.IsAllDayEvent, Converter={StaticResource BooleanToVisibilityConverter}}" /> 538.            <TextBlock telerik:LocalizationManager.ResourceKey="Appointment" 539.                       Visibility="{Binding Appointment.IsAllDayEvent, Converter={StaticResource InvertedBooleanToVisibilityConverter}}" /> 540.            <TextBlock Text=" - " /> 541.            <TextBlock x:Name="SubjectTextBlock" 542.                       Visibility="{Binding Appointment.Subject, Converter={StaticResource NullToVisibilityConverter}}" 543.                       Text="{Binding Appointment.Subject}" /> 544.            <TextBlock telerik:LocalizationManager.ResourceKey="Untitled" 545.                       Visibility="{Binding Appointment.Subject, Converter={StaticResource InvertedNullToVisibilityConverter}}" /> 546.        </StackPanel> 547.    </DataTemplate> 548.    <Style x:Key="EditAppointmentStyle" 549.           TargetType="telerikScheduler:AppointmentDialogWindow"> 550.        <Setter Property="IconTemplate" 551.                Value="{StaticResource IconDataEditTemplate}" /> 552.        <Setter Property="HeaderTemplate" 553.                Value="{StaticResource AppointmentDialogWindowHeaderDataTemplate}" /> 554.        <Setter Property="Background" 555.                Value="{StaticResource DialogWindowBackground}" /> 556.        <Setter Property="Template" 557.                Value="{StaticResource EditAppointmentTemplate}" /> 558.    </Style> 559.</UserControl.Resources> The first line there is the DataContextProxy I mentioned previously- we use that again to work a bit of magic in this template. Where we start getting into the dialog in question is line 132, but line 407 is where things start getting interesting.  The ItemsSource is pointing at a list that exists in my ViewModel (or code-behind, if it is used as a DataContext), the SelectedValue is the item I am actually binding from the applicant (note the TwoWay binding), and SelectedValuePath and DisplayMemberPath ensure the proper applicant is being displayed from the collection.  You will also see similar starting on line 420 where I do the same for the Jobs we'll be displaying. Just to wrap-up the Xaml, here's the RadScheduler declaraction that ties this all together and will be the main focus of our view: 01.<telerikScheduler:RadScheduler x:Name="xJobsScheduler" 02.                  Grid.Row="1" 03.                  Grid.Column="1" 04.                  Width="800" 05.                  MinWidth="600" 06.                  Height="500" 07.                  MinHeight="300" 08.                  AppointmentsSource="{Binding Interviews}" 09.                  EditAppointmentStyle="{StaticResource EditAppointmentStyle}" 10.                  command:AppointmentAddedEventClass.Command="{Binding AddAppointmentCommand}" 11.                  command:ApptCreatedEventClass.Command="{Binding ApptCreatingCommand}" 12.                  command:ApptEditedEventClass.Command="{Binding ApptEditedCommand}" 13.                  command:ApptDeletedEventClass.Command="{Binding ApptDeletedCommand}"> 14.</telerikScheduler:RadScheduler> Now, we get to the ViewModel and what it takes to get that rigged up.  And for those of you who remember the jobs post, those command:s in the Xaml are pointing to attached behavior commands that reproduce the respective events.  This becomes very handy when we're setting up the code-behind version. ;) ViewModel I've been liking this approach so far, so I'm going to put the entire ViewModel here and then go into the lines of interest.  Of course, feel free to ask me questions about anything that isn't clear (by line number, ideally) so I can help out if I have missed anything important: 001.public class SchedulerViewModel : ViewModelBase 002.{ 003.    private readonly IEventAggregator eventAggregator; 004.    private readonly IRegionManager regionManager; 005.   006.    public RecruitingContext context; 007.   008.    private ObservableItemCollection<InterviewAppointment> _interviews = new ObservableItemCollection<InterviewAppointment>(); 009.    public ObservableItemCollection<InterviewAppointment> Interviews 010.    { 011.        get { return _interviews; } 012.        set 013.        { 014.            if (_interviews != value) 015.            { 016.                _interviews = value; 017.                NotifyChanged("Interviews"); 018.            } 019.        } 020.    } 021.   022.    private QueryableCollectionView _jobsList; 023.    public QueryableCollectionView JobsList 024.    { 025.        get { return this._jobsList; } 026.        set 027.        { 028.            if (this._jobsList != value) 029.            { 030.                this._jobsList = value; 031.                this.NotifyChanged("JobsList"); 032.            } 033.        } 034.    } 035.   036.    private QueryableCollectionView _applicantList; 037.    public QueryableCollectionView ApplicantList 038.    { 039.        get { return _applicantList; } 040.        set 041.        { 042.            if (_applicantList != value) 043.            { 044.                _applicantList = value; 045.                NotifyChanged("ApplicantList"); 046.            } 047.        } 048.    } 049.   050.    public DelegateCommand<object> AddAppointmentCommand { get; set; } 051.    public DelegateCommand<object> ApptCreatingCommand { get; set; } 052.    public DelegateCommand<object> ApptEditedCommand { get; set; } 053.    public DelegateCommand<object> ApptDeletedCommand { get; set; } 054.   055.    public SchedulerViewModel(IEventAggregator eventAgg, IRegionManager regionmanager) 056.    { 057.        // set Unity items 058.        this.eventAggregator = eventAgg; 059.        this.regionManager = regionmanager; 060.   061.        // load our context 062.        context = new RecruitingContext(); 063.        LoadOperation<Interview> loadOp = context.Load(context.GetInterviewsQuery()); 064.        loadOp.Completed += new EventHandler(loadOp_Completed); 065.   066.        this._jobsList = new QueryableCollectionView(context.JobPostings); 067.        context.Load(context.GetJobPostingsQuery()); 068.   069.        this._applicantList = new QueryableCollectionView(context.Applicants); 070.        context.Load(context.GetApplicantsQuery()); 071.   072.        AddAppointmentCommand = new DelegateCommand<object>(this.AddAppt); 073.        ApptCreatingCommand = new DelegateCommand<object>(this.ApptCreating); 074.        ApptEditedCommand = new DelegateCommand<object>(this.ApptEdited); 075.        ApptDeletedCommand = new DelegateCommand<object>(this.ApptDeleted); 076.   077.    } 078.   079.    void loadOp_Completed(object sender, EventArgs e) 080.    { 081.        LoadOperation loadop = sender as LoadOperation; 082.   083.        foreach (var ent in loadop.Entities) 084.        { 085.            _interviews.Add(EntityToAppointment(ent as Interview)); 086.        } 087.    } 088.   089.    #region Appointment Adding 090.   091.    public void AddAppt(object obj) 092.    { 093.        // now we have a new InterviewAppointment to add to our QCV :) 094.        InterviewAppointment newInterview = obj as InterviewAppointment; 095.   096.        this.context.Interviews.Add(AppointmentToEntity(newInterview)); 097.        this.context.SubmitChanges((s) => 098.        { 099.            ActionHistory myAction = new ActionHistory(); 100.            myAction.InterviewID = newInterview.InterviewID; 101.            myAction.PostingID = newInterview.PostingID; 102.            myAction.ApplicantID = newInterview.ApplicantID; 103.            myAction.Description = String.Format("Interview with {0} has been created by {1}", newInterview.ApplicantID.ToString(), "default user"); 104.            myAction.TimeStamp = DateTime.Now; 105.            eventAggregator.GetEvent<AddActionEvent>().Publish(myAction); 106.        } 107.            , null); 108.    } 109.   110.    public void ApptCreating(object obj) 111.    { 112.        // handled in the behavior, just a placeholder to ensure it runs :) 113.    } 114.   115.    #endregion 116.   117.    #region Appointment Editing 118.   119.    public void ApptEdited(object obj) 120.    { 121.        Interview editedInterview = (from x in context.Interviews 122.                            where x.InterviewID == (obj as InterviewAppointment).InterviewID 123.                            select x).SingleOrDefault(); 124.   125.        CopyAppointmentEdit(editedInterview, obj as InterviewAppointment); 126.   127.        context.SubmitChanges((s) => { 128.            ActionHistory myAction = new ActionHistory(); 129.            myAction.InterviewID = editedInterview.InterviewID; 130.            myAction.PostingID = editedInterview.PostingID; 131.            myAction.ApplicantID = editedInterview.ApplicantID; 132.            myAction.Description = String.Format("Interview with {0} has been modified by {1}", editedInterview.ApplicantID.ToString(), "default user"); 133.            myAction.TimeStamp = DateTime.Now; 134.            eventAggregator.GetEvent<AddActionEvent>().Publish(myAction); } 135.            , null); 136.    } 137.   138.    #endregion 139.   140.    #region Appointment Deleting 141.   142.    public void ApptDeleted(object obj) 143.    { 144.        Interview deletedInterview = (from x in context.Interviews 145.                                      where x.InterviewID == (obj as InterviewAppointment).InterviewID 146.                                      select x).SingleOrDefault(); 147.   148.        context.Interviews.Remove(deletedInterview); 149.        context.SubmitChanges((s) => 150.        { 151.            ActionHistory myAction = new ActionHistory(); 152.            myAction.InterviewID = deletedInterview.InterviewID; 153.            myAction.PostingID = deletedInterview.PostingID; 154.            myAction.ApplicantID = deletedInterview.ApplicantID; 155.            myAction.Description = String.Format("Interview with {0} has been deleted by {1}", deletedInterview.ApplicantID.ToString(), "default user"); 156.            myAction.TimeStamp = DateTime.Now; 157.            eventAggregator.GetEvent<AddActionEvent>().Publish(myAction); 158.        } 159.            , null); 160.    } 161.   162.    #endregion 163.   164.    #region Appointment Helpers :) 165.   166.    public Interview AppointmentToEntity(InterviewAppointment ia) 167.    { 168.        Interview newInterview = new Interview(); 169.        newInterview.Subject = ia.Subject; 170.        newInterview.Body = ia.Body; 171.        newInterview.Start = ia.Start; 172.        newInterview.End = ia.End; 173.        newInterview.ApplicantID = ia.ApplicantID; 174.        newInterview.PostingID = ia.PostingID; 175.        newInterview.InterviewID = ia.InterviewID; 176.   177.        return newInterview; 178.    } 179.   180.    public InterviewAppointment EntityToAppointment(Interview ia) 181.    { 182.        InterviewAppointment newInterview = new InterviewAppointment(); 183.        newInterview.Subject = ia.Subject; 184.        newInterview.Body = ia.Body; 185.        newInterview.Start = ia.Start; 186.        newInterview.End = ia.End; 187.        newInterview.ApplicantID = ia.ApplicantID; 188.        newInterview.PostingID = ia.PostingID; 189.        newInterview.InterviewID = ia.InterviewID; 190.   191.        return newInterview; 192.    } 193.   194.    public void CopyAppointmentEdit(Interview entityInterview, InterviewAppointment appointmentInterview) 195.    { 196.        entityInterview.Subject = appointmentInterview.Subject; 197.        entityInterview.Body = appointmentInterview.Body; 198.        entityInterview.Start = appointmentInterview.Start; 199.        entityInterview.End = appointmentInterview.End; 200.        entityInterview.ApplicantID = appointmentInterview.ApplicantID; 201.        entityInterview.PostingID = appointmentInterview.PostingID; 202.    } 203.   204.    #endregion 205.} One thing we're doing here which you won't see in any of the other ViewModels is creating a duplicate collection.  I know this is something which will be fixed down the line for using RadScheduler, simplifying this process, but with WCF RIA changing as it does I wanted to ensure functionality would remain consistent as I continued development on this application.  So, I do a little bit of duplication, but for the greater good.  This all takes place starting on line 79, so for every entity that comes back we add it to the collection that is bound to RadScheduler.  Otherwise, the DelegateCommands that you see correspond directly to the events they are named after.  In each case, rather than sending over the full event arguments, I just send in the appointment in question (coming through as the object obj in all cases) so I can add (line 91), edit (line 119), and delete appointments (line 142) like normal.  This just ensures they get updated back to my database.  Also, the one bit of code you won't see is for the Appointment Creating (line 110) event- that is because in the command I've created I simply make the replacement I need to: 1.void element_AppointmentCreating(object sender, AppointmentCreatingEventArgs e) 2.{ 3.    e.NewAppointment = new InterviewAppointment(); 4.    base.ExecuteCommand(); 5.} And the ViewModel is none the wiser, the appointments just work as far as it is concerned since as they are created they become InterviewAppointments.  End result?  I've customized my EditAppointmentDialog as follows: And adding, editing, and deleting appointments works like a charm.  I can even 'edit' by moving appointments around RadScheduler, so as they are dropped into a timeslot they perform their full edit routine and things get updated. And then, the Code-Behind Version Perhaps the thing I like the most about doing one then the other is I get to steal 90% or more of the code from the MVVM version.  For example, the only real changes to the Code-Behind Xaml file exist in the control declaration, in which I use events instead of attached-behavior-event-commands: 01.<telerikScheduler:RadScheduler x:Name="xJobsScheduler" 02.                  Grid.Row="1" 03.                  Grid.Column="1" 04.                  Width="800" 05.                  MinWidth="600" 06.                  Height="500" 07.                  MinHeight="300" 08.                  EditAppointmentStyle="{StaticResource EditAppointmentStyle}" 09.                  AppointmentAdded="xJobsScheduler_AppointmentAdded" 10.                  AppointmentCreating="xJobsScheduler_AppointmentCreating" 11.                  AppointmentEdited="xJobsScheduler_AppointmentEdited" 12.                  AppointmentDeleted="xJobsScheduler_AppointmentDeleted"> 13.</telerikScheduler:RadScheduler> Easy, right?  Otherwise, all the same styling in UserControl.Resources was re-used, right down to the DataContextProxy that lets us bind to a collection from our viewmodel (in this case, our code-behind) to use within the DataTemplate.  The code conversion gets even easier, as I could literally copy and paste almost everything from the ViewModel to my Code-Behind, just a matter of pasting the right section into the right event.  Here's the code-behind as proof: 001.public partial class SchedulingView : UserControl, INotifyPropertyChanged 002.{ 003.    public RecruitingContext context; 004.   005.    private QueryableCollectionView _jobsList; 006.    public QueryableCollectionView JobsList 007.    { 008.        get { return this._jobsList; } 009.        set 010.        { 011.            if (this._jobsList != value) 012.            { 013.                this._jobsList = value; 014.                this.NotifyChanged("JobsList"); 015.            } 016.        } 017.    } 018.   019.    private QueryableCollectionView _applicantList; 020.    public QueryableCollectionView ApplicantList 021.    { 022.        get { return _applicantList; } 023.        set 024.        { 025.            if (_applicantList != value) 026.            { 027.                _applicantList = value; 028.                NotifyChanged("ApplicantList"); 029.            } 030.        } 031.    } 032.   033.    private ObservableItemCollection<InterviewAppointment> _interviews = new ObservableItemCollection<InterviewAppointment>(); 034.    public ObservableItemCollection<InterviewAppointment> Interviews 035.    { 036.        get { return _interviews; } 037.        set 038.        { 039.            if (_interviews != value) 040.            { 041.                _interviews = value; 042.                NotifyChanged("Interviews"); 043.            } 044.        } 045.    } 046.   047.    public SchedulingView() 048.    { 049.        InitializeComponent(); 050.   051.        this.DataContext = this; 052.   053.        this.Loaded += new RoutedEventHandler(SchedulingView_Loaded); 054.    } 055.   056.    void SchedulingView_Loaded(object sender, RoutedEventArgs e) 057.    { 058.        this.xJobsScheduler.AppointmentsSource = Interviews; 059.   060.        context = new RecruitingContext(); 061.           062.        LoadOperation loadop = context.Load(context.GetInterviewsQuery()); 063.        loadop.Completed += new EventHandler(loadop_Completed); 064.   065.        this._applicantList = new QueryableCollectionView(context.Applicants); 066.        context.Load(context.GetApplicantsQuery()); 067.   068.        this._jobsList = new QueryableCollectionView(context.JobPostings); 069.        context.Load(context.GetJobPostingsQuery()); 070.    } 071.   072.    void loadop_Completed(object sender, EventArgs e) 073.    { 074.        LoadOperation loadop = sender as LoadOperation; 075.   076.        _interviews.Clear(); 077.   078.        foreach (var ent in loadop.Entities) 079.        { 080.            _interviews.Add(EntityToAppointment(ent as Interview)); 081.        } 082.    } 083.   084.    private void xJobsScheduler_AppointmentAdded(object sender, Telerik.Windows.Controls.AppointmentAddedEventArgs e) 085.    { 086.        // now we have a new InterviewAppointment to add to our QCV :) 087.        InterviewAppointment newInterview = e.Appointment as InterviewAppointment; 088.   089.        this.context.Interviews.Add(AppointmentToEntity(newInterview)); 090.        this.context.SubmitChanges((s) => 091.        { 092.            ActionHistory myAction = new ActionHistory(); 093.            myAction.InterviewID = newInterview.InterviewID; 094.            myAction.PostingID = newInterview.PostingID; 095.            myAction.ApplicantID = newInterview.ApplicantID; 096.            myAction.Description = String.Format("Interview with {0} has been created by {1}", newInterview.ApplicantID.ToString(), "default user"); 097.            myAction.TimeStamp = DateTime.Now; 098.            context.ActionHistories.Add(myAction); 099.            context.SubmitChanges(); 100.        } 101.            , null); 102.    } 103.   104.    private void xJobsScheduler_AppointmentCreating(object sender, Telerik.Windows.Controls.AppointmentCreatingEventArgs e) 105.    { 106.        e.NewAppointment = new InterviewAppointment(); 107.    } 108.   109.    private void xJobsScheduler_AppointmentEdited(object sender, Telerik.Windows.Controls.AppointmentEditedEventArgs e) 110.    { 111.        Interview editedInterview = (from x in context.Interviews 112.                                     where x.InterviewID == (e.Appointment as InterviewAppointment).InterviewID 113.                                     select x).SingleOrDefault(); 114.   115.        CopyAppointmentEdit(editedInterview, e.Appointment as InterviewAppointment); 116.   117.        context.SubmitChanges((s) => 118.        { 119.            ActionHistory myAction = new ActionHistory(); 120.            myAction.InterviewID = editedInterview.InterviewID; 121.            myAction.PostingID = editedInterview.PostingID; 122.            myAction.ApplicantID = editedInterview.ApplicantID; 123.            myAction.Description = String.Format("Interview with {0} has been modified by {1}", editedInterview.ApplicantID.ToString(), "default user"); 124.            myAction.TimeStamp = DateTime.Now; 125.            context.ActionHistories.Add(myAction); 126.            context.SubmitChanges(); 127.        } 128.            , null); 129.    } 130.   131.    private void xJobsScheduler_AppointmentDeleted(object sender, Telerik.Windows.Controls.AppointmentDeletedEventArgs e) 132.    { 133.        Interview deletedInterview = (from x in context.Interviews 134.                                      where x.InterviewID == (e.Appointment as InterviewAppointment).InterviewID 135.                                      select x).SingleOrDefault(); 136.   137.        context.Interviews.Remove(deletedInterview); 138.        context.SubmitChanges((s) => 139.        { 140.            ActionHistory myAction = new ActionHistory(); 141.            myAction.InterviewID = deletedInterview.InterviewID; 142.            myAction.PostingID = deletedInterview.PostingID; 143.            myAction.ApplicantID = deletedInterview.ApplicantID; 144.            myAction.Description = String.Format("Interview with {0} has been deleted by {1}", deletedInterview.ApplicantID.ToString(), "default user"); 145.            myAction.TimeStamp = DateTime.Now; 146.            context.ActionHistories.Add(myAction); 147.            context.SubmitChanges(); 148.        } 149.            , null); 150.    } 151.   152.    #region Appointment Helpers :) 153.   154.    public Interview AppointmentToEntity(InterviewAppointment ia) 155.    { 156.        Interview newInterview = new Interview(); 157.        newInterview.Subject = ia.Subject; 158.        newInterview.Body = ia.Body; 159.        newInterview.Start = ia.Start; 160.        newInterview.End = ia.End; 161.        newInterview.ApplicantID = ia.ApplicantID; 162.        newInterview.PostingID = ia.PostingID; 163.        newInterview.InterviewID = ia.InterviewID; 164.   165.        return newInterview; 166.    } 167.   168.    public InterviewAppointment EntityToAppointment(Interview ia) 169.    { 170.        InterviewAppointment newInterview = new InterviewAppointment(); 171.        newInterview.Subject = ia.Subject; 172.        newInterview.Body = ia.Body; 173.        newInterview.Start = ia.Start; 174.        newInterview.End = ia.End; 175.        newInterview.ApplicantID = ia.ApplicantID; 176.        newInterview.PostingID = ia.PostingID; 177.        newInterview.InterviewID = ia.InterviewID; 178.   179.        return newInterview; 180.    } 181.   182.    public void CopyAppointmentEdit(Interview entityInterview, InterviewAppointment appointmentInterview) 183.    { 184.        entityInterview.Subject = appointmentInterview.Subject; 185.        entityInterview.Body = appointmentInterview.Body; 186.        entityInterview.Start = appointmentInterview.Start; 187.        entityInterview.End = appointmentInterview.End; 188.        entityInterview.ApplicantID = appointmentInterview.ApplicantID; 189.        entityInterview.PostingID = appointmentInterview.PostingID; 190.    } 191.   192.    #endregion 193.   194.    #region INotifyPropertyChanged Members 195.   196.    public event PropertyChangedEventHandler PropertyChanged; 197.   198.    public void NotifyChanged(string propertyName) 199.    { 200.        if (string.IsNullOrEmpty(propertyName)) 201.            throw new ArgumentException("propertyName"); 202.   203.        PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 204.    } 205.   206.    #endregion 207.} Nice... right? :) One really important thing to note as well.  See on line 51 where I set the DataContext before the Loaded event?  This is super important, as if you don't have this set before the usercontrol is loaded, the DataContextProxy has no context to use and your EditAppointmentDialog Job/Applicant dropdowns will be blank and empty.  Trust me on this, took a little bit of debugging to figure out that by setting the DataContext post-loaded would only lead to disaster and frustration.  Otherwise, the only other real difference is that instead of sending an ActionHistory item through an event to get added to the database and saved, I do those right in the callback from submitting.  The Result Again, I only have to post one picture because these bad boys used nearly identical code for both the MVVM and the code-behind views, so our end result is... So what have we learned here today?  One, for the most part this MVVM thing is somewhat easy.  Yeah, you sometimes have to write a bunch of extra code, but with the help of a few useful snippits you can turn the process into a pretty streamlined little workflow.  Heck, this story gets even easier as you can see in this blog post by Michael Washington- specifically run a find on 'InvokeCommandAction' and you'll see the section regarding the command on TreeView in Blend 4.  Brilliant!  MVVM never looked so sweet! Otherwise, it is business as usual with RadScheduler for Silverlight whichever path you're choosing for your development.  Between now and the next post, I'll be cleaning up styles a bit (those RadComboBoxes are a little too close to my labels!) and adding some to the RowDetailsViews for Applicants and Jobs, so you can see all the info for an appointment in the dropdown tab view.  Otherwise, we're about ready to call a wrap on this oneDid you know that DotNetSlackers also publishes .net articles written by top known .net Authors? We already have over 80 articles in several categories including Silverlight. Take a look: here.

    Read the article

  • Silverlight Recruiting Application Part 6 - Adding an Interview Scheduling Module/View

    Between the last post and this one I went ahead and carried the ideas for the Jobs module and view into the Applicants module and view- they're both doing more or less the same thing, except with different objects being at their core.  Made for an easy cut-and-paste operation with a few items being switched from one to another.  Now that we have the ability to add postings and applicants, wouldn't it be nice if we could schedule an interview?  Of course it would! Scheduling Module I think you get the drift from previous posts that these project structures start looking somewhat similar.  The interview scheduling module is no different than the rest- it gets a SchedulingModule.cs file at the root that inherits from IModule, and there is a single SchedulerView.xsml and SchedulerViewModel.cs setup for our V+VM.  We have one unique concern as we enter into this- RadScheduler deals with AppointmentsSource, not ItemsSource, so there are some special considerations to take into account when planning this module. First, I need something which inherits from AppointmentBase.  This is the core of the RadScheduler appointment, and if you are planning to do any form of custom appointment, you'll want it to inherit from this.  Then you can add-on functionality as needed.  Here is my addition to the mix, the InterviewAppointment: 01.public class InterviewAppointment : AppointmentBase 02.{ 03.    private int _applicantID; 04.    public int ApplicantID 05.    { 06.        get { return this._applicantID; } 07.        set 08.        { 09.            if (_applicantID != value) 10.            { 11.                _applicantID = value; 12.                OnPropertyChanged("ApplicantID"); 13.            } 14.        } 15.    } 16.   17.    private int _postingID; 18.    public int PostingID 19.    { 20.        get { return _postingID; } 21.        set 22.        { 23.            if (_postingID != value) 24.            { 25.                _postingID = value; 26.                OnPropertyChanged("PostingID"); 27.            } 28.        } 29.    } 30.   31.    private string _body; 32.    public string Body 33.    { 34.        get { return _body; } 35.        set 36.        { 37.            if (_body != value) 38.            { 39.                _body = value; 40.                OnPropertyChanged("Body"); 41.            } 42.        } 43.    } 44.   45.    private int _interviewID; 46.    public int InterviewID 47.    { 48.        get { return _interviewID; } 49.        set 50.        { 51.            if (_interviewID != value) 52.            { 53.                _interviewID = value; 54.                OnPropertyChanged("InterviewID"); 55.            } 56.        } 57.    } 58.   59.    public override IAppointment Copy() 60.    { 61.        IAppointment appointment = new InterviewAppointment(); 62.        appointment.CopyFrom(this);             63.        return appointment; 64.    } 65.   66.    public override void CopyFrom(IAppointment other) 67.    {             68.        base.CopyFrom(other); 69.        var appointment = other as InterviewAppointment; 70.        if (appointment != null) 71.        { 72.            ApplicantID = appointment.ApplicantID; 73.            PostingID = appointment.PostingID; 74.            Body = appointment.Body; 75.            InterviewID = appointment.InterviewID; 76.        } 77.    } 78.} Nothing too exciting going on here, we just make sure that our custom fields are persisted (specifically set in CopyFrom at the bottom) and notifications are fired- otherwise this ends up exactly like the standard appointment as far as interactions, etc.  But if we've got custom appointment items... that also means we need to customize what our appointment dialog window will look like. Customizing the Edit Appointment Dialog This initially sounds a lot more intimidating than it really is.  The first step here depends on what you're dealing with for theming, but for ease of everything I went ahead and extracted my templates in Blend for RadScheduler so I could modify it as I pleased.  For the faint of heart, the RadScheduler template is a few thousand lines of goodness since there are some very complex things going on in that control.  I've gone ahead and trimmed down the template parts I don't need as much as possible, so what is left is all that is relevant to the Edit Appointment Dialog.  Here's the resulting Xaml, with line numbers, so I can explain further: 001.<UserControl.Resources> 002.    <!-- begin Necessary Windows 7 Theme Resources for EditAppointmentTemplate --> 003.    <helpers:DataContextProxy x:Key="DataContextProxy" /> 004.       005.    <telerik:Windows7Theme x:Key="Theme" /> 006.    <SolidColorBrush x:Key="DialogWindowBackground" 007.                     Color="White" /> 008.    <SolidColorBrush x:Key="CategorySelectorBorderBrush" 009.                     Color="#FFB1B1B1" /> 010.    <LinearGradientBrush x:Key="RadToolBar_InnerBackground" 011.                         EndPoint="0.5,1" 012.                         StartPoint="0.5,0"> 013.        <GradientStop Color="#FFFDFEFF" 014.                      Offset="0" /> 015.        <GradientStop Color="#FFDDE9F7" 016.                      Offset="1" /> 017.        <GradientStop Color="#FFE6F0FA" 018.                      Offset="0.5" /> 019.        <GradientStop Color="#FFDCE6F4" 020.                      Offset="0.5" /> 021.    </LinearGradientBrush> 022.    <Style x:Key="FormElementTextBlockStyle" 023.           TargetType="TextBlock"> 024.        <Setter Property="HorizontalAlignment" 025.                Value="Right" /> 026.        <Setter Property="VerticalAlignment" 027.                Value="Top" /> 028.        <Setter Property="Margin" 029.                Value="15, 15, 0, 2" /> 030.    </Style> 031.    <Style x:Key="FormElementStyle" 032.           TargetType="FrameworkElement"> 033.        <Setter Property="Margin" 034.                Value="10, 10, 0, 2" /> 035.    </Style> 036.    <SolidColorBrush x:Key="GenericShallowBorderBrush" 037.                     Color="#FF979994" /> 038.    <telerik:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 039.    <telerikScheduler:ImportanceToBooleanConverter x:Key="ImportanceToBooleanConverter" /> 040.    <telerikScheduler:NullToVisibilityConverter x:Key="NullToVisibilityConverter" /> 041.    <telerikScheduler:InvertedNullToVisibilityConverter x:Key="InvertedNullToVisibilityConverter" /> 042.    <scheduler:ResourcesSeparatorConverter x:Key="ResourcesSeparatorConverter" /> 043.    <DataTemplate x:Key="IconDataEditTemplate"> 044.        <Image Source="/Telerik.Windows.Controls.Scheduler;component/Themes/Office/Images/cal.png" 045.               Margin="3,3,0,0" 046.               Width="16" 047.               Height="16" /> 048.    </DataTemplate> 049.    <DataTemplate x:Key="SingleSelectionTemplate"> 050.        <Grid VerticalAlignment="Stretch" 051.              HorizontalAlignment="Stretch"> 052.            <Grid.RowDefinitions> 053.                <RowDefinition Height="Auto" /> 054.            </Grid.RowDefinitions> 055.            <Grid.ColumnDefinitions> 056.                <ColumnDefinition Width="Auto" 057.                                  MinWidth="84" /> 058.                <ColumnDefinition Width="Auto" 059.                                  MinWidth="200" /> 060.            </Grid.ColumnDefinitions> 061.            <TextBlock x:Name="SelectionNameLabel" 062.                       Margin="0,13,4,2" 063.                       Text="{Binding ResourceType.DisplayName}" 064.                       Style="{StaticResource FormElementTextBlockStyle}" 065.                       Grid.Column="0" /> 066.            <telerikInput:RadComboBox ItemsSource="{Binding ResourceItems}" 067.                                      Width="185" 068.                                      Margin="5,10,20,2" 069.                                      HorizontalAlignment="Left" 070.                                      Grid.Column="1" 071.                                      ClearSelectionButtonVisibility="Visible" 072.                                      ClearSelectionButtonContent="Clear All" 073.                                      DisplayMemberPath="Resource.DisplayName" 074.                                      telerik:StyleManager.Theme="{StaticResource Theme}" 075.                                      SelectedItem="{Binding SelectedItem, Mode=TwoWay}" /> 076.        </Grid> 077.    </DataTemplate> 078.    <DataTemplate x:Key="MultipleSelectionTemplate"> 079.        <Grid VerticalAlignment="Stretch" 080.              HorizontalAlignment="Stretch"> 081.            <Grid.RowDefinitions> 082.                <RowDefinition Height="Auto" /> 083.            </Grid.RowDefinitions> 084.            <Grid.ColumnDefinitions> 085.                <ColumnDefinition Width="Auto" 086.                                  MinWidth="84" /> 087.                <ColumnDefinition Width="Auto" 088.                                  MinWidth="200" /> 089.            </Grid.ColumnDefinitions> 090.            <TextBlock x:Name="SelectionNameLabel" 091.                       Grid.Column="0" 092.                       Text="{Binding ResourceType.DisplayName}" 093.                       Margin="0,13,4,2" 094.                       Style="{StaticResource FormElementTextBlockStyle}" /> 095.            <telerikInput:RadComboBox Grid.Column="1" 096.                                      Width="185" 097.                                      HorizontalAlignment="Left" 098.                                      Margin="5,10,20,2" 099.                                      ItemsSource="{Binding ResourceItems}" 100.                                      SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}" 101.                                      ClearSelectionButtonVisibility="Visible" 102.                                      ClearSelectionButtonContent="Clear All" 103.                                      telerik:StyleManager.Theme="{StaticResource Theme}"> 104.                <telerikInput:RadComboBox.ItemTemplate> 105.                    <DataTemplate> 106.                        <Grid HorizontalAlignment="Stretch" 107.                              VerticalAlignment="Stretch"> 108.                            <CheckBox VerticalAlignment="Center" 109.                                      HorizontalContentAlignment="Stretch" 110.                                      VerticalContentAlignment="Center" 111.                                      IsChecked="{Binding IsChecked, Mode=TwoWay}" 112.                                      Content="{Binding Resource.DisplayName}"> 113.                                <CheckBox.ContentTemplate> 114.                                    <DataTemplate> 115.                                        <TextBlock HorizontalAlignment="Stretch" 116.                                                   VerticalAlignment="Stretch" 117.                                                   Text="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" /> 118.                                    </DataTemplate> 119.                                </CheckBox.ContentTemplate> 120.                            </CheckBox> 121.                        </Grid> 122.                    </DataTemplate> 123.                </telerikInput:RadComboBox.ItemTemplate> 124.            </telerikInput:RadComboBox> 125.        </Grid> 126.    </DataTemplate> 127.    <scheduler:ResourceTypeTemplateSelector x:Key="ItemTemplateSelector" 128.                                            MultipleSelectionTemplate="{StaticResource MultipleSelectionTemplate}" 129.                                            SingleSelectionTemplate="{StaticResource SingleSelectionTemplate}" /> 130.    <!-- end Necessary Windows 7 Theme Resources for EditAppointmentTemplate -->  131.       132.    <ControlTemplate x:Key="EditAppointmentTemplate" 133.                     TargetType="telerikScheduler:AppointmentDialogWindow"> 134.        <StackPanel Background="{TemplateBinding Background}" 135.                    UseLayoutRounding="True"> 136.            <StackPanel Grid.Row="0" 137.                        Orientation="Horizontal" 138.                        Background="{StaticResource RadToolBar_InnerBackground}" 139.                        Grid.ColumnSpan="2" 140.                        Height="0"> 141.                <!-- Recurrence buttons --> 142.                <Border Margin="1,1,0,0" 143.                        Background="#50000000" 144.                        HorizontalAlignment="Left" 145.                        VerticalAlignment="Center" 146.                        Width="2" 147.                        Height="16"> 148.                    <Border Margin="0,0,1,1" 149.                            Background="#80FFFFFF" 150.                            HorizontalAlignment="Left" 151.                            Width="1" /> 152.                </Border> 153.                <Border Margin="1,1,0,0" 154.                        Background="#50000000" 155.                        HorizontalAlignment="Left" 156.                        VerticalAlignment="Center" 157.                        Width="2" 158.                        Height="16"> 159.                    <Border Margin="0,0,1,1" 160.                            Background="#80FFFFFF" 161.                            HorizontalAlignment="Left" 162.                            Width="1" /> 163.                </Border> 164.                <TextBlock telerik:LocalizationManager.ResourceKey="ShowAs" 165.                           VerticalAlignment="Center" 166.                           Margin="5,0,0,0" /> 167.                <telerikInput:RadComboBox ItemsSource="{TemplateBinding TimeMarkers}" 168.                                          Width="100" 169.                                          Height="20" 170.                                          VerticalAlignment="Center" 171.                                          Margin="5,0,0,0" 172.                                          ClearSelectionButtonVisibility="Visible" 173.                                          ClearSelectionButtonContent="Clear" 174.                                          SelectedItem="{Binding TimeMarker,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" 175.                                          telerik:StyleManager.Theme="{StaticResource Theme}"> 176.                    <telerikInput:RadComboBox.ItemTemplate> 177.                        <DataTemplate> 178.                            <StackPanel Orientation="Horizontal"> 179.                                <Rectangle Fill="{Binding TimeMarkerBrush}" 180.                                           Margin="2" 181.                                           Width="12" 182.                                           Height="12" /> 183.                                <TextBlock Text="{Binding TimeMarkerName}" 184.                                           Margin="2" /> 185.                            </StackPanel> 186.                        </DataTemplate> 187.                    </telerikInput:RadComboBox.ItemTemplate> 188.                </telerikInput:RadComboBox> 189.                <telerik:RadToggleButton x:Name="High" 190.                                         BorderThickness="0" 191.                                         Background="{StaticResource RadToolBar_InnerBackground}" 192.                                         DataContext="{TemplateBinding EditedAppointment}" 193.                                         telerik:StyleManager.Theme="{StaticResource Theme}" 194.                                         IsChecked="{Binding Importance,Mode=TwoWay, Converter={StaticResource ImportanceToBooleanConverter},ConverterParameter=High}" 195.                                         Margin="2,2,0,2" 196.                                         Width="23" 197.                                         Height="23" 198.                                         HorizontalContentAlignment="Center" 199.                                         ToolTipService.ToolTip="High importance" 200.                                         CommandParameter="High" 201.                                         Command="telerikScheduler:RadSchedulerCommands.SetAppointmentImportance"> 202.                    <StackPanel HorizontalAlignment="Center"> 203.                        <Path Stretch="Fill" 204.                              Height="10" 205.                              HorizontalAlignment="Center" 206.                              VerticalAlignment="Top" 207.                              Width="5.451" 208.                              Data="M200.39647,58.840393 C200.39337,58.336426 201.14566,57.683922 202.56244,57.684292 C204.06589,57.684685 204.73764,58.357765 204.72783,58.992363 C205.04649,61.795574 203.04713,64.181099 202.47388,66.133446 C201.93753,64.154961 199.9471,61.560352 200.39647,58.840393 z"> 209.                            <Path.Fill> 210.                                <LinearGradientBrush EndPoint="1.059,0.375" 211.                                                     StartPoint="-0.457,0.519"> 212.                                    <GradientStop Color="#FFFF0606" 213.                                                  Offset="0.609" /> 214.                                    <GradientStop Color="#FFBF0303" 215.                                                  Offset="0.927" /> 216.                                </LinearGradientBrush> 217.                            </Path.Fill> 218.                        </Path> 219.                        <Ellipse Height="3" 220.                                 HorizontalAlignment="Center" 221.                                 Margin="0,-1,0,0" 222.                                 VerticalAlignment="Top" 223.                                 Width="3"> 224.                            <Ellipse.Fill> 225.                                <RadialGradientBrush> 226.                                    <GradientStop Color="#FFFF0606" 227.                                                  Offset="0" /> 228.                                    <GradientStop Color="#FFBF0303" 229.                                                  Offset="1" /> 230.                                </RadialGradientBrush> 231.                            </Ellipse.Fill> 232.                        </Ellipse> 233.                    </StackPanel> 234.                </telerik:RadToggleButton> 235.                <telerik:RadToggleButton x:Name="Low" 236.                                         HorizontalContentAlignment="Center" 237.                                         BorderThickness="0" 238.                                         Background="{StaticResource RadToolBar_InnerBackground}" 239.                                         DataContext="{TemplateBinding EditedAppointment}" 240.                                         IsChecked="{Binding Importance,Mode=TwoWay, Converter={StaticResource ImportanceToBooleanConverter},ConverterParameter=Low}" 241.                                         Margin="0,2,0,2" 242.                                         Width="23" 243.                                         Height="23" 244.                                         ToolTipService.ToolTip="Low importance" 245.                                         CommandParameter="Low" 246.                                         telerik:StyleManager.Theme="{StaticResource Theme}" 247.                                         Command="telerikScheduler:RadSchedulerCommands.SetAppointmentImportance"> 248.                    <Path Stretch="Fill" 249.                          Height="12" 250.                          HorizontalAlignment="Center" 251.                          VerticalAlignment="Top" 252.                          Width="9" 253.                          Data="M222.40353,60.139881 L226.65768,60.139843 L226.63687,67.240196 L229.15347,67.240196 L224.37816,71.394943 L219.65274,67.240196 L222.37572,67.219345 z" 254.                          Stroke="#FF0365A7"> 255.                        <Path.Fill> 256.                            <LinearGradientBrush EndPoint="1.059,0.375" 257.                                                 StartPoint="-0.457,0.519"> 258.                                <GradientStop Color="#FFBBE4FF" /> 259.                                <GradientStop Color="#FF024572" 260.                                              Offset="0.836" /> 261.                                <GradientStop Color="#FF43ADF4" 262.                                              Offset="0.466" /> 263.                            </LinearGradientBrush> 264.                        </Path.Fill> 265.                    </Path> 266.                </telerik:RadToggleButton> 267.            </StackPanel > 268.            <Border DataContext="{TemplateBinding EditedAppointment}" 269.                    Background="{Binding Category.CategoryBrush}" 270.                    Visibility="{Binding Category,Converter={StaticResource NullToVisibilityConverter}}" 271.                    CornerRadius="3" 272.                    Height="20" 273.                    Margin="5,10,5,0"> 274.                <TextBlock Text="{Binding Category.DisplayName}" 275.                           VerticalAlignment="Center" 276.                           Margin="5,0,0,0" /> 277.            </Border> 278.            <Grid VerticalAlignment="Stretch" 279.                  HorizontalAlignment="Stretch" 280.                  DataContext="{TemplateBinding EditedAppointment}" 281.                  Background="{TemplateBinding Background}"> 282.                <Grid.RowDefinitions> 283.                    <RowDefinition Height="Auto" /> 284.                    <RowDefinition Height="Auto" /> 285.                    <RowDefinition Height="Auto" /> 286.                    <RowDefinition Height="Auto" /> 287.                    <RowDefinition Height="Auto" /> 288.                    <RowDefinition Height="Auto" /> 289.                    <RowDefinition Height="Auto" /> 290.                    <RowDefinition Height="Auto" /> 291.                    <RowDefinition Height="Auto" /> 292.                    <RowDefinition Height="Auto" /> 293.                </Grid.RowDefinitions> 294.                <Grid.ColumnDefinitions> 295.                    <ColumnDefinition Width="Auto" 296.                                      MinWidth="100" /> 297.                    <ColumnDefinition Width="Auto" 298.                                      MinWidth="200" /> 299.                </Grid.ColumnDefinitions> 300.                <!-- Subject --> 301.                <TextBlock x:Name="SubjectLabel" 302.                           Grid.Row="0" 303.                           Grid.Column="0" 304.                           Margin="0,15,0,2" 305.                           telerik:LocalizationManager.ResourceKey="Subject" 306.                           Style="{StaticResource FormElementTextBlockStyle}" /> 307.                <TextBox x:Name="Subject" 308.                         Grid.Row="0" 309.                         Grid.Column="1" 310.                         MinHeight="22" 311.                         Padding="4 2" 312.                         Width="340" 313.                         HorizontalAlignment="Left" 314.                         Text="{Binding Subject, Mode=TwoWay}" 315.                         MaxLength="255" 316.                         telerik:StyleManager.Theme="{StaticResource Theme}" 317.                         Margin="10,12,20,2" /> 318.                <!-- Description --> 319.                <TextBlock x:Name="DescriptionLabel" 320.                           Grid.Row="1" 321.                           Grid.Column="0" 322.                           Margin="0,13,0,2" 323.                           telerik:LocalizationManager.ResourceKey="Body" 324.                           Style="{StaticResource FormElementTextBlockStyle}" /> 325.                <TextBox x:Name="Body" 326.                         VerticalAlignment="top" 327.                         Grid.Row="1" 328.                         Grid.Column="1" 329.                         Height="Auto" 330.                         MaxHeight="82" 331.                         Width="340" 332.                         HorizontalAlignment="Left" 333.                         MinHeight="22" 334.                         Padding="4 2" 335.                         TextWrapping="Wrap" 336.                         telerik:StyleManager.Theme="{StaticResource Theme}" 337.                         Text="{Binding Body, Mode=TwoWay}" 338.                         AcceptsReturn="true" 339.                         Margin="10,10,20,2" 340.                         HorizontalScrollBarVisibility="Auto" 341.                         VerticalScrollBarVisibility="Auto" /> 342.                <!-- Start/End date --> 343.                <TextBlock x:Name="StartDateLabel" 344.                           Grid.Row="2" 345.                           Grid.Column="0" 346.                           Margin="0,13,0,2" 347.                           telerik:LocalizationManager.ResourceKey="StartTime" 348.                           Style="{StaticResource FormElementTextBlockStyle}" /> 349.                <telerikScheduler:DateTimePicker x:Name="StartDateTime" 350.                                                 Height="22" 351.                                                 Grid.Row="2" 352.                                                 Grid.Column="1" 353.                                                 HorizontalAlignment="Left" 354.                                                 Margin="10,10,20,2" 355.                                                 Style="{StaticResource FormElementStyle}" 356.                                                 SelectedDateTime="{Binding Start, Mode=TwoWay}" 357.                                                 telerikScheduler:StartEndDatePicker.EndPicker="{Binding ElementName=EndDateTime}" 358.                                                 IsTabStop="False" 359.                                                 IsEnabled="False" /> 360.                <TextBlock x:Name="EndDateLabel" 361.                           Grid.Row="3" 362.                           Grid.Column="0" 363.                           Margin="0,13,0,2" 364.                           telerik:LocalizationManager.ResourceKey="EndTime" 365.                           Style="{StaticResource FormElementTextBlockStyle}" /> 366.                <telerikScheduler:DateTimePicker x:Name="EndDateTime" 367.                                                 Height="22" 368.                                                 Grid.Row="3" 369.                                                 Grid.Column="1" 370.                                                 HorizontalAlignment="Left" 371.                                                 Margin="10,10,20,2" 372.                                                 Style="{StaticResource FormElementStyle}" 373.                                                 IsTabStop="False" 374.                                                 IsEnabled="False" 375.                                                 SelectedDateTime="{Binding End, Mode=TwoWay}" /> 376.                <!-- Is-all-day selector --> 377.                <CheckBox x:Name="AllDayEventCheckbox" 378.                          IsChecked="{Binding IsAllDayEvent, Mode=TwoWay}" 379.                          Grid.Row="4" 380.                          Grid.Column="1" 381.                          Margin="10,10,20,2" 382.                          HorizontalAlignment="Left" 383.                          telerik:StyleManager.Theme="{StaticResource Theme}" 384.                          telerik:LocalizationManager.ResourceKey="AllDayEvent"> 385.                    <telerik:CommandManager.InputBindings> 386.                        <telerik:InputBindingCollection> 387.                            <telerik:MouseBinding Command="telerikScheduler:RadSchedulerCommands.ChangeTimePickersVisibility" 388.                                                  Gesture="LeftClick" /> 389.                        </telerik:InputBindingCollection> 390.                    </telerik:CommandManager.InputBindings> 391.                </CheckBox> 392.                <Grid Grid.Row="5" 393.                      Grid.ColumnSpan="2"> 394.                    <Grid.ColumnDefinitions> 395.                        <ColumnDefinition Width="Auto" 396.                                          MinWidth="100" /> 397.                        <ColumnDefinition Width="Auto" 398.                                          MinWidth="200" /> 399.                    </Grid.ColumnDefinitions> 400.                    <Grid.RowDefinitions> 401.                        <RowDefinition Height="Auto" /> 402.                        <RowDefinition Height="Auto" /> 403.                    </Grid.RowDefinitions> 404.                    <TextBlock Text="Applicant" 405.                               Margin="0,13,0,2" 406.                               Style="{StaticResource FormElementTextBlockStyle}" /> 407.                    <telerikInput:RadComboBox IsEditable="False" 408.                                              Grid.Column="1" 409.                                              Height="24" 410.                                              VerticalAlignment="Center" 411.                                              ItemsSource="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.ApplicantList}" 412.                                              SelectedValue="{Binding ApplicantID, Mode=TwoWay}" 413.                                              SelectedValuePath="ApplicantID" 414.                                              DisplayMemberPath="FirstName" /> 415.                       416.                    <TextBlock Text="Job" 417.                               Margin="0,13,0,2" 418.                               Grid.Row="1" 419.                               Style="{StaticResource FormElementTextBlockStyle}" /> 420.                    <telerikInput:RadComboBox IsEditable="False" 421.                                              Grid.Column="1" 422.                                              Grid.Row="1" 423.                                              Height="24" 424.                                              VerticalAlignment="Center" 425.                                              ItemsSource="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.JobsList}" 426.                                              SelectedValue="{Binding PostingID, Mode=TwoWay}" 427.                                              SelectedValuePath="PostingID" 428.                                              DisplayMemberPath="JobTitle"/> 429.                </Grid> 430.                    <!-- Resources --> 431.                <Grid x:Name="ResourcesLayout" 432.                      Grid.Row="7" 433.                      Grid.Column="0" 434.                      Grid.ColumnSpan="2" 435.                      MaxHeight="130" 436.                      Margin="20,5,20,0"> 437.                    <Border Margin="0" 438.                            BorderThickness="1" 439.                            BorderBrush="{StaticResource GenericShallowBorderBrush}" 440.                            Visibility="{Binding ElementName=ResourcesScrollViewer, Path=ComputedVerticalScrollBarVisibility}"></Border> 441.                    <ScrollViewer x:Name="ResourcesScrollViewer" 442.                                  IsTabStop="false" 443.                                  Grid.Row="6" 444.                                  Grid.Column="0" 445.                                  Grid.ColumnSpan="2" 446.                                  Margin="1" 447.                                  telerik:StyleManager.Theme="{StaticResource Theme}" 448.                                  VerticalScrollBarVisibility="Auto"> 449.                        <scheduler:ResourcesItemsControl x:Name="PART_Resources" 450.                                                         HorizontalAlignment="Left" 451.                                                         Padding="0,2,0,5" 452.                                                         IsTabStop="false" 453.                                                         ItemsSource="{TemplateBinding ResourceTypeModels}" 454.                                                         ItemTemplateSelector="{StaticResource ItemTemplateSelector}" /> 455.                    </ScrollViewer> 456.                </Grid> 457.                <StackPanel x:Name="FooterControls" 458.                            Margin="5 10 10 10" 459.                            Grid.Row="8" 460.                            Grid.Column="1" 461.                            HorizontalAlignment="Left" 462.                            Orientation="Horizontal"> 463.                    <telerik:RadButton x:Name="OKButton" 464.                                       Margin="5" 465.                                       Padding="10 0" 466.                                       MinWidth="80" 467.                                       Command="telerikScheduler:RadSchedulerCommands.SaveAppointment" 468.                                       telerik:StyleManager.Theme="{StaticResource Theme}" 469.                                       telerikNavigation:RadWindow.ResponseButton="Accept" 470.                                       telerik:LocalizationManager.ResourceKey="SaveAndCloseCommandText"> 471.                    </telerik:RadButton> 472.                    <telerik:RadButton x:Name="CancelButton" 473.                                       Margin="5" 474.                                       Padding="10 0" 475.                                       MinWidth="80" 476.                                       telerik:LocalizationManager.ResourceKey="Cancel" 477.                                       telerik:StyleManager.Theme="{StaticResource Theme}" 478.                                       telerikNavigation:RadWindow.ResponseButton="Cancel" 479.                                       Command="telerik:WindowCommands.Close"> 480.                    </telerik:RadButton> 481.                </StackPanel> 482.            </Grid> 483.            <vsm:VisualStateManager.VisualStateGroups> 484.                <vsm:VisualStateGroup x:Name="RecurrenceRuleState"> 485.                    <vsm:VisualState x:Name="RecurrenceRuleIsNull"> 486.                        <Storyboard> 487.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="StartDateTime" 488.                                                           Storyboard.TargetProperty="IsEnabled" 489.                                                           Duration="0"> 490.                                <DiscreteObjectKeyFrame KeyTime="0" 491.                                                        Value="True" /> 492.                            </ObjectAnimationUsingKeyFrames> 493.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="EndDateTime" 494.                                                           Storyboard.TargetProperty="IsEnabled" 495.                                                           Duration="0"> 496.                                <DiscreteObjectKeyFrame KeyTime="0" 497.                                                        Value="True" /> 498.                            </ObjectAnimationUsingKeyFrames> 499.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="AllDayEventCheckbox" 500.                                                           Storyboard.TargetProperty="IsEnabled" 501.                                                           Duration="0"> 502.                                <DiscreteObjectKeyFrame KeyTime="0" 503.                                                        Value="True" /> 504.                            </ObjectAnimationUsingKeyFrames> 505.                        </Storyboard> 506.                    </vsm:VisualState> 507.                    <vsm:VisualState x:Name="RecurrenceRuleIsNotNull"> 508.                        <Storyboard> 509.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="StartDateTime" 510.                                                           Storyboard.TargetProperty="IsEnabled" 511.                                                           Duration="0"> 512.                                <DiscreteObjectKeyFrame KeyTime="0" 513.                                                        Value="False" /> 514.                            </ObjectAnimationUsingKeyFrames> 515.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="EndDateTime" 516.                                                           Storyboard.TargetProperty="IsEnabled" 517.                                                           Duration="0"> 518.                                <DiscreteObjectKeyFrame KeyTime="0" 519.                                                        Value="False" /> 520.                            </ObjectAnimationUsingKeyFrames> 521.                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="AllDayEventCheckbox" 522.                                                           Storyboard.TargetProperty="IsEnabled" 523.                                                           Duration="0"> 524.                                <DiscreteObjectKeyFrame KeyTime="0" 525.                                                        Value="False" /> 526.                            </ObjectAnimationUsingKeyFrames> 527.                        </Storyboard> 528.                    </vsm:VisualState> 529.                </vsm:VisualStateGroup> 530.            </vsm:VisualStateManager.VisualStateGroups> 531.        </StackPanel> 532.    </ControlTemplate> 533.    <DataTemplate x:Key="AppointmentDialogWindowHeaderDataTemplate"> 534.        <StackPanel Orientation="Horizontal" 535.                    MaxWidth="400"> 536.            <TextBlock telerik:LocalizationManager.ResourceKey="Event" 537.                       Visibility="{Binding Appointment.IsAllDayEvent, Converter={StaticResource BooleanToVisibilityConverter}}" /> 538.            <TextBlock telerik:LocalizationManager.ResourceKey="Appointment" 539.                       Visibility="{Binding Appointment.IsAllDayEvent, Converter={StaticResource InvertedBooleanToVisibilityConverter}}" /> 540.            <TextBlock Text=" - " /> 541.            <TextBlock x:Name="SubjectTextBlock" 542.                       Visibility="{Binding Appointment.Subject, Converter={StaticResource NullToVisibilityConverter}}" 543.                       Text="{Binding Appointment.Subject}" /> 544.            <TextBlock telerik:LocalizationManager.ResourceKey="Untitled" 545.                       Visibility="{Binding Appointment.Subject, Converter={StaticResource InvertedNullToVisibilityConverter}}" /> 546.        </StackPanel> 547.    </DataTemplate> 548.    <Style x:Key="EditAppointmentStyle" 549.           TargetType="telerikScheduler:AppointmentDialogWindow"> 550.        <Setter Property="IconTemplate" 551.                Value="{StaticResource IconDataEditTemplate}" /> 552.        <Setter Property="HeaderTemplate" 553.                Value="{StaticResource AppointmentDialogWindowHeaderDataTemplate}" /> 554.        <Setter Property="Background" 555.                Value="{StaticResource DialogWindowBackground}" /> 556.        <Setter Property="Template" 557.                Value="{StaticResource EditAppointmentTemplate}" /> 558.    </Style> 559.</UserControl.Resources> The first line there is the DataContextProxy I mentioned previously- we use that again to work a bit of magic in this template. Where we start getting into the dialog in question is line 132, but line 407 is where things start getting interesting.  The ItemsSource is pointing at a list that exists in my ViewModel (or code-behind, if it is used as a DataContext), the SelectedValue is the item I am actually binding from the applicant (note the TwoWay binding), and SelectedValuePath and DisplayMemberPath ensure the proper applicant is being displayed from the collection.  You will also see similar starting on line 420 where I do the same for the Jobs we'll be displaying. Just to wrap-up the Xaml, here's the RadScheduler declaraction that ties this all together and will be the main focus of our view: 01.<telerikScheduler:RadScheduler x:Name="xJobsScheduler" 02.                  Grid.Row="1" 03.                  Grid.Column="1" 04.                  Width="800" 05.                  MinWidth="600" 06.                  Height="500" 07.                  MinHeight="300" 08.                  AppointmentsSource="{Binding Interviews}" 09.                  EditAppointmentStyle="{StaticResource EditAppointmentStyle}" 10.                  command:AppointmentAddedEventClass.Command="{Binding AddAppointmentCommand}" 11.                  command:ApptCreatedEventClass.Command="{Binding ApptCreatingCommand}" 12.                  command:ApptEditedEventClass.Command="{Binding ApptEditedCommand}" 13.                  command:ApptDeletedEventClass.Command="{Binding ApptDeletedCommand}"> 14.</telerikScheduler:RadScheduler> Now, we get to the ViewModel and what it takes to get that rigged up.  And for those of you who remember the jobs post, those command:s in the Xaml are pointing to attached behavior commands that reproduce the respective events.  This becomes very handy when we're setting up the code-behind version. ;) ViewModel I've been liking this approach so far, so I'm going to put the entire ViewModel here and then go into the lines of interest.  Of course, feel free to ask me questions about anything that isn't clear (by line number, ideally) so I can help out if I have missed anything important: 001.public class SchedulerViewModel : ViewModelBase 002.{ 003.    private readonly IEventAggregator eventAggregator; 004.    private readonly IRegionManager regionManager; 005.   006.    public RecruitingContext context; 007.   008.    private ObservableItemCollection<InterviewAppointment> _interviews = new ObservableItemCollection<InterviewAppointment>(); 009.    public ObservableItemCollection<InterviewAppointment> Interviews 010.    { 011.        get { return _interviews; } 012.        set 013.        { 014.            if (_interviews != value) 015.            { 016.                _interviews = value; 017.                NotifyChanged("Interviews"); 018.            } 019.        } 020.    } 021.   022.    private QueryableCollectionView _jobsList; 023.    public QueryableCollectionView JobsList 024.    { 025.        get { return this._jobsList; } 026.        set 027.        { 028.            if (this._jobsList != value) 029.            { 030.                this._jobsList = value; 031.                this.NotifyChanged("JobsList"); 032.            } 033.        } 034.    } 035.   036.    private QueryableCollectionView _applicantList; 037.    public QueryableCollectionView ApplicantList 038.    { 039.        get { return _applicantList; } 040.        set 041.        { 042.            if (_applicantList != value) 043.            { 044.                _applicantList = value; 045.                NotifyChanged("ApplicantList"); 046.            } 047.        } 048.    } 049.   050.    public DelegateCommand<object> AddAppointmentCommand { get; set; } 051.    public DelegateCommand<object> ApptCreatingCommand { get; set; } 052.    public DelegateCommand<object> ApptEditedCommand { get; set; } 053.    public DelegateCommand<object> ApptDeletedCommand { get; set; } 054.   055.    public SchedulerViewModel(IEventAggregator eventAgg, IRegionManager regionmanager) 056.    { 057.        // set Unity items 058.        this.eventAggregator = eventAgg; 059.        this.regionManager = regionmanager; 060.   061.        // load our context 062.        context = new RecruitingContext(); 063.        LoadOperation<Interview> loadOp = context.Load(context.GetInterviewsQuery()); 064.        loadOp.Completed += new EventHandler(loadOp_Completed); 065.   066.        this._jobsList = new QueryableCollectionView(context.JobPostings); 067.        context.Load(context.GetJobPostingsQuery()); 068.   069.        this._applicantList = new QueryableCollectionView(context.Applicants); 070.        context.Load(context.GetApplicantsQuery()); 071.   072.        AddAppointmentCommand = new DelegateCommand<object>(this.AddAppt); 073.        ApptCreatingCommand = new DelegateCommand<object>(this.ApptCreating); 074.        ApptEditedCommand = new DelegateCommand<object>(this.ApptEdited); 075.        ApptDeletedCommand = new DelegateCommand<object>(this.ApptDeleted); 076.   077.    } 078.   079.    void loadOp_Completed(object sender, EventArgs e) 080.    { 081.        LoadOperation loadop = sender as LoadOperation; 082.   083.        foreach (var ent in loadop.Entities) 084.        { 085.            _interviews.Add(EntityToAppointment(ent as Interview)); 086.        } 087.    } 088.   089.    #region Appointment Adding 090.   091.    public void AddAppt(object obj) 092.    { 093.        // now we have a new InterviewAppointment to add to our QCV :) 094.        InterviewAppointment newInterview = obj as InterviewAppointment; 095.   096.        this.context.Interviews.Add(AppointmentToEntity(newInterview)); 097.        this.context.SubmitChanges((s) => 098.        { 099.            ActionHistory myAction = new ActionHistory(); 100.            myAction.InterviewID = newInterview.InterviewID; 101.            myAction.PostingID = newInterview.PostingID; 102.            myAction.ApplicantID = newInterview.ApplicantID; 103.            myAction.Description = String.Format("Interview with {0} has been created by {1}", newInterview.ApplicantID.ToString(), "default user"); 104.            myAction.TimeStamp = DateTime.Now; 105.            eventAggregator.GetEvent<AddActionEvent>().Publish(myAction); 106.        } 107.            , null); 108.    } 109.   110.    public void ApptCreating(object obj) 111.    { 112.        // handled in the behavior, just a placeholder to ensure it runs :) 113.    } 114.   115.    #endregion 116.   117.    #region Appointment Editing 118.   119.    public void ApptEdited(object obj) 120.    { 121.        Interview editedInterview = (from x in context.Interviews 122.                            where x.InterviewID == (obj as InterviewAppointment).InterviewID 123.                            select x).SingleOrDefault(); 124.   125.        CopyAppointmentEdit(editedInterview, obj as InterviewAppointment); 126.   127.        context.SubmitChanges((s) => { 128.            ActionHistory myAction = new ActionHistory(); 129.            myAction.InterviewID = editedInterview.InterviewID; 130.            myAction.PostingID = editedInterview.PostingID; 131.            myAction.ApplicantID = editedInterview.ApplicantID; 132.            myAction.Description = String.Format("Interview with {0} has been modified by {1}", editedInterview.ApplicantID.ToString(), "default user"); 133.            myAction.TimeStamp = DateTime.Now; 134.            eventAggregator.GetEvent<AddActionEvent>().Publish(myAction); } 135.            , null); 136.    } 137.   138.    #endregion 139.   140.    #region Appointment Deleting 141.   142.    public void ApptDeleted(object obj) 143.    { 144.        Interview deletedInterview = (from x in context.Interviews 145.                                      where x.InterviewID == (obj as InterviewAppointment).InterviewID 146.                                      select x).SingleOrDefault(); 147.   148.        context.Interviews.Remove(deletedInterview); 149.        context.SubmitChanges((s) => 150.        { 151.            ActionHistory myAction = new ActionHistory(); 152.            myAction.InterviewID = deletedInterview.InterviewID; 153.            myAction.PostingID = deletedInterview.PostingID; 154.            myAction.ApplicantID = deletedInterview.ApplicantID; 155.            myAction.Description = String.Format("Interview with {0} has been deleted by {1}", deletedInterview.ApplicantID.ToString(), "default user"); 156.            myAction.TimeStamp = DateTime.Now; 157.            eventAggregator.GetEvent<AddActionEvent>().Publish(myAction); 158.        } 159.            , null); 160.    } 161.   162.    #endregion 163.   164.    #region Appointment Helpers :) 165.   166.    public Interview AppointmentToEntity(InterviewAppointment ia) 167.    { 168.        Interview newInterview = new Interview(); 169.        newInterview.Subject = ia.Subject; 170.        newInterview.Body = ia.Body; 171.        newInterview.Start = ia.Start; 172.        newInterview.End = ia.End; 173.        newInterview.ApplicantID = ia.ApplicantID; 174.        newInterview.PostingID = ia.PostingID; 175.        newInterview.InterviewID = ia.InterviewID; 176.   177.        return newInterview; 178.    } 179.   180.    public InterviewAppointment EntityToAppointment(Interview ia) 181.    { 182.        InterviewAppointment newInterview = new InterviewAppointment(); 183.        newInterview.Subject = ia.Subject; 184.        newInterview.Body = ia.Body; 185.        newInterview.Start = ia.Start; 186.        newInterview.End = ia.End; 187.        newInterview.ApplicantID = ia.ApplicantID; 188.        newInterview.PostingID = ia.PostingID; 189.        newInterview.InterviewID = ia.InterviewID; 190.   191.        return newInterview; 192.    } 193.   194.    public void CopyAppointmentEdit(Interview entityInterview, InterviewAppointment appointmentInterview) 195.    { 196.        entityInterview.Subject = appointmentInterview.Subject; 197.        entityInterview.Body = appointmentInterview.Body; 198.        entityInterview.Start = appointmentInterview.Start; 199.        entityInterview.End = appointmentInterview.End; 200.        entityInterview.ApplicantID = appointmentInterview.ApplicantID; 201.        entityInterview.PostingID = appointmentInterview.PostingID; 202.    } 203.   204.    #endregion 205.} One thing we're doing here which you won't see in any of the other ViewModels is creating a duplicate collection.  I know this is something which will be fixed down the line for using RadScheduler, simplifying this process, but with WCF RIA changing as it does I wanted to ensure functionality would remain consistent as I continued development on this application.  So, I do a little bit of duplication, but for the greater good.  This all takes place starting on line 79, so for every entity that comes back we add it to the collection that is bound to RadScheduler.  Otherwise, the DelegateCommands that you see correspond directly to the events they are named after.  In each case, rather than sending over the full event arguments, I just send in the appointment in question (coming through as the object obj in all cases) so I can add (line 91), edit (line 119), and delete appointments (line 142) like normal.  This just ensures they get updated back to my database.  Also, the one bit of code you won't see is for the Appointment Creating (line 110) event- that is because in the command I've created I simply make the replacement I need to: 1.void element_AppointmentCreating(object sender, AppointmentCreatingEventArgs e) 2.{ 3.    e.NewAppointment = new InterviewAppointment(); 4.    base.ExecuteCommand(); 5.} And the ViewModel is none the wiser, the appointments just work as far as it is concerned since as they are created they become InterviewAppointments.  End result?  I've customized my EditAppointmentDialog as follows: And adding, editing, and deleting appointments works like a charm.  I can even 'edit' by moving appointments around RadScheduler, so as they are dropped into a timeslot they perform their full edit routine and things get updated. And then, the Code-Behind Version Perhaps the thing I like the most about doing one then the other is I get to steal 90% or more of the code from the MVVM version.  For example, the only real changes to the Code-Behind Xaml file exist in the control declaration, in which I use events instead of attached-behavior-event-commands: 01.<telerikScheduler:RadScheduler x:Name="xJobsScheduler" 02.                  Grid.Row="1" 03.                  Grid.Column="1" 04.                  Width="800" 05.                  MinWidth="600" 06.                  Height="500" 07.                  MinHeight="300" 08.                  EditAppointmentStyle="{StaticResource EditAppointmentStyle}" 09.                  AppointmentAdded="xJobsScheduler_AppointmentAdded" 10.                  AppointmentCreating="xJobsScheduler_AppointmentCreating" 11.                  AppointmentEdited="xJobsScheduler_AppointmentEdited" 12.                  AppointmentDeleted="xJobsScheduler_AppointmentDeleted"> 13.</telerikScheduler:RadScheduler> Easy, right?  Otherwise, all the same styling in UserControl.Resources was re-used, right down to the DataContextProxy that lets us bind to a collection from our viewmodel (in this case, our code-behind) to use within the DataTemplate.  The code conversion gets even easier, as I could literally copy and paste almost everything from the ViewModel to my Code-Behind, just a matter of pasting the right section into the right event.  Here's the code-behind as proof: 001.public partial class SchedulingView : UserControl, INotifyPropertyChanged 002.{ 003.    public RecruitingContext context; 004.   005.    private QueryableCollectionView _jobsList; 006.    public QueryableCollectionView JobsList 007.    { 008.        get { return this._jobsList; } 009.        set 010.        { 011.            if (this._jobsList != value) 012.            { 013.                this._jobsList = value; 014.                this.NotifyChanged("JobsList"); 015.            } 016.        } 017.    } 018.   019.    private QueryableCollectionView _applicantList; 020.    public QueryableCollectionView ApplicantList 021.    { 022.        get { return _applicantList; } 023.        set 024.        { 025.            if (_applicantList != value) 026.            { 027.                _applicantList = value; 028.                NotifyChanged("ApplicantList"); 029.            } 030.        } 031.    } 032.   033.    private ObservableItemCollection<InterviewAppointment> _interviews = new ObservableItemCollection<InterviewAppointment>(); 034.    public ObservableItemCollection<InterviewAppointment> Interviews 035.    { 036.        get { return _interviews; } 037.        set 038.        { 039.            if (_interviews != value) 040.            { 041.                _interviews = value; 042.                NotifyChanged("Interviews"); 043.            } 044.        } 045.    } 046.   047.    public SchedulingView() 048.    { 049.        InitializeComponent(); 050.   051.        this.DataContext = this; 052.   053.        this.Loaded += new RoutedEventHandler(SchedulingView_Loaded); 054.    } 055.   056.    void SchedulingView_Loaded(object sender, RoutedEventArgs e) 057.    { 058.        this.xJobsScheduler.AppointmentsSource = Interviews; 059.   060.        context = new RecruitingContext(); 061.           062.        LoadOperation loadop = context.Load(context.GetInterviewsQuery()); 063.        loadop.Completed += new EventHandler(loadop_Completed); 064.   065.        this._applicantList = new QueryableCollectionView(context.Applicants); 066.        context.Load(context.GetApplicantsQuery()); 067.   068.        this._jobsList = new QueryableCollectionView(context.JobPostings); 069.        context.Load(context.GetJobPostingsQuery()); 070.    } 071.   072.    void loadop_Completed(object sender, EventArgs e) 073.    { 074.        LoadOperation loadop = sender as LoadOperation; 075.   076.        _interviews.Clear(); 077.   078.        foreach (var ent in loadop.Entities) 079.        { 080.            _interviews.Add(EntityToAppointment(ent as Interview)); 081.        } 082.    } 083.   084.    private void xJobsScheduler_AppointmentAdded(object sender, Telerik.Windows.Controls.AppointmentAddedEventArgs e) 085.    { 086.        // now we have a new InterviewAppointment to add to our QCV :) 087.        InterviewAppointment newInterview = e.Appointment as InterviewAppointment; 088.   089.        this.context.Interviews.Add(AppointmentToEntity(newInterview)); 090.        this.context.SubmitChanges((s) => 091.        { 092.            ActionHistory myAction = new ActionHistory(); 093.            myAction.InterviewID = newInterview.InterviewID; 094.            myAction.PostingID = newInterview.PostingID; 095.            myAction.ApplicantID = newInterview.ApplicantID; 096.            myAction.Description = String.Format("Interview with {0} has been created by {1}", newInterview.ApplicantID.ToString(), "default user"); 097.            myAction.TimeStamp = DateTime.Now; 098.            context.ActionHistories.Add(myAction); 099.            context.SubmitChanges(); 100.        } 101.            , null); 102.    } 103.   104.    private void xJobsScheduler_AppointmentCreating(object sender, Telerik.Windows.Controls.AppointmentCreatingEventArgs e) 105.    { 106.        e.NewAppointment = new InterviewAppointment(); 107.    } 108.   109.    private void xJobsScheduler_AppointmentEdited(object sender, Telerik.Windows.Controls.AppointmentEditedEventArgs e) 110.    { 111.        Interview editedInterview = (from x in context.Interviews 112.                                     where x.InterviewID == (e.Appointment as InterviewAppointment).InterviewID 113.                                     select x).SingleOrDefault(); 114.   115.        CopyAppointmentEdit(editedInterview, e.Appointment as InterviewAppointment); 116.   117.        context.SubmitChanges((s) => 118.        { 119.            ActionHistory myAction = new ActionHistory(); 120.            myAction.InterviewID = editedInterview.InterviewID; 121.            myAction.PostingID = editedInterview.PostingID; 122.            myAction.ApplicantID = editedInterview.ApplicantID; 123.            myAction.Description = String.Format("Interview with {0} has been modified by {1}", editedInterview.ApplicantID.ToString(), "default user"); 124.            myAction.TimeStamp = DateTime.Now; 125.            context.ActionHistories.Add(myAction); 126.            context.SubmitChanges(); 127.        } 128.            , null); 129.    } 130.   131.    private void xJobsScheduler_AppointmentDeleted(object sender, Telerik.Windows.Controls.AppointmentDeletedEventArgs e) 132.    { 133.        Interview deletedInterview = (from x in context.Interviews 134.                                      where x.InterviewID == (e.Appointment as InterviewAppointment).InterviewID 135.                                      select x).SingleOrDefault(); 136.   137.        context.Interviews.Remove(deletedInterview); 138.        context.SubmitChanges((s) => 139.        { 140.            ActionHistory myAction = new ActionHistory(); 141.            myAction.InterviewID = deletedInterview.InterviewID; 142.            myAction.PostingID = deletedInterview.PostingID; 143.            myAction.ApplicantID = deletedInterview.ApplicantID; 144.            myAction.Description = String.Format("Interview with {0} has been deleted by {1}", deletedInterview.ApplicantID.ToString(), "default user"); 145.            myAction.TimeStamp = DateTime.Now; 146.            context.ActionHistories.Add(myAction); 147.            context.SubmitChanges(); 148.        } 149.            , null); 150.    } 151.   152.    #region Appointment Helpers :) 153.   154.    public Interview AppointmentToEntity(InterviewAppointment ia) 155.    { 156.        Interview newInterview = new Interview(); 157.        newInterview.Subject = ia.Subject; 158.        newInterview.Body = ia.Body; 159.        newInterview.Start = ia.Start; 160.        newInterview.End = ia.End; 161.        newInterview.ApplicantID = ia.ApplicantID; 162.        newInterview.PostingID = ia.PostingID; 163.        newInterview.InterviewID = ia.InterviewID; 164.   165.        return newInterview; 166.    } 167.   168.    public InterviewAppointment EntityToAppointment(Interview ia) 169.    { 170.        InterviewAppointment newInterview = new InterviewAppointment(); 171.        newInterview.Subject = ia.Subject; 172.        newInterview.Body = ia.Body; 173.        newInterview.Start = ia.Start; 174.        newInterview.End = ia.End; 175.        newInterview.ApplicantID = ia.ApplicantID; 176.        newInterview.PostingID = ia.PostingID; 177.        newInterview.InterviewID = ia.InterviewID; 178.   179.        return newInterview; 180.    } 181.   182.    public void CopyAppointmentEdit(Interview entityInterview, InterviewAppointment appointmentInterview) 183.    { 184.        entityInterview.Subject = appointmentInterview.Subject; 185.        entityInterview.Body = appointmentInterview.Body; 186.        entityInterview.Start = appointmentInterview.Start; 187.        entityInterview.End = appointmentInterview.End; 188.        entityInterview.ApplicantID = appointmentInterview.ApplicantID; 189.        entityInterview.PostingID = appointmentInterview.PostingID; 190.    } 191.   192.    #endregion 193.   194.    #region INotifyPropertyChanged Members 195.   196.    public event PropertyChangedEventHandler PropertyChanged; 197.   198.    public void NotifyChanged(string propertyName) 199.    { 200.        if (string.IsNullOrEmpty(propertyName)) 201.            throw new ArgumentException("propertyName"); 202.   203.        PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 204.    } 205.   206.    #endregion 207.} Nice... right? :) One really important thing to note as well.  See on line 51 where I set the DataContext before the Loaded event?  This is super important, as if you don't have this set before the usercontrol is loaded, the DataContextProxy has no context to use and your EditAppointmentDialog Job/Applicant dropdowns will be blank and empty.  Trust me on this, took a little bit of debugging to figure out that by setting the DataContext post-loaded would only lead to disaster and frustration.  Otherwise, the only other real difference is that instead of sending an ActionHistory item through an event to get added to the database and saved, I do those right in the callback from submitting.  The Result Again, I only have to post one picture because these bad boys used nearly identical code for both the MVVM and the code-behind views, so our end result is... So what have we learned here today?  One, for the most part this MVVM thing is somewhat easy.  Yeah, you sometimes have to write a bunch of extra code, but with the help of a few useful snippits you can turn the process into a pretty streamlined little workflow.  Heck, this story gets even easier as you can see in this blog post by Michael Washington- specifically run a find on 'InvokeCommandAction' and you'll see the section regarding the command on TreeView in Blend 4.  Brilliant!  MVVM never looked so sweet! Otherwise, it is business as usual with RadScheduler for Silverlight whichever path you're choosing for your development.  Between now and the next post, I'll be cleaning up styles a bit (those RadComboBoxes are a little too close to my labels!) and adding some to the RowDetailsViews for Applicants and Jobs, so you can see all the info for an appointment in the dropdown tab view.  Otherwise, we're about ready to call a wrap on this oneDid you know that DotNetSlackers also publishes .net articles written by top known .net Authors? We already have over 80 articles in several categories including Silverlight. Take a look: here.

    Read the article

< Previous Page | 124 125 126 127 128