tag:blogger.com,1999:blog-79492676712125942242024-03-04T22:34:46.032-08:00DevScapeTips, Tricks, and Lessons Learned from the world of Application DevelopmentJBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.comBlogger91125tag:blogger.com,1999:blog-7949267671212594224.post-51922005812219772932011-08-24T20:40:00.001-07:002011-08-24T20:40:50.670-07:00Book Review: Introducing HTML5 by Bruce Lawson and Remy Sharp<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHzqXuS9UiynF6pxXSQV7inN4yxV384mdYx2TDE_RPqnwYn8c2tSf4i2ZcyEfo4BlU_bNUO2-mB4As7qyyOMUZXJeUkjnTdM0rlJsG_BXZAW7xbmr-Vep_Bghc1XtlA-OBfcVLD8vj3Jo/s1600-h/IntroducingHtml5%25255B2%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 10px 5px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="IntroducingHtml5" border="0" alt="IntroducingHtml5" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLcOiyyOXvs8NCzh3NFMI3Njebj4KjM3Dj_FMU9gxJFEQ3Eg1rkqc0vwoblJS_hVir5SOLwK6Jj_AendGQkSjQ6XMS-wljElQMxs8Zbekp0JRH9C4PHaRJmrlL4_387zl28cjooDS3vHI/?imgmax=800" width="244" height="164" /></a>The buzz in the development world these days has changed. Cloud Computing?<em> That’s so 2010</em>. Multi-core CPU’s? <em>Ho-hum</em>. Tablet computing? <em>Whatever</em>. </p> <p>But when Microsoft announced that the next version of Windows would allow for development in HTML5 and JavaScript, the world took notice, and a lot of us are scrambling to get up to speed. Okay, so some developers have been playing with HTML5 for a while now, and JavaScript has been around for years. I’ve worked in HTML4 for quite a while, and JavaScript has never really floated my boat. I’m a traditionalist. Code compiles. Scripts are what I use to run back in college before I had a real IDE. </p> <p>I say that with only a little bit of sarcasm. I’ve never liked Web UI coding. Working with the infinite number of browsers and their individual peculiarities frustrated the crap out of me. The web was for signing people up for things, watching videos and browsing news and sports. You would never write a real application in this environment. Would you? What masochistic developer would want to build a core business system in something you could never truly test, and would behave differently on every computer? What sadistic system designer would expect users who have jobs to do to wait for a page to refresh every time they wanted to know if their data was valid?</p> <p>When I heard about Microsoft’s intentions, my initial reaction was to think it was a joke. After hearing it a few times, and learning it really was true, my heart skipped a beat. I was worried that I was about to be left behind again technically, and in a few years, I’d be one of those back-end developers that couldn’t change with the time. I’d be branded as a ‘.NET Developer’, something akin to the 2011 version of a COBOL programmer. It didn’t take long for that fear to turn to anger. I’d just invested the last five years working my way deep into the Microsoft .NET Stack, building my skills and my reputation, and… and it just wasn’t fair! This whole process was very similar to the seven stages of grief. I went through the depression of realizing that I was again going to have to rebrand myself and rebuild my skills, and then the realization that doing it the last time really hadn’t been that bad. I started to look at the opportunities this would present – things that I had never before been able to do, that I could now do. I started to research what HTML5 really was, and what it was that made the world so sure this was the way to go.</p> <p>After doing some piecemeal research on the web, I realized I needed a book. I’m a book learning. Reading a book primes my brain. Books are generally better organized than the snippets you might find on line. I wanted to start with the basics, and form a solid base with which I could talk intelligently with my coworkers and my bosses. I wanted a book that would explain it from the beginning.</p> <p><em>Introducing HTML5 (First Edition)</em> by Bruce Lawson and Remy Sharp was the book I chose to get me there, and I highly recommend it. It starts by covering the Structural Elements of HTML5, how pages are organized, the new elements and the expanded role of JavaScript in HTML5 applications. It then dives into some of the more advanced features of HTML, including Audio and Video, Canvas, Data Storage, Offline mode, Drag and Drop, Geo-Location and Messaging. I skimmed the Audio and Video and the Canvas sections since I am usually designing business apps, and haven’t had the need to build an app that draws lines since I was in college. I did, however, build a Silverlight Video player on Windows Azure for <a href="www.demoshowcasesuite.com" target="_blank">Microsoft Demo Showcase</a> back in 2009/2010, so I expect that sooner or later, I’ll be doing something similar to that in HTML5. It’s good to know it’s there.</p> <p>I was fascinated by the offline storage possibilities and the future of messaging and sockets. I can see a day coming very soon where I build an HTML5 app with messaging tied to the service bus on Windows Azure that handles Windows Workflow Processes and notifies users that some long running, multiple streamed process has completed. There’s power there. A lot of it. </p> <p>I do find it a little bit funny that this is the second technical book in a row I’ve read where the authors are constantly taking shots at Microsoft and Internet Explorer. I guess I’ve been buried so deep in the mother-ship for so long, that I don’t have the same level of animosity. Of course, I have worked my career around not having to do a lot of browser work. Perhaps that has insulated me far more than I thought.</p> <p>This book is short and to the point, and a great introduction to HTML5. You won’t come out a world class expert on HTML5, but you will understand the basic concepts, enough to be able to talk about it, and to begin the honest discussion of whether or not that next project you are starting should target HTML5. I’m at least willing to consider it at this point, as long as we don’t implement any features that can’t be made backwards compatible by implementing modernizr.js which is covered by Scott Guthrie <a href="http://weblogs.asp.net/scottgu/archive/2011/05/09/html5-improvements-with-the-asp-net-mvc-3-tools-update.aspx" target="_blank">here</a>.</p> <p>The biggest advantage I see to HTML5 is that in the ideal world going forward, we can build an app once, and as long as it is HTML5 compliant, it should just work on all browsers. I really like that. I want to do the work once, and move on the next project. HTML5 brings the Web UI development out of the dark ages, and makes it a real possibility for someone like me. This is a good book to get up and running inside of a week, and I’ve already recommended it to my team.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-39540998063219206542011-07-30T09:05:00.001-07:002011-07-30T09:05:08.761-07:00Book Review: jQuery in Action<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvl95UzCXcfR8yvXcat8uJQ_5heOScL9vt-ktu4NJOQcrebsCnitrPz-_fHCh24pBnOTPsoGZvMGWnJNAhk-oEYZDCGwIfJ_L1mbFSA9ONR6Xa-76LWT0hf3lMrnsAHFXAbgv4cESOBNo/s1600-h/JQueryInAction%25255B4%25255D.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 10px 5px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="JQueryInAction" border="0" alt="JQueryInAction" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7_-mMOSkT-qhEVREolNDgp9ybqA9FlRH0s80Cm-FU4O0ijq3RUwEaaQlSQ3_anHtqIi8az7BpivbaJJPyeol7L_1WBPfGMjYOoE8pjNlExwCLIrIw3qCDDm4ZZkT4zWfRJ4HcoczF7hQ/?imgmax=800" width="150" height="195" /></a></p> <p>A few years ago, when I first got into ASP.NET development, I worked on a project that used the Ajax Controls Toolkit. I was not a JavaScript person, and my experience with the Toolkit and all its idiosyncrasies left a very bitter taste in my mouth for ‘client-side’ web development. For many of the projects after that, I worked on the back end of the system – the database, data model and business logic, and eventually the controllers and web services. We had a UI guy who tackled the JavaScript stuff and worked ‘magic’ there.</p> <p>A couple of months ago, I got involved in a project which had a very large existing code base, with a lot of jQuery and my UI guy was nowhere to be found. Before I knew it, I was neck deep in it, and drowning fast. I muddled through the project and got it out the door, but I realized that I could no longer have this gap in my education. I also realized, by working on that existing code base, that jQuery was nothing like the JavaScript and Toolkit I once struggled with, and it was really freaking powerful.</p> <p>It turns out that back in early 2010, I had ordered <em>jQuery In Action</em> by Bear Bibeault and Yehuda Katz during some book buying binge, but never read it. It got loaned out to a couple of people at work, and I didn’t see it for the longest time. It wasn’t until I finished working on that big jQuery project that I even remembered that I still had it. I tracked it down, and it flew to the top of my reading list.</p> <p>I wish I had read this book a three years ago. jQuery is really powerful. And it’s really big.  <em>jQuery in Action</em> did a great job of introducing me to the core concepts, and giving me a refresher on basic JavaScript. Ok, not a refresher – an introduction. The unfortunate part is that I ordered this book in early 2010, which meant the version I have is the first edition published in 2008. The second edition came out in May 2010. The first edition covered up to jQuery 1.2. The second edition covers jQuery 1.4.  As I recall, there are some fairly major differences in jQuery between 1.2 and 1.4, but more importantly, there have been major changes in browsers. Internet Explorer was just on Version 7 when the book was written, and a lot of time had to be spent by developers to account for the way IE6 worked, and to a slightly lesser extent, IE7. With IE9 now out and promising “It just works”, I would like to think that jQuery will have gotten even easier in the last few years. The first edition of jQuery in Action has quite a few asides that detail the frustrations developers had with IE6 & 7, and I get the impression that the authors would have little good to say about Internet Explorer in conversation.</p> <p>The book is well organized and the coverage of the core concepts appropriate for a beginning jQuery developer as long as you have a solid background in web development. It even has a very good appendix on JavaScript, which was invaluable to someone like me with a large gap in their knowledge of the subject. They build a large number of exercises into the book as well. Since I was reading the book whilst commuting, I didn’t get a chance to try them, but I think I understood them well enough from the written copy. At the very least, I know they are out there and I can download them when I get a chance to give them a try.</p> <p>What I find amazing about this book (and jQuery), is how many times I thought back to projects I already have in production, and said “Wow, the UI could be so much better”, or “If I had only known about jQuery, the whole architecture would have changed.” The former makes me happy that I can now say “Yes, we can do that.” more often to clients. The latter makes me question my skills as a software architect. I had never even considered some of the approaches presented in the book, and not only would the UI have been more user friendly, it would have been faster and more reliable. I’m disappointed in myself for not taking the time to learn about jQuery before now. I can rationalize all I want about being busy with other things (like learning Windows Azure, MVC, WPF, writing 4 books, etc.) but the truth is that I considered the UI side to be the ‘poofy’ stuff and let other people handle it. The UI, I thought, was just for displaying the results of all the ‘hard work’ done on the back end.</p> <p>No longer. Reading <em>jQuery in Action</em> has opened my eyes to the fact that I have to know all the layers, at least well enough to know what is possible. I have no doubt that there will be aspects (especially in CSS) that require an artist’s touch (which no amount of reading is going to give me), but I will now treat jQuery as a first class language in solving client problems. I still have qualms about jQuery, mainly from the testability standpoint, but I do like the idea of unobtrusive JavaScript which will allow me to keep a separation of concerns and allow me to build up a personal collection of functions that I trust just work.</p> <p>I will, at some point, go out and get the second edition of this book to see what has changed in the last few years, and to reinforce my basic knowledge of JavaScript and jQuery. With HTML 5 and JavaScript coming at developers like an out of control freight train, jQuery in Action is a great way to get started and to get up to speed. </p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-54903461723429957482011-07-19T11:20:00.001-07:002011-07-19T11:20:34.032-07:00Using etc/Hosts to Assist in Testing<p>A coworker and I were in the process of migrating a client’s web server from old hardware to new hardware last week, and we needed to be able to test the system before turning it on to live traffic. The web applications called web services, and the configuration of the web app included the URL for the web services.</p> <p>We needed to be careful what we were doing here, because the web services were also migrating to a new server, and on this new server, were pointing to a new database server as well. We didn’t want to change all the configuration settings on the new servers, and we couldn’t change the public DNS entry.</p> <p>I’ve done this before, but not everyone knows about the following trick, so here it is:</p> <p>On Windows, if you go into your <a>%WinDir%\System32\drivers\etc</a> directory, you’ll find a file called <strong>hosts, </strong>often referred to as “etc\hosts” or “Etsy Hosts”. Open this file with notepad running as administrator on your machine. The instructions for changing this file are right in there, and it’s pretty easy. We added a new line to file on the new server, (and on the test client) like:</p> <p>127.0.0.1       <a href="http://www.palador.com">www.palador.com</a></p> <p>We saved our changes, and then restarted IIS on the box. And presto…</p> <p>But it didn’t work.</p> <p>We reset IIS again, and did an ipconfig /flushdns from the command prompt.</p> <p>And it still pointed to the old domain.</p> <p>We went back to the Hosts file and everything looked fine. I scratched my head. <strong>Then I realized that we had forgotten to put a carriage return after the new line</strong>. We added the hard-return, restarted IIS and flushed DNS, and now everything worked.</p> <p>I’m pretty sure I had run into this exact same issue a few years ago, and that’s why I knew to look for it. Hopefully this will help someone else avoid this issue.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-72480381322663918782011-07-17T20:46:00.001-07:002011-07-17T20:46:09.570-07:00Book Review: The Nomadic Developer by Aaron Erickson<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCM25vG2bGdoyIEspACvyllUpdnqUcTr3ndBrYWQ7RUrX59kRNVCiYfa5oRpjCVbkCL4lQoqpcsqEJMLPJtTv_eig0DFV_pSQEgc1_sZbXVo2DcjH69Ag_NnmOeKrhnVzjuP1gfoNTvrM/s1600-h/NomadicDeveloper%25255B4%25255D.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 10px 5px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="NomadicDeveloper" border="0" alt="NomadicDeveloper" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwXML0lxY6AU3zY1CB1EnP-JHeEB5IDhT9GKEtvQCVPmPaORKLWcsiPZLmu6bjubyh1kuYO3_B_dvlr_4-zBMNW3mYhHGBpbXDx2GnwrbLDmxgWt1Q77qtwqdVf87LDwwPEwaple3CeZo/?imgmax=800" width="198" height="272" /></a>I don’t actually remember how I found this book. It somehow got onto my Amazon wish list one day, and it was one of those things I bought because I needed to top up an order above $25 to qualify for free shipping. I don’t remember what it was that I bought with this book, but I doubt it was as impressive as <em>The Nomadic Developer</em>.</p> <p>It’s funny, because I tell people that I got into the consulting world back in 2008. After reading this book, I realized that I actually started in consulting back in 1994. My very first job in IT was technically at a consulting firm, albeit a very large one, (the one started by Ross Perot back in the sixties and famous for making everyone wear blue suits everywhere they went). I worked on a couple of very large accounts, so it seemed like I was just a developer in Corporate IT, but in reality, I was a consultant. I left that company in 1999, and moved on to real Corporate IT, working for an airline maintaining their revenue management systems, and later on to building and maintaining the fight operations systems. We owned those systems from cradle to grave, twenty four hours a day, seven days a week. They were horribly difficult to change. There was a tremendous amount of tribal knowledge in every subsystem, and many were already five or six years old when I started, and rewrites were impossible. By the end of my 8.5 years there, my technological skills were atrophied to the point where another year or two, and I would have been completely unmarketable outside of that industry vertical.</p> <p>I jumped (back) into consulting in 2008 with little idea of what true consulting was. I wish I had had this book at my disposal back then. Not that I would change my decision – the leap into consulting has done wonders for my skills and my career. I have no doubt that making the move, when I did, was absolutely the right decision for both me and my family, and I’d like to think it was the right decision for the company I work for as well.</p> <p>But in <em>The Nomadic Developer</em>, Aaron Erickson goes into wonderful detail of what to really expect from technology consulting, how to identify good (and bad) companies, how to survive, and how to thrive in the consulting world. He talks about how to maintain both your position and your passion during both good and bad times in the economy, and how to avoid career limiting moves. At the very least, had I read this book while still working for the airline, I could have avoided a couple of interviews that would have led to positions that I was not right for. My trouble-radar kicked in on those before I accepted, and I count myself lucky. By the time I had finished chapter two of The Nomadic Developer, I had already identified those firms as being one of the ‘Seven Deadly Firms’, and hiring on there likely would have tainted my consulting experience for the rest of my career.</p> <p><em>The Nomadic Developer</em> is not only for people who are thinking of becoming consultants. It’s also for consultants who are fairly new to the game, and will help you to stay out of trouble as the economy changes. I think it should also be read by owners/senior management of consulting firms, if only to avoid uncomfortable moments brought on during interviews by people who have read the book and are asking some of the hard questions Erickson suggests. Most of those questions I would be a little uncomfortable asking during a interview, but I see the value in at least trying to ask them. It’s not always the response that is important, it’s the way the response is said that will tell you if the employer is going to treat you as a partner / investment or a warm body / cost.</p> <p>Here are some of the questions he suggests:</p> <ul> <li>What is your annual revenue?</li> <li>What is your (target) profit margin?</li> <li>What is your exit strategy?</li> <li>What’s the value of the sales pipeline?</li> <li>What is the sales process?</li> </ul> <p>I’ve done a lot of interviews of candidates in the last few years, and even though I have been on the technical side, I’ve never been asked questions like that. I’m actually pretty horrible at technical interviews because I hate trivia questions. I prefer to ask about experiences and expectations and to evaluate the personality of the interviewee. If someone was to ask questions like that, and I hadn’t read Erickson’s book, I would perceive them as intelligent but aggressive. But after reading his book, I would think that the candidate truly is trying to find the right fit. If I’m a consulting company senior management, I’m reading this book to make sure I’ve got my crap together so I don’t lose out on good consultants because I look like an amateur. I’m also doing an honest assessment of my company to see if I am making any of the mistakes Erikson lists in the Deadly Firms chapter. Unless my goal is to build an unsuccessful company, I want to be active in fixing these situations, even if it is just an employee perception. I don’t think too many people want to be unsuccessful at running their own company.</p> <p>Another point Erickson makes is about passion for work, and how to maintain that during hard times, especially when the client you are working for is not in an industry you find appealing. I spent three years working for a client that did direct marketing… sending out junk mail and running those annoying call centers that call you during dinner. I slept on my office floor multiple nights while doing system upgrades, and let me tell you, that was really hard to justify to myself after a while. That experience left me quite cynical when it comes to working on projects I don’t fully believe have societal value. In the long run, that cynicism can be a career killer in consulting. It can kill your passion for software development, and once you’ve lost that, it can be very difficult to get it back. Employers, and especially co-workers, notice when your passion withers. In tough markets, not every job will be life-fulfilling, but Erickson suggests that taking pride in the work <u>you</u> do on each project will preserve the passion, and from there, passion will generate positive results and better  opportunities in the future. It takes a while to build up the resume, and there is something to learn on just about every project.</p> <p>I’m giving this book a big, big thumbs up, and making sure that my wife, who is a project management consultant, also reads  this book. Very little of the book is specific to programming, and those bits can be read and parallels drawn with most other industries and job types.</p> <p>Do yourself a favor, and read this book, and then get your coworkers, and your boss to read it too. If the suggestion is negatively received, you may already be working at one of the ‘Seven Deadly Firms’, and its time to find your exit strategy.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-26097481492010955472011-04-12T15:44:00.001-07:002011-04-12T15:44:01.171-07:00Where did I go?<p>Judging by the activity on this blog (or lack thereof), you'd think I was either dead or retired. I am not dead.</p> <p>I am still actively developing software, and am constantly hanging out on the bleeding edge.  To that end, I do occasionally post blog entries on the web site of the company I work for (<a href="http://www.Palador.com">www.Palador.com</a>).  But most of the stuff I work on I cannot discuss in public, or is so well covered by other blogs that I don't see the need to cover.  In the best case I’d just be repeating what someone else has said, or in the worst case, I’d be plagiarizing it.</p> <p>So if you have a question or a comment, feel free to leave it.  But I only swing by this blog once in a blue moon, so if you are in a hurry, you might want to try another search.</p> <p>If you really need to get ahold of me, you can try my writing blog at <a href="http://www.joebeernink.com">www.joebeernink.com</a>.  It’s not technical in the least, but it is monitored much more frequently.</p> <p>Thanks for stopping by.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-5135926358686324912010-09-28T15:18:00.001-07:002010-09-28T15:18:22.898-07:00MVC Abstract Controller<p>It’s been a while since I’ve posted anything here.  I’ve been busy, and most of the stuff I am working on I either can’t blog about or isn’t worth blogging about as it’s pretty much already covered in a dozen other blogs.  But I have been doing a lot of very basic ASP.NET MVC coding lately on a couple of sites.  I’ve stepped step back from my architect role to do some heads down coding to fill a personnel gap.  I don’t get to do that a lot, and I rather enjoy it when I get the chance.  </p> <p>But I did come across a very interesting ASP.NET MVC situation this week that required more than a little thought.  And since my monthly blog entry was due for work, I put a long entry about an <a href="http://palador.com/blog/post/ASPNET-MVC-Creating-an-Abstract-Controller.aspx">ASP.NET MVC Abstract Controller</a> on the <a href="http://www.palador.com">Palador</a> web site blog.</p> <p>Feel free to leave me a note here or there.  I’m always afraid of putting a big ‘code’ blog up because it’s just asking for someone to come along and rip the snot out of it and show me a better way to do it. But in this case, I’ll take the chance, as the solution was simple and saved me a lot of time and frustration.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-76768852288223538372010-08-05T09:16:00.001-07:002010-08-05T09:16:25.978-07:00Book Review: Microsoft SharePoint 2010 – Building Solutions<p> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsmDsLpcEDM4A0djudugcsAjkXGD-ZxbVXvlawM06AfFCJ2OEP3VjzOfsK94TGfcenOCRKC6VQmDh7A95ov2bVuQhBm7IepPNEk3-I7E4hLWTIe52qr6_eTf3ZCdn8Y9q2H9S1xW3GiL8/s1600-h/sp2010%5B4%5D.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="sp2010" border="0" alt="sp2010" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiltUfTlC4_yYyg809x-7pVjDULSv-hwSPefV8EC1HsVLcfTx2aUuGjSfQyIRJbhxcSnH5yuKpdTokD3ixL4ShdQb3h_TJdPv8mRni0WFU2BRlCgLw1gDVgk6B7z9ssY02SgtiLBFy7kZ4/?imgmax=800" width="92" height="118" /></a> The full title of this book by Sahil Malik is <strong>Microsoft SharePoint 2010 – Building Solutions for SharePoint 2010</strong>, and it was recently published by Apress.  I love Apress books, and have 6 others on various .NET related topics on my shelf.  SharePoint 2010 is something I needed to get up to speed on really quickly for a new project at work, as in I had less than a week to make sure I knew what I was talking about.</p> <p>The book is 367 pages, and covers a wide variety of topics in SharePoint 2010.  It demos a few techniques and tools, and identifies some of the differences between SharePoint 2007 and SharePoint 2010, so even if you know SharePoint 2007, it will really help you to identify what is different about 2010.  </p> <p>I’ve barely worked in SharePoint in the past.  I tried a little bit of SharePoint 2003, and dabbled in 2007, but frankly, after seeing how painful it was to work in either of those environments, I wanted nothing to do with it.  SharePoint was where good developers went to watch their career die.  Once you knew it, you were guaranteed to get every crappy job out there, and because you were so valuable to the execs and their TPS reports, there was no way you were ever going to get out without quitting your job.  And then, of course, you were so pigeonholed as a SharePoint developer, you could never get out from under it.  Even if I knew SharePoint 2007, I would never put it on my resume.  Career suicide.</p> <p>SharePoint 2010 seems to be a little different.  With the advent of Windows Identity Foundation and the advanced made in PowerPivot Services, there are definitely things that can be done in 2010 that would take forever in a typical ASP.NET application.  And Linq to SharePoint is a godsend.</p> <p>Malik covers all these topics with a few quick examples so that at least you know what is there, and how to use it.  Each topic is probably worthy of a book of its own.  I don’t have that kind of spare time, so I needed something at this level so I at least can speak the language and help to architect where these features can be used.  Some features I will deep dive into in the future.  Some features I will leave for others on my team to get familiar with.  You can’t know them all.</p> <p>I do have a very big gripe with this book.  It does not appear as if it was ever professionally edited by a real copy editor.  There are grammar and spelling mistakes on just about every page.  As a fellow author, I know how hard it is to produce clean copy by yourself.  A second or third set of eyes is always necessary.  So I don’t blame the author for this, I blame the publishing company, Apress.  I really hope this is not a sign of things to come.  I know things are changing in the publishing world, and time to market on these books is critical and compressed.  But in the two or three dozen technical books I’ve read in the last few years, and the dozens of fiction books I’ve read, I can only remember a few typos.  This book had hundreds, and it drove me batty.  I had to reread entire sentences to try to make sense out of them because words were transposed, missing or extras added in and never removed.</p> <p>Also, the print on this book, and the line spacing is small.  It really felt like they were trying to save paper by eliminating paragraph breaks.  If the book was a fast action thriller, that may not be a problem, but in a technical book, I expect proper formatting.  It helps to convey information and give your brain a break; an indication that the topic or idea is changing.  Without a break, it gets really hard to read. A lot of the graphics are blurry or too dark to read, though that could have been my eyes as I was reading late in the evening.  At one point, it was so bad, I wanted to hurl the book across the room.</p> <p>I’m going to recommend this book, but I really hope they do another edit on it.  Architects should read it.  SharePoint 2007 devs should read it to get up to speed on the changes.  New devs for SharePoint 2010?  Not sure.  It does give a good introduction to SharePoint Development, but you’ll probably end up buying another book as well to get into the nitty-gritty.</p> <p>SharePoint 2010 seems to have come a very long way from it predecessors, but it still feels like it is behind the times, and a little kludgy.  I’m worried that there are difficulties hidden in the practicalities of working with it that are glossed over by this book – things that you could spend a week trying to figure out, only to be frustrated by some weird case where you have to use I before E except after C when the word is in French and followed by an apostrophe.  SharePoint 2010 is to SharePoint 2007 as .NET 2.0 was to .NET 1.1.  The next version should be like .NET 3.5, infinitely better and more stable.  2010 is usable, but just not quite there yet.</p> <p>But it no longer seems like career suicide to know it.  You’ll probably just need to make sure it is not the first item you list on your resume.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com2tag:blogger.com,1999:blog-7949267671212594224.post-36651491109367452612010-08-04T08:30:00.001-07:002010-08-04T08:30:20.894-07:00Book Review: Programming Windows Azure<p>I meant to review Sriram Krishnan’s <a href="http://www.amazon.com/Programming-Windows-Azure-Microsoft-Cloud/dp/0596801971/ref=sr_1_1?ie=UTF8&s=books&qid=1280934338&sr=8-1-spell">Programming Windows Azure</a> book a few weeks ago, but I have been slacking.  It wasn’t until last night, when I was halfway through my next technical book (which I will review soon), that I realized that I had neglected to do the obligatory blog post.</p> <p>I’ve been working with Windows Azure since the day after the CTP Launch.  I was in the Early Adopter program.  I corresponded regularly via email or via the forums with various members of the Azure Team for about 8 months between December 2008 and July 2009.  I’ve led three major projects in the Azure world, and at PDC last year, members of the Azure team were finally able to put a face to the name of the guy that kept asking the questions that kept them working a lot of hours.  Most of them didn’t hold that against me.</p> <p>I give that background because when I bought this book I didn’t think I, of all people, would get much out of it.  It was going to be another trophy on my shelf, a book read, a subject I thought I knew well enough to make this what I would consider a ‘light read’.</p> <p>I was in for a shock.  A refreshing one.  This book taught me something new, or closed a gap in my knowledge base, on just about every page.  While I had worked with Windows Azure, it was in the context of delivering a specific product, and my focus was on using Windows Azure as a tool to allow the product to launch, and a lot of the details had be bypassed.</p> <p>This is a great book – one of the top 3 or 4 technical books I’ve read in the past 3 years.  Every developer working on Azure must read this book.  Must.  Nothing beats the experience of working on a new platform, but this book will sure make it easier, and teach you the benefits and the pitfalls of this environment.</p> <p>The biggest downfall of this book is that Chapters 1 (Cloud Computing) and 2 (Under The Hood) will lose a lot of developers who have no interest in the internals of Azure or the history of cloud computing.  These are both necessary and interesting chapters, but for the non-architect or truly technical geek, most will skim them or skip them.</p> <p>Also, the scope of the book is limited to the Azure Platform itself, and it does not cover things like the AppFabric or the role of Windows Identity Foundation in Azure.  I’m looking for a good book on those as well, since I have yet to deep dive into the Service Bus, and haven’t worked with WIF since it was still called Geneva.</p> <p>The rest of the book is superb, and like I said, I learned something on every page.  Every Azure developer should have this trophy on their shelf.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com1tag:blogger.com,1999:blog-7949267671212594224.post-35379930030936406262010-08-04T07:46:00.001-07:002010-08-04T07:46:02.760-07:00Microsoft Word 2010 Bug<p>I spend a lot of time in Microsoft Word 2010 writing my novels.  I most often am working on my ACER 1420P laptop while doing it, and honestly, this is the only place I have seen this bug, but it annoys the crap out of me. </p> <p>Here’s what happens:</p> <ol> <li>Open a new or existing document</li> <li>Start typing</li> <li>Let you mouse cursor drift up over the tool bar (like the one for text formatting).  </li> <li>Keep typing.</li> <li>Eventually, characters will start repeating.  First you’ll see three ‘c’ characters (or whatever character that falls victim to this bug on that given day).  If you see this start to happen, sometimes moving the mouse will stop the next phase from happening, but if you miss it because you watch your fingers and not the screen (which I am prone to do), phase 2 of the bug will soon kick in.</li> <li>Phase 2 involves Satan taking over your computer.  If you just happen to hit the backspace key or a cursor key, it will start repeating indefinitely.  Next thing you know, your whole document is gone or you are sitting at the top or bottom of your document, and you still can’t get control back.</li> </ol> <p>The only thing that I have ever found that works is to pull up task manager, and kill Word.  But at least it will ask you if you want to save your changes before it closes.  If the repeating character is a cursor movement, no problem.  If it was the backspace key, you are SOL.</p> <p>I find that the bug shows up most often if the cursor seems caught between tool bar buttons.  It looks like a Windows event has gotten into an infinite loop, and as a developer, I would not want to be the one who has to try to figure this one out.</p> <p>That said, I really hope this gets fixed soon.  It happens to me at least once a week, and more than once has cost me work.  I save early and save often because this one could strike at any moment.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-30777857167605361332010-07-05T14:34:00.001-07:002010-07-05T14:34:27.129-07:00Gradients, CSS and Overflow<p>Last year, I built a website (http://<a href="http://www.joebeernink.com">www.joebeernink.com</a>) to handle aspect of my burgeoning writing career.  I also used it to learn ASP.NET MVC.</p> <p>I had a designer do the styles and the graphics, but I did all the HTML work.  When I originally laid everything out, the content all fit nicely on a single 800px long div which exactly matched the length of the repeating vertical gradient the designer put together for me for the outer background.  </p> <p>Once the content got too long, the repeating style left a lot to be desired.  It not only repeated across the X axis, but the Y axis as well, which meant starting at pixel 801, I had this nasty black line across the bottom of the screen, and then the gradient began again.  Yuck.</p> <p>So instead of that, I set overflow = auto on all my inner divs, which for a while meant that the one page that had too much content had an inner scroll bar.  I was kind of okay with that (I shouldn’t have been), but CSS has never been something I’ve worked with a lot, so I ignored it.</p> <p>Lately, as I’ve been upgrading my site for an upcoming conference, every page began to have the scroll bar, and it was killing me.  I talked to my designer at work and they shook their heads and said, “Dude, that’s like one line of CSS to fix.  Don’t be such a loser.”  Okay they didn’t say that, but they should have.  They said it was pretty easy, and could be done in a single line of CSS.  They were going to send me that line of CSS, but must have forgot.  So yesterday, knowing that a single line solution existed, I got ready to do some CSS spelunking, and eventually came up with the solution.</p> <p>Out with the old CSS Classes</p> <p>.page <br />{ <br />    background-image: url("../../Content/beernink_pagebkgd.jpg"); <br />    margin-left: auto; <br />    margin-right: auto; <br />    background-repeat: repeat; <br />}</p> <p>#main <br />{ <br />    margin-left: auto; <br />    margin-right: auto; <br />    padding: 20px 30px 20px 30px; <br />    background-image: url("../../Content/beernink_insideBkgd.jpg"); <br />    background-repeat: repeat; <br />    margin-bottom: 5px; <br />    width: 740px; <br />    _height: 1px; /* only IE6 applies CSS properties starting with an underscrore */ <br />    overflow: auto; <br />    height: 500px; <br />}</p> <p>And in with the new</p> <p>.page <br />{ <br />    <strong>background: #252E33 url("../../Content/beernink_pagebkgd.jpg"); <br /></strong>    margin-left: auto; <br />    margin-right: auto; <br />    background-repeat: <strong>repeat-x</strong>; <br />}</p> <p>#main <br />{ <br />    margin-left: auto; <br />    margin-right: auto; <br />    padding: 20px 30px 20px 30px; <br />    background-image: url("../../Content/beernink_insideBkgd.jpg"); <br />    background-repeat: repeat; <br />    margin-bottom: 5px; <br />    width: 740px; <br />    _height: 1px; /* only IE6 applies CSS properties starting with an underscrore */ <br /><strong>    /* overflow: auto; <br />    height: 500px; */ <br /></strong>}</p> <p>The #252E33 is the color at the bottom of the gradient. The color nicely fills the page beyond the 800px line, and looks great.  </p> <p>There are probably better ways to do this, but this was simple and allowed me to say the site was ‘done-done’ for the conference later this month.</p> <p>Of course, now I want to find a real blogging engine in ASP.NET MVC that I can deploy with my site.  Any recommendations?</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com1tag:blogger.com,1999:blog-7949267671212594224.post-27339435863340470302010-05-07T07:08:00.001-07:002010-05-07T07:08:23.741-07:00Silverlight + Azure Shared Access Policy Issue<p>We’ve been working with <a href="http://blog.smarx.com/posts/shared-access-signatures-are-easy-these-days">Shared Access Policies</a> in Azure for the last week or so, and for the most part it was working.  But it would only work for a while, then it would stop.  Then it would start working again.   It took some help from Steve Marx and Jai Haridas on the Azure Team to figure out what was going on.</p> <p>This first piece of code is part of our storage manager that retrieves the Uri for the blob from Azure Blob Storage, and creates a Shared Access Policy for that blob so that our Silverlight Video Player can directly access the blob without going through a very slow web service call.</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> <span style="color: #008000">/// <summary></span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span> <span style="color: #008000">/// Get the Uri for a specified video blob</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> <span style="color: #008000">/// </summary></span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span> <span style="color: #008000">/// <param name="videoId">The unique identifier of the video</param></span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5"> 5:</span> <span style="color: #008000">/// <returns>A Uri ponting to the Video</returns></span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6"> 6:</span> <span style="color: #0000ff">public</span> Uri GetVideoBlobUri(Guid videoId)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7"> 7:</span> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8"> 8:</span> var log = Log4NetHelper.GetLogger();</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9"> 9:</span> log.DebugFormat(<span style="color: #006080">"Getting Video for video id {0}"</span>, videoId);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10"> 10:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11"> 11:</span> <span style="color: #0000ff">try</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12"> 12:</span> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13"> 13:</span> CloudBlobContainer container = GetContainer(<span style="color: #006080">"VideoContainerName"</span>);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14"> 14:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15"> 15:</span> CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference(<span style="color: #0000ff">string</span>.Format(CultureInfo.InvariantCulture, <span style="color: #006080">"{0}"</span>, videoId));</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16"> 16:</span> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17"> 17:</span> var readPolicy = <span style="color: #0000ff">new</span> SharedAccessPolicy</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18"> 18:</span> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum19"> 19:</span> Permissions = SharedAccessPermissions.Read,</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum20"> 20:</span> SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(10)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum21"> 21:</span> };</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum22"> 22:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum23"> 23:</span> var blobUri = <span style="color: #0000ff">new</span> Uri(cloudBlockBlob.Uri.AbsoluteUri + cloudBlockBlob.GetSharedAccessSignature(readPolicy));</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum24"> 24:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum25"> 25:</span> log.DebugFormat(<span style="color: #006080">"GetVideoBlobUri successfully retrieved for video id {0}"</span>, videoId);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum26"> 26:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum27"> 27:</span> <span style="color: #0000ff">return</span> blobUri;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum28"> 28:</span> }</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum29"> 29:</span> <span style="color: #0000ff">catch</span> (StorageClientException ex)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum30"> 30:</span> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum31"> 31:</span> <span style="color: #008000">// If the blob was not found, return null</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum32"> 32:</span> <span style="color: #0000ff">if</span> (ex.ErrorCode == StorageErrorCode.BlobNotFound)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum33"> 33:</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum34"> 34:</span> <span style="color: #008000">// Rethrow the exception in all other cases</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum35"> 35:</span> <span style="color: #0000ff">throw</span>;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum36"> 36:</span> }</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum37"> 37:</span> <span style="color: #0000ff">catch</span> (Exception ex)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum38"> 38:</span> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum39"> 39:</span> log.ErrorFormat(<span style="color: #006080">"Error while retrieving video blob {0}"</span>, ex.Message);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum40"> 40:</span> <span style="color: #0000ff">throw</span>;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum41"> 41:</span> } </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum42"> 42:</span> }</pre><br /><!--CRLF--></div><br /></div><br /><br /><p>In our Silverlight Web Service, we call this manager class and return the Uri embedded in an XElement.  Originally we did this to allow us to return other information with the Uri, but at this point, the Uri is all we are passing through.</p><br /><br /><div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"><br /> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> <span style="color: #008000">/// <summary></span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span> <span style="color: #008000">/// Get video URI.</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> <span style="color: #008000">/// </summary></span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span> <span style="color: #008000">/// <param name="videoId">ID of the given video.</param></span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5"> 5:</span> <span style="color: #008000">/// <returns>Status</returns></span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6"> 6:</span> <span style="color: #0000ff">public</span> XElement DemoVideoUri(<span style="color: #0000ff">string</span> videoId)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7"> 7:</span> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8"> 8:</span> var blobManager = UnityFactory.Current.Resolve<IBlobManager>();</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9"> 9:</span> var blobUri = blobManager.GetVideoBlobUri(<span style="color: #0000ff">new</span> Guid(videoId));</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10"> 10:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11"> 11:</span> <span style="color: #0000ff">string</span> xml = <span style="color: #0000ff">string</span>.Format(<span style="color: #006080">"<VideoUri>{0}</VideoUri>"</span>, HttpUtility.HtmlEncode(blobUri.AbsoluteUri));</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12"> 12:</span> var sr = <span style="color: #0000ff">new</span> StringReader(xml);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13"> 13:</span> <span style="color: #0000ff">return</span> XElement.Load(sr);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14"> 14:</span> }</pre><br /><!--CRLF--></div><br /></div><br /><br /><p>On the Silverlight side, we take make a call to this web service, extract the Url from the XElement, and pass the Url into the MediaPlayer like so</p><br /><br /><div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"><br /> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> var client = <span style="color: #0000ff">new</span> WebClient();</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> var videoUri = GetVideoUri();</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5"> 5:</span> client.DownloadStringCompleted += (x, y) =></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6"> 6:</span> Dispatcher.BeginInvoke(</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7"> 7:</span> () =></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8"> 8:</span> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9"> 9:</span> var xdoc = XDocument.Parse(y.Result);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10"> 10:</span> var query = from b <span style="color: #0000ff">in</span> xdoc.Descendants()</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11"> 11:</span> select b.Value;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12"> 12:</span> HostedVideoUri = <span style="color: #0000ff">new</span> Uri(HttpUtility.HtmlDecode(query.First()), UriKind.Absolute);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13"> 13:</span> mediaPlayer.Source = HostedVideoUri;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14"> 14:</span> Log(<span style="color: #0000ff">string</span>.Format(<span style="color: #006080">"HostedVideoUrl = {0}"</span>, HostedVideoUri.AbsoluteUri));</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15"> 15:</span> }</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16"> 16:</span> );</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17"> 17:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18"> 18:</span> client.DownloadStringAsync(<span style="color: #0000ff">new</span> Uri(videoUri, UriKind.Absolute));</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum19"> 19:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum20"> 20:</span>  </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum21"> 21:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">string</span> GetDemoVideoUri()</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum22"> 22:</span> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum23"> 23:</span> var host = HtmlPage.Window.Eval(<span style="color: #006080">"window.location.hostname;"</span>) <span style="color: #0000ff">as</span> <span style="color: #0000ff">string</span>;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum24"> 24:</span> var path = HtmlPage.Window.Eval(<span style="color: #006080">"window.location.pathname;"</span>) <span style="color: #0000ff">as</span> <span style="color: #0000ff">string</span>;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum25"> 25:</span> var refererUri = host + path;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum26"> 26:</span> var url = <span style="color: #0000ff">string</span>.Format(<span style="color: #006080">"http://{0}/xxxx.Svc/DemoVideoUri/{1}"</span>, GetHost(), VideoId);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum27"> 27:</span> <span style="color: #0000ff">return</span> url;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum28"> 28:</span> }</pre><br /><!--CRLF--></div><br /></div><br /><br /><p></p><br /><br /><p>This is all pretty simple code (and the above code works, by the way).</p><br /><br /><p>Where we ran into problems was in the Web Service, when populating the xml string.  Originally, we used blobUri.ToString() instead of blobUri.AbsoluteUri.   This caused big issues (403 errors returned from the Azure Storage Service), when the Video Player tried to retrieve the blob because the Url returned from the Shared Access Policy generator can have spaces in it.  And Uri.ToString and Uri.AbsoluteUri work very differently when handling spaces.  I did not know this until last night.  <a href="http://www.pluralsight-training.net/community/blogs/keith/archive/2009/10/10/beware-uri-tostring.aspx">Uri.ToString unescapes the Uri before returning it.</a></p><br /><br /><p></p><br /><br /><p></p><br /><br /><p>So why did it work sometimes, and not all the time?  Simple.  Sometimes the Uri from the Shared Access Policy Generator has spaces, and sometimes it does not.  The former did not work, while the latter did.  We were looking for a pattern in the number of times we called the web service, or the interval between calls, and the size of the video blob.  But it was as simple as a single space.</p><br /><br /><p>I think we spent at least 8 hours over the last two days trying to track down this bug.  Hopefully this saves someone else some grief.</p><br /><br /><p><font size="1">This post is cross posted on </font><a title="http://www.palador.com/blog/Blog/Silverlight--Azure-Shared-Access-Policy-Issue" href="http://www.palador.com/blog/Blog/Silverlight--Azure-Shared-Access-Policy-Issue"><font size="1">http://www.palador.com/blog/Blog/Silverlight--Azure-Shared-Access-Policy-Issue</font></a><font size="1"> intentionally.</font></p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-89467493476608307102010-04-26T12:08:00.001-07:002010-04-26T12:08:39.455-07:00Book Review: Professional Application Life Cycle Management with Visual Studio 2010<p>We’re jumping into Visual Studio 2010 this week, and beginning the migration to TFS 2010 as well.  I wanted to get familiar with TFS 2010 and try to standardize our practices a little more before we mis-configured everything, so I bought the first book I saw that seemed to cover TFS 2010.  Professional Application Lifecycle Management with Visual Studio 2010 by Mickey Gousset, Brian Keller, Ajoy Krishnomoorthy and MArtin Woodward fit the bill for what I was looking for and more.</p> <p>The book is broken into 5 Parts:</p> <ul> <li>Architect</li> <ul> <li>This was a little basic, and highlighted a few new features in VS 2010 that I once used Visio to accomplish.  But it also clarified for me a few basic UML constructs that I rarely used or may have been using incorrectly.  I’m not sure I’ll use all of the available UML diagrams very frequently, mainly because not everyone on the team will be able to use them or understand them, but I’ll see how it goes.  Ironically, this may be the last section that is truly useful for me.</li> </ul> <li>Developer</li> <ul> <li>I’m going to make sure all my developers are familiar with the new capabilities of VS2010, and this is a fantastic guide to what is possible.  It make take a little effort to get to add these tools to the dev tool belt, but I think these time savers make the difference between a professional development shop, and a place that is just throwing code over the fence.</li> </ul> <li>Tester</li> <ul> <li>A great section about brand new functionality in 2010, and an area both testers and devs should be reading.  I’m hoping that I can really alter our expectations of the relationship between dev and QA through the use of these tools, and that by the end of the year, our QA process can be much more thorough than it is now, and not cost any more time than it already does.  It’s definitely been the neglected child of the development process, and my goal for the rest of 2010 is to bring it up to speed.</li> </ul> <li>Team Foundation Server</li> <ul> <li>A solid primer on TFS and some good guidance on branching and merging.  A must read for dev leads, architects and build engineers</li> </ul> <li>Project / Process Management</li> <ul> <li>This is the section that really got my attention at first, and the one I would like everyone here to read, even the execs, and especially the solution managers.  Half the battle of good project execution is getting everyone on the same page of terminology and process.  This is definitely worth a read for a shop that is will to make changes, not for the sake of making changes, but to fix issues and bring themselves into compliance with the rest of the development world to eliminate the vocabulary barrier.</li> </ul> </ul> <p>I found all the sections useful as a starting point to either make slight improvements to the processes we use, or as a guideline to make wholesale changes to how we are working to improve our output.  </p> <p>What I really liked about this book was that while I could have figured this stuff out on my own over the next year or so, it gave me a good primer to get started, so hopefully that will result in fewer wrong steps, and let me know about hidden features that I may have never discovered.  </p> <p>I powered through this book in about a week, and I’m sure I remember less than 50% of it.  But at least I know where to go to look things up, and can begin to plot out direct for the configuration of our TFS servers and our processes.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com6tag:blogger.com,1999:blog-7949267671212594224.post-68625094968395049602010-03-02T15:13:00.003-08:002010-03-02T15:13:24.998-08:00Book Review: Introducing .NET 4.0<p>I recently finished reading Alex Mackey’s book, “Introducing .NET 4.0 With Visual Studio 2010”.  VS2010 won’t be launched until April 12, 2010, which is still just over a month away, but I’ve been champing at the bit, ready to dive into .NET 4.0 for months now.  Mackey does a great job of whetting my appetite without drowning me in the minutiae of each new or improved feature.  </p> <p>.NET 4.0 is all about improvements to pieces that have been slowly coming together over the past few years.  There have been a number of out of band releases to the .NET Framework since .NET 3.5 launched.  .NET 4.0 enhances a lot of those releases, and, in some cases, completely goes back to the drawing board.  There are a few new features that will make developers happy, but for me, the money is in the things Microsoft made better.  </p> <p>Mackey assumes you have a good knowledge of .NET, as this book targets what is new since 3.5.  He includes things which were included in .NET 3.5. SP1, since not everyone may have gotten into that yet.  I was pleasantly surprised at how much of the SP1 functionality we have actually put to use here, and was able to skim those chapters.</p> <p>There are parts of the book that were finished before the actual functionality of VS2010 or .NET 4 were finalized, but that’s what you’ll get when you buy a book on a product before the product is released. Caveat Emptor.</p> <p>By the end of the book, I was able to make some decisions on what functionality to target for further research.  My bets are on three areas that will have the biggest payoffs for my team and my customers:</p> <ul> <li>MEF (Managed Extensibility Framework) </li> <li>Entity Framework 4.0 </li> <li>Windows Workflow 4 </li> </ul> <p>With MEF being such an integral part of Office 2010, a good working knowledge of it is essential to provide process enhancements for our customers.</p> <p>We use Entity Framework 1.0 in just about every project we work on, and the leap to 4.0 should resolve a number of significant issues and code costs that we have encountered in the past year.  I expect to see a large effort reduction in application development costs due to this upgrade.</p> <p>If the improvements to Windows Workflow are as good as advertised, then I believe WF will go from shunned cousin to an accepted member of the development family.  There’s a lot of power in WF, but the previous implementation was lacking.  I stopped considering the previous releases as viable last year after a few false starts, but I have much higher hopes for it going forward with V4.</p> <p>I recommended Introducing .NET 4 to my colleagues as a good getting started guide, and directed some to target certain chapters to match up with the type of work they typically do, or areas where they have yet to become involved in to give them a 40,000 foot view.  </p> <p>I will probably go out and buy other .NET 4 books as they become available, but will focus on the three areas above as they will have the biggest impact to my architecture choices in the coming months.  </p> <p>Mackey helps to give that guidance, and gets me excited for the new features.  That’s what I want in an introductory level book.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-74304916160142447862010-03-02T15:13:00.001-08:002010-03-02T15:13:08.367-08:00Cross Site Blogging<p>Today, I’m proud to announce the launch of a revamped <a href="http://www.palador.com">Palador.com</a> web site.  Palador is the consulting company that I work for, and as the Senior Application Architect there, I will be doing my part to blog there, as well as here, and my personal blog as well.  That’s a whole lot of blogging, but I actually get paid to blog there, so hey, I’m okay with taking that on.</p> <p>Occasionally, I will cross post blogs here and there.  Sometimes things will be posted there and not here, depending on the topic. We’ll see how it goes.</p> <p>We’ll have five or six of us posting entries on a variety of topics, which is cool as it just goes to show how diverse our skill set is here.  </p> <p>Anyway, take a spin over to the new site and let us know what you think.  I wrote or edited a lot of the copy there, so if you find issues, let me know. </p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-64189600387176655772010-02-01T10:45:00.001-08:002010-02-01T11:30:20.393-08:00Living the Evolved Digital Life<p>Okay, it’s been a couple of months since I evolved my digital life, cut the cord to Premium Digital TV, and got my house in order.  So where am I now?</p> <p>1.  Lesson Learned:  You cannot run digital video over a wireless router, especially if you have more than 1 wall to go through.  Bite the bullet and pull the ethernet cable if you can.  I was always at 4 bars with the XBox 360, but the router would shutdown every hour or so (sometimes 3 times in a single episode of CSI).  Pulling the cable through the floor was a PITA, but worth it now.</p> <p>2.  Spend some time and tune your Harmony remote.  It’ll take a lot of time to get it right.  I still have work to do on mine, but each improvement is noticeable, and after a while, you can’t believe you used to use 3 (or 4) remotes.  That said, sometimes it still is a big pain, especially when the kids are sleeping and you switch video inputs, and the sound is cranked up and you can’t get back to turn down the volume down fast enough.  I find myself planning my moves with the remote.</p> <p>3.  Make sure you have enough disk (at least 1TB) on your Media PC.  I still haven’t hooked up my HD tuner because I haven’t wanted to spend any more money on the setup right now to add enough disk to record HD shows.  I’d also like to have a dedicated Media PC with faster processors that can also host PlayOn, but since we have multiple laptops floating around the house, most of the time the PC is a dedicated Media machine.</p> <p>4.  2010 will be the year Internet TV really takes off.  My wife says we were probably a year or two early jumping online, and maybe we were.  I’m looking at things like Boxee Box and thinking that was probably what I wanted.</p> <p>5.  We miss having a channel guide on our TV.  We currently have to switch over to the Media center to get it, and because we get more channels on the cable than what the media center allows us to see, we don’t always know what is on at any given time.  This might be worth a little more research.</p> <p>6.  I don’t use Hulu near as much as I thought I would.  I just don’t want to go back and watch old shows that often.</p> <p>7.  I watch a lot more Netflix and am willing to break movies up over multiple nights if I need to.</p> <p>8.  The kids don’t miss on demand that much.  We have a few videos laying around at home, and a few lined up on Netflix.  That seems to get us through rainy Saturday afternoons.</p> <p>9.  Maybe I’ve just been busy the last couple of months, but I am watching less TV.  That was a side effect I hoped for.  I’m reading more, and watching better TV when I am watching it.  When there is a little resistance to the inertia of just keeping the TV on all evening, you find other things to do pretty quickly.</p> <p>10.  I haven’t sprung for the XBox Live Gold Membership since I get everything I want through PlayOn, but as I was watching a movie last night, I definitely noticed that the hop across my HomeServer through PlayOn left dark scenes a little blocky.  For $40 a year, it might be worth it to get the membership.</p> <p>These things always turn out to be a little more complicated than you think they will.  I feel pretty good about it now, but it’ll be a few months before I really forget the pain of the conversion.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-9008388691736741492010-01-14T13:07:00.001-08:002010-01-14T13:07:40.122-08:00.Net 4.0 and Azure<p>We were mapping out a release schedule for one of our Azure based applications today, and a major part of the application needs to be completely refactored to eliminate tight coupling between our WPF client and our server application.  This coupling is exacerbated by the inability to properly XML serialize some of our Entity Framework 1.0 objects due to the recursive traversal capabilities of EF 1.0.  We’d like to push the refactor back until EF 4.0 is available, but that brought up the question of when .NET 4.0 would be available on Azure.  </p> <p>There is no set release data for Azure with .NET 4.0 support at this time. However, Scott Guthrie mentioned on his blog on Dec 17<sup>th</sup> that </p> <blockquote> <p>“We are working with the Azure folks right now to try and get .NET 4 installed on it as soon as possible.  Unfortunately I don't have an exact ETA yet.”</p> </blockquote> <p>However, the Azure team this week (today since Thursday is their deployment day) did a release to include an ‘OS Version’ attribute for roles so you could specify a particular Azure Build level when deploying. It will default to the most current version if you don’t set it, so it is a way to ensure that if you don’t want to be upgraded, you won’t be. Right now, they only support one version of the Azure OS. This has to be a precursor to the .NET 4 rollout, and something we have been trying to get them to include since our very first meeting with the Azure Team back in November 2008.  I haven’t looked at the feature in detail, but I’m glad they’ve addressed the concern.</p> <p>My guess is that they will have to spin up .NET 4.0 support well before the commercial launch of .NET 4 because of the integral role of Azure in VS2010, and that in order for final testing to happen, they’ll have to allow full .NET 4.0 Azure deployments. Kind of a chicken and egg thing.  Stay tuned.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-48165402246574882242010-01-14T11:48:00.001-08:002010-01-14T11:48:04.350-08:00Setting up VS2008 For Windows Mobile 6.1 Development<p>There are a few tricks to setting up your PC for Windows Mobile 6.1 Development that are needed to get moving.  Of course some of this will depend on exactly what you want to do in Windows Mobile.</p> <p>My project was pretty simple.</p> <ol> <li>Create a Windows Mobile Forms app that interfaces with a Motorola M9090-G scanning device that allows a user of the scanner to scan their employee badge barcode, a barcode for a shipping document, and a barcode for a series of packages.</li> <li>The user will scan a large number of packages, and then send their scan records in a batch to a central database for further processing.  The user may or may not be close to a wireless access point at the time of the scan.</li> <li>The app has to be fast.   The folks using this device will fly through dozens of packages a minute, and there will be multiple scanners working to unload a truck, but there are logical gaps in the loading and unloading where the app can upload to the database.</li> </ol> <p>It’s pretty obvious I needed a client cache for the data.  I chose Microsoft SQL Server CE.  For the backend data store, we’re using SQL Server 2008 (with Change Tracking turned on)</p> <p>I didn’t want to custom build a synchronization methodology, and since I played with Microsoft Sync Services a bit last spring on another project, it seemed like a good place to start.</p> <p>First off, VS2008 SP1 comes with a number of emulators built in, but no Windows Mobile 6 emulators.  In order to get the right emulators installed, download the following, and install in the following order.  You’ll need to shut down VS2008 to complete this install.</p> <ol> <li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=06111A3A-A651-4745-88EF-3D48091A390B&displaylang=en" target="_blank">Windows Mobile 6 Profession and Standard Software Development Kits Refresh</a></li> <li><a href="http://www.microsoft.com/downloads/details.aspx?familyid=38c46aa8-1dd7-426f-a913-4f370a65a582&displaylang=en" target="_blank">Windows Mobile 6 Professional Images (USA).msi</a></li> <li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6eb8d0aa-bc6b-4864-8ffe-dc26e1d9f843&displaylang=en" target="_blank">Microsoft Windows Mobile Device Center Driver</a></li> <li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=38ed2670-a70a-43b3-87f3-7ab67b56cbf2&displaylang=en" target="_blank">Microsoft SQL Server CE for Devices</a></li> <li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=75FEF59F-1B5E-49BC-A21A-9EF4F34DE6FC&displaylang=en" target="_blank">Microsoft Synchronization Services for ADO.NET</a> for devices – note that you cannot user Sync Services 2.0, as it is not device ready yet.</li> </ol> <p>You should now be able to fire up VS2008 and create a new Smart Device Project.  Make sure you set it up for Windows Mobile 6, or you’ll not have all the options you need, and will have to start over.</p> <p>One mistake I made, was not realizing that there is a different version of <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=38ed2670-a70a-43b3-87f3-7ab67b56cbf2&displaylang=en" target="_blank">Microsoft SQL Server CE for Devices</a> than for PCs.  You will need to download the correct version to get everything to work.</p> <p>I strongly suggest creating two solutions for this type of an application.  One for the Mobile client, and one for the WCF Service, whether it be a Windows Service or a Web Service.  It makes it a lot easier to debug, and helps to ensure that you don’t try to deploy Mobile targeted assemblies to the server and vice versa.  The IDE should prevent you from doing it, but it doesn’t hurt to take this approach anyway.</p> <p>I like writing code, but I like getting projects done even more.  So if I find code out there that works, I’m not afraid to put it to use.  There were a couple of projects I found that really help to do some of the heavy lifting:</p> <ol> <li><a href="http://synccomm.codeplex.com/" target="_blank">SyncComm on Codeplex</a>.  This provides you with all the plumbing you need to get Windows Mobile Sync working in your project.  If there is one thing I would change (and did) in the project, it was to break the ClientService.cs up into another partial class to remove the customizations that were done to it.  I have found three methods that I moved into a separate file.  Otherwise the code gets wiped out when you regenerate it.  Cost me an hour of work.  See code below.</li> <li><a href="http://msdn.microsoft.com/en-us/library/ms751458.aspx" target="_blank">Custom Message Encoder: Compression Encoder on MSDN</a>.  Download the sample there.  The download link is trickily hidden under the title of the article.  This provides you with all kinds of samples.  The one you want to go to is under <installroot>\WCFSamples\WCF\Extensibility\MessageEncoder\Compression\CS.  Take the GZipEncoder and add the project to your server solution.</li> </ol> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> ServerClient(System.ServiceModel.EndpointAddress endPointAddress, BindingType bindingType)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> : <span style="color: #0000ff">this</span>(GetBinding(bindingType), endPointAddress)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> { }</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">static</span> Binding GetBinding(BindingType bindingType)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> Binding binding;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">switch</span> (bindingType)</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">case</span> BindingType.Basic:</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> binding = CreateDefaultBinding();</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">break</span>;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">case</span> BindingType.Compressed:</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> binding = CreateCompressionBinding();</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">break</span>;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">default</span>:</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> ArgumentException(<span style="color: #006080">"BindingType value not excepted"</span>);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> }</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">return</span> binding;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> }</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//NOTE:</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//set compressed endpoint binding custom properties here</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> Binding CreateCompressionBinding()</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> {</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">// Create a CustomBinding</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> var customBinding = <span style="color: #0000ff">new</span> CustomBinding();</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">// Create a compression binding element</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> var compressionBindingElmnt = <span style="color: #0000ff">new</span> CompressionMessageEncodingBindingElement();</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">// ..and add to the custom binding</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> customBinding.Elements.Add(compressionBindingElmnt);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">// Create an HttpTransportBindingElement and add that as well</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> var httpBindingElement = <span style="color: #0000ff">new</span> HttpTransportBindingElement();</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//TODO</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//Set here desired values. Take care to match such values </span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//in app.config in SyncComm host project</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//max buffer size</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//httpBindingElement.MaxBufferSize = int.MaxValue;</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//max received message size</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//httpBindingElement.MaxReceivedMessageSize = long.MaxValue;</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//max buffer pool size</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #008000">//httpBindingElement.MaxBufferPoolSize = long.MaxValue;</span></pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> customBinding.Elements.Add(httpBindingElement);</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> <span style="color: #0000ff">return</span> customBinding;</pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre><br /><!--CRLF--><br /><br /> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> }</pre><br /><!--CRLF--></div><br /></div><br /><br /><p>In order to get WCF to connect from the Windows Mobile 6 Emulator to a Web Service on the local host, you’ll need to follow the steps listed by <a href="http://stackoverflow.com/questions/735770/wcf-on-pocketpc-not-connecting-to-host-machine" target="_blank">Chris Brandsma on StackOverflow</a>.  This is critical and can cause a lot of frustration if you don’t do it.</p><br /><br /><p>So as of today, I have a client on my Windows 6 Emulator, a Web Service, and the basic data flowing, though I have a lot of work left to do to test and refine the processing, and to test on an actual device.  I’m sure I’ll find a few more issues, but I wanted to note what I had done to this point, just in case I need to replicate the process on another PC or build server here in the near future.</p><br /><br /><p>Let me know if this doesn’t work for you.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-27242459518949376502010-01-11T20:17:00.001-08:002010-01-11T20:17:16.314-08:00Windows Mobile versus Windows CE<p>As I explore the wonderful world of really small screens, I’m having to choose between Windows CE and Windows Mobile.  There are pros and cons to both, and what I’m going to list below is just what I think I know at the moment.  Of course what I thought I knew on Friday has changed a bunch, so I’m sure I’ll be contradicting myself in later posts, if not calling myself a complete idiot.</p> <p>Windows CE is a term used to describe a variable set of OS components that can be deployed to small devices with limited memory and storage.  If you look at the .NET Framework options available in CE apps, you’ve got very little available.  Certainly no WPF, no Silverlight, no native WCF.  You basically need to build up your OS as you go with these components.</p> <p>Windows Mobile is built on top of CE, but comes with a more standard (i.e. heavier) package of components and applications built into the OS.  The basic environment to run the application is baked in, but you can add elements from CE type SDKs as needed.</p> <p>At this point, there seems to be the following CE Environments:</p> <ul> <li>4.2 – Deprecated and generally not supported</li> <li>5.0 – Most devices can run 5.0.  Its like the XP of the Device world.</li> <li>6.x – Various incantations of 6.0 are out there, but the adoption rate by the major vendors is slow.  Motorola (who bought Symbol), is the big player in the scanner market, and they’re just releasing their 6.x machines this year, and 6.x hit the market in 2006.</li> </ul> <p>Windows Mobile is on a slightly different pace</p> <ul> <li>5.0 – Seems to be fading fast</li> <li>6.0, 6.1 – Are the mainstay of the Windows Mobile Market place, though being surpassed on phones by 6.5</li> <li>6.5 – The current version, though wikipedia says it was never really planned.  It just sort of happened.  I hate it when that happens.</li> <li>7.0 – The light at the end of the tunnel, coming out sometime this year.  Rumors are swirling that the whole OS will be built in Silverlight.  Microsoft has to come out with something just kick ass to stay relevant in the market.  If Windows Mobile 7 is still based on CE, then that’s a good indication, that they’ve given up on everything except bar code readers.</li> </ul> <p>As I was evaluating the various options, I got that creepy feeling with Windows CE, that if I tied my client to it, or worse, spent the year learning it myself, it would be obsolete before the calendar read 2011.  I was also finding it really difficult to just get going with it, finding the tools I needed to build the software, figuring out how to deploy it, and how to build an emulator for it.  I can’t say that from an architectural perspective, it’s a bad product, but in my gut, I knew it was a dead end.  It hasn’t updated in 4 years.  Even COBOL has been updated in the last 4 years, right?</p> <p>So I switched my project over to target Windows Mobile 6.1, and within an hour or two (most of that being downloads of SDKs), I was up and running, and realizing just how little real-estate is on a 240px-320px screen.  Now it’s a matter of figuring out Windows Synchronization Services, and I’m off and running.</p> <p>Tomorrow, I’ll post what I did to get my Visual Studio 2008 ready to build and test the Windows Mobile app, which is something I need to document anyway, since I’ll be getting a new work computer soon, and will need to reinstall it anyway.</p> <p>Let me know if you think my evaluation is off target.  I’d appreciate the feedback.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-63026174063470426572010-01-08T17:19:00.001-08:002010-01-08T17:19:42.113-08:00Windows Devices<p>I recently took on a new project at work to build a custom scanning app for one of our customers.  It’s a brand new system, likely to be built on the Motorola (ex-Symbol) MC3090-G or MC90900G platform using either Windows CE or Windows Mobile as the base environment.</p> <p>I’ve never worked on a mobile device, and the first three days has been something of an adventure.  I’d love to use Silverlight, but the 3090 doesn’t seem to support it.  I’d love to use the Microsoft Sync Framework 2.0, but it looks like that SyncFX 2 does not work on CE, and I’ll have to use 1.0.  I may end up spinning up my own sync processor since the database is dead simple (1, maybe 2 tables).  </p> <p>What’s weird is that a year ago I was struggling as an early adopter to learn all new concepts for Azure, a new technology with little documentation and an unstable base.  Now I’m trying to use technology that’s been around for quite a while, and changes a lot more slowly than Azure and Windows Desktop, yet the process of learning is just as hard because the documentation all dates back to 2006-2007 and my gut says ‘don’t trust it, it’s old’.</p> <p>So over the next few weeks, I’ll be blogging more about CE / Win Mobile.  Hopefully others will find this useful to get started, and maybe, just maybe, someone will read this, and be able to point me in the right direction.</p> <p>Anyone at Microsoft need an early adopter for Windows Mobile 7 + Silverlight on a scanner?  Let me know.  I may consider it if I can’t figure out the other ways sooner than that.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-76281815499683197362010-01-08T17:18:00.001-08:002010-01-08T17:18:37.500-08:00Moral Responsibilities<p>If you work in the software industry long enough, sooner or later you are going to be asked to do something that comes into conflict with your conscience.  Whether it be to ship with defects in the hopes that no key users will find them before you can get it fixed so you can ship on time, or whether it be to include some arcane EULA agreement into the software that no one will ever read, but gives the software or the company to do anything to your PC, or to gather and distribute any personal information the company wants to sell.  Sooner or later, you will review the strength of your convictions.</p> <p>When I started out in the industry fifteen years ago, I was an idealist (aren’t we all when we are young).  I can remember tracking my hours religiously to ensure that I got paid for every minute I worked past 40 (this was in Canada and overtime was required… that was nice).  Now, I track hours so I can bill clients, but I have adapted to the term ‘salaried employee’, and I just do the work.  It took a few years to get the ‘overtime’ idea out of my head, but I’m paid well for what I do and I want the small company I work for to be a success.  I also know that I must spend my own time to improve my skill set.  That  was something I didn’t see as my cost of working, just a few short years ago.  My moral values changed over time.  </p> <p>A few weeks ago, I upgraded all my personal PCs to Windows 7.  One thing I hadn’t done was to install the HP driver software so I could download pictures from my HP C6180 All in One printer.  I could print to it, but I couldn’t see the SIMM card reader to get the photos.  We had a bunch of pictures on the camera I wanted to post for family to see.  I went out to HP’s website and started to download the installer for the drivers.</p> <p>I stopped the download when I saw it was 340 MB.</p> <p>Yes, 340 MB.  For drivers.</p> <p>Now I’m not an expert on driver software, but I recognize bloatware when I see it.  I stopped the download, and attempted to find driver software just to get the ph0tos.  You know, something that will allow me to see the SIMM as a USB device.  HP’s own site (in small letters off to the side), said that if you wanted just the drivers (no network), to search for the Basic package.   I did that.  The only package that came up was one for XP and Windows 2000 Server.  Hmmm.</p> <p>I got impatient.  I didn’t plan to have my whole evening sucked up with just trying to get pictures off the camera,  That’s supposed to be the easy part.  So I decided to download the 340 MB package and install it.  I knew that the previous version of the software had some really annoying apps that I didn’t want, so I figured at some point during the install I would have a chance to opt out of those. I started clicking through the install.  I got to  the page that asked you to accept the EULA.  I clicked to accept (like anyone reads those), and then clicked next.  I then noticed that the install was about to start without giving me an option to opt out of the bloatware.  Hmmm.</p> <p>I went back a screen, and re-read it.  On the screen were a series of links that look like they are part of the text, but are really optional installer screens that let you go an opt out of some of the options.  Okay, my fault, I missed it.  But reading on, I see a part that says failure to install all of the options will probably cause the installer to fail.  What?  Scare tactics or honest truth?  Bad software?  I was about to commend them for their honesty, until I went into the screens, and started to see all the crap (pure bloatware) and all the really dangerous stuff (outright spyware) they were about to try to install.  Holy Mother of God.  I’ve never seen such a blatant attempt to take my personal information.</p> <p>Let me stop here for a second, and go back 29 hours.  The previous day I got a call from my wife that she got a call from our credit card company that they had noticed some unusual activity on our credit cards, and sure enough, someone had stolen our number and was buying stuff at BigLots! and Target in California.  I live on the West Coast, but nowhere near California.  So we cancelled our card, had the charges removed, and everything was taken care of in a couple of hours.  I was a little upset, and briefly talked about the death penalty for credit card theft (a damn fine idea if you ask me), but after a few hours, everything was okay.</p> <p>Fast forward to last night, sitting in front of my PC, looking at all of this crap.  I was spitting mad.  Mad at HP for creating such a mess.  Mad at HP for knowingly taking advantage of the fact that no one ever reads the EULA.  Mad at HP for violating the trust that we are supposed to have for large purveyors of  hardware and software.  They are supposed to be out there fighting against this kind of thing.  Mad at HP for making software developers do this, because I have to believe that no self-respecting developer would ever do this except against their will in an effort to keep their job.  Mad at the industry that slowly whittles away our moral values to the point that this is acceptable behavior.  Mad at the fact that my elderly parents would install this without questioning it, and expose themselves to all kinds of corporate invasion.</p> <p>I went through and eliminated the stuff I didn’t want, and installed what I thought was the barebones driver.  But I missed a checkbox, and it still installed something called HP Web Printer Helper.  The next time I fired up a browser, half the screen was taken up by an HP add on that kept asking for special permissions to send information HP to help improve my experience.  What the fuck!?!  Screw that.  Search though the add on list and disabled it.</p> <p>But then I realized that disabling it wasn’t enough.  My other logins for the rest of the family may still have it installed and active.   So I went back into Control Panel and removed anything from HP that was questionable.  I was still pissed.</p> <p>I popped on to HP’s site, looked through their contact page, and fired off a long note to the HP CEO Mark something or other.  There was a 3500 word limit.  I may have been close.  I doubt if I’ll hear back, and I doubt even more if HP will change their evil ways.  I was ready to call for an all out boycott, but I realized that I liked the HP EX 490 Home Server I recently purchased too much not to recommend that one to other people.</p> <p>Instead, I’ll simply document my experience here, and hope that my tale takes root, and those roots break the concrete of corporate greed and malfeasance. </p> <p>So be forewarned, those of you who blindly approve all EULAs from supposedly trustworthy companies.  They know it, and they’re starting to take advantage of that fact.  Scary. </p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-53830180959688465082010-01-07T10:52:00.001-08:002010-01-07T10:52:17.929-08:00Bug in Entity Framework<p>I found a great little bug in Entity Framework this morning.  One of their exception handlers can throw an exception, that hides the true exception.  Here’s how to recreate this:</p> <ol> <li>Set your thread culture to a neutral culture:  i.e. ‘en’ instead of ‘en-US’</li> <li>Create a new EF Context</li> <li>Find an object (A) that has a dependency to another object (B) via foreign key and B has a dependency to object C via another foreign key.</li> <li>Create a new object of type A called ‘a’</li> <li>Get object B and detach it from the database (as if you were getting it in via a web service call).  B should lose it’s link to C</li> <li>Add object B to A</li> <li>Attempt to add A to the database via the context.AddToA(a)</li> <li>Call context.SaveChanges().</li> </ol> <p>What you should get is </p> <p>System.Data.Entity  Type: System.Data.UpdateException  Message: Entities in '[contextName].B partticipate in the 'FK_B_C' relationship. 0 related 'C' were found. 1 'C' is expected.</p> <p>What you will get is:</p> <p><font face="Times New Roman">System.NotSupportedException: Culture 'en' is a neutral culture. It cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture.     at System.Globalization.CultureInfo.CheckNeutral(CultureInfo culture)     at System.Globalization.CultureInfo.get_NumberFormat()     at System.Globalization.NumberFormatInfo.GetInstance(IFormatProvider formatProvider)     at System.Data.EntityUtil.ConvertCardinalityToString(Nullable`1 cardinality)     at System.Data.EntityUtil.UpdateRelationshipCardinalityConstraintViolation(String relationshipSetName, Int32 minimumCount, Nullable`1 maximumCount, String entitySetName, Int32 actualCount, String otherEndPluralName, IEntityStateEntry stateEntry)     at System.Data.Mapping.Update.Internal.UpdateTranslator.RelationshipConstraintValidator.ValidateConstraints()     at System.Data.Mapping.Update.Internal.UpdateTranslator.ProduceCommands()     at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)     at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)     at System.Data.Objects.ObjectContext.SaveChanges(Boolean acceptChangesDuringSave)     at System.Data.Objects.ObjectContext.SaveChanges()</font>   </p> <p>The only way to get the real error, is to change your current culture from a neutral to a specific culture.  I’ve never seen this one before, and I had a few minutes of head scratching before we got the real cause.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com2tag:blogger.com,1999:blog-7949267671212594224.post-88398332252754846272010-01-01T16:44:00.001-08:002010-01-01T16:49:16.809-08:00Evolution<p>I have evolved.  Well, not me personally, but the technology in my house has definitely undergone an evolution over the past few months.  Or at least a refresh.  It was a long time coming, and there’s still a way left to go, but here’s where I started from, where I am now, and where I think I still need to upgrade.</p> <p>Last year at this time I had the following:</p> <ul> <li>Home Computer:  Dell XPS 410 pretty much a standard ship from the factory (without the TV card) running Vista Ultimate bought in 2005 </li> <li>My Laptop:  Toshiba U405-2854 running Vista Ultimate bought in 2008 </li> <li>My Wife’s Laptop:  Dell Latitude 550  running Windows XP bought in 2004 </li> <li>Phones:  Qwest RAZR with limited texting (2 phones bought in 2005 appx $70/month charges) </li> <li>Internet Connection:  Qwest DSL 1.5 MB Download, .3 MB Upload ($30 / month) </li> <li>TV Connection:  Comcast Basic Cable ($78/month with DVR and 2 cable boxes) </li> <li>Game System:  Standard XBox circa 2004 </li> <li>Backup Strategy:  Used Windows Live Mesh for my writing and personal docs, plus a Maxtor 300 GB US Backup drive with Norton Backup (Never worked right) </li> </ul> <p>A number of factors came together over the past year to cause me to spend a bunch of time and a bunch of money upgrading various technical aspects of my life</p> <p>1. We upgraded from the basic Qwest Phones to Apple IPhone 3GS with unlimited data from AT&T last spring.  I was happy with the phone I had, but Qwest was discontinuing wireless in our area, and we had to choose a new plan.  I left it up to my wife to pick a new plan / phone for us.  I’ve been fairly satisfied with the IPhone on the whole.  I use the phone every day, for far more than I thought I ever would (who needs web / email on their phone, I used to say), but I actually regret having email on my phone.  I have it linked into my work email, and at times I feel obliged to answer emails at odd hours of the night.  There is nothing worse than getting home on a Friday night, ready for a good, relaxing weekend, only to see an emergency email pop into your box at 6:00 PM.  A year ago, that email would have waited there just fine until Monday morning, and no one would have cared.  I may not work two jobs like some people I know, but I have one job that takes up twice the time it used to.</p> <p>I am not happy with ITunes, but that is a whole other story.</p> <p>2.  My wife’s computer, the Dell 550, is a beast, both in weight and in the heat it puts out.  It would literally burn your legs if you left it on your lap for too long.  In November, she finally ordered a new laptop, an HP.  That was the same week I went to Microsoft PDC, and received a new ACER 1420P laptop running Windows 7 courtesy of Microsoft.  We promptly returned the HP unopened, and swapped / upgraded laptops.  She got my Toshiba (just over a year old) and I got the Acer.  If you’ve read my blog, you know what I think of the ACER.  I got the raw end of the deal, and would switch with my wife if it wasn’t such a pain to move ITunes from one machine to another.  Unless I can find a glare reducer for the ACER, I’ll probably replace it before 2010 is done.</p> <p>We upgraded my wife’s Toshiba to Windows 7, and the Dell XPS 410 to Windows 7 as well.</p> <p>3.  With the money we originally had budgeted for the new Laptop, we bought an HP-490 MediaSmart Home Server.  I love this box.  Easy to do the initial setup, looks good, runs quiet.  I added an extra 1.5 TB of disk into it so it could spread the load over multiple disks.</p> <p>4.  I then splurged on a new XBox 360 Elite with the 120 GB hard drive, with the idea that I could use it an a media extender for my home server.  I also got the idea that with a little planning, I could drop the $78/month Comcast bill, and make back the money I spent on the XBox in less than 6 months.  This is where my plan started to run into some trouble, and also where the story gets interesting.</p> <p>First off, I wanted to put my media server and XBox 360 in my Home Entertainment center, hard wire them to my wireless router and DSL line, then run my desktop off a wireless USB receiver.  A few problems cropped up.</p> <p>a)  Running a desktop PC off a USB Wireless G (Linksys WUSB54GC) when you are frequently remote desktopped into you work PC from there is a complete disaster waiting to happen.  Of course the morning after I set this all up, I had to be up at 4:00 AM to talk to someone in India, and my connection kept getting dropped, and I had to go pull the router back out of the entertainment center and put it back into my office just to finish the chat.</p> <p>b) 1.5 MB download over Qwest DSL is not fast enough to watch movies on Netflix or TV shows on Hulu.  I thought initially I’d be able to upgrade to 7 or 12 MB on Qwest, but that level is not available in my neighborhood.  Time to call Comcast.</p> <p>c) In order to watch internet TV on the XBox 360 from the HP Homeserver, you need to install a product like PlayOn Media Server.  The product works pretty well, though the install on WHS is not straightforward.  Follow the special directions as best you can, and do lots of Google searches. The HP 490 does have one critical flaw for those of you who want to run PlayOn to stream Internet TV.  The CPU is a little slow.  In hindsight, upgrading to the 495 with the Dual Core CPU would have been a better deal.</p> <p>I also went out and bought the XBox N Wireless antenna, and had Comcast Upgrade my router to N as well.</p> <p>Once I confirmed that Comcast could give me the service level I needed, I was able to drop my TV cable plan from the $78/month to $13.50 a month by going with their very basic plan, and getting rid of the Comcast DVR.  I bought a Hauppauge 1850 Win-TV-HVR PCI-E card and popped that into the last PCI-E slot on the Dell XPS 410 to act as my TV guide / tuner.  That brought up another issue though with the Dell 410.  Drive space.  The Dell is supposed to have dual 175 GB drives set up in a Raid 1 configuration.  When I upgraded the machine to Windows 7, it appears that I lost the Raid Configuration, and now I have 175GB C: drive, and 48 GB on the D: drive.  If you try to set up the DVR on the D drive on the digital tuner, you can only record about 4 hours of TV.  If you set it up on the analog channel, you can get about 30 Hours of shows (due HD vs std output.).</p> <p>5.  We bought a Harmony 900 universal remote.  This thing is a beast, but it does work with everything we have, though not quite perfectly.  We’ve been talking about getting something like this for a very long time, but using the XBox controller as a remote for the DVR was the final straw.</p> <p>So what was the cost of all this (Roughly, tax excluded)?</p> <p>IPhones:  $199 each + $170 per month  (We’ll keep those out the final numbers, since my wife can’t hold those against me.)</p> <ul> <li>HP 490:  $475 </li> <li>Extra 1.5 TB for Home Server:   $90 </li> <li>XBox 360:  $350 </li> <li>XBox 360 N Connector:  $99 </li> <li>USB G Receiver:  $50 </li> <li>Hauppauge WinTV Card:  $119 </li> <li>PlayOn Media Server:  $40 </li> <li>Windows 7 3 Pack for Toshiba and Home PC - $149 </li> <li>Microsoft Office 2007 Home edition 3 pack - $129 </li> <li>Harmony 900 – $274 ($138 by using a bunch of Christmas Gift certificates)</li> </ul> <p>Total Hardware / Software Cost:  $1501</p> <ul> <li>New: Comcast TV – 13.50 / month </li> <li>New: Comcast Internet:  $20/month for 6 month (25MB down, 8 MB up), $45 / month after 6 months </li> <li>New Total Cost / Month:  $33.50 / 58.50 after 6 months </li> <li>Original Cost / Month:  $30 (Qwest) + 80 (Comcast) = $110. </li> <li>Savings after 6 months:  450 </li> <li>Savings after 12 months: 450 + 300 = $700. </li> </ul> <p>So after 1 year, I will have saved about $700, so it will take me about 2 years to break even.</p> <p>But I also gained a more reliable backup system (worth quite a bit to me).</p> <p>I also turned my WHS into a Web Server and Host my own website there (<a href="http://www.joebeernink.com">www.joebeernink.com</a>), which I was hosting on Windows Azure, but since they are about to start charging outrageous amounts of money, I was going to have to switch to GoDaddy.com ($4 / month).  But this way I can try more things with my web site and set up others as well.  Not a big savings in money there, but honesty, going out to godaddy.com when I’m at work makes me feel like I’m looking at porn on company time.</p> <p>All of this was a learning experience.  I had some grandiose plans about getting rid of Comcast for good if I could get fast enough DSL speeds, and find all the TV content I wanted on-line, but alas, neither the former or the latter is completely possible, yet.</p> <p>For someone about to go through all this themselves, here are a few tips.</p> <ol> <li>Confirm your DSL provider can give you the speed you want before you start. </li> <li>The HP Home Server is great, but get the 495. </li> <li>Don’t try all this with Windows Vista.  Wait till you have Windows 7 </li> <li>Upgrade your wireless to N before you start </li> <li>Really investigate what you think you will do with you gaming system.  The PS3 might be a better choice if you want to watch BluRay.  The XBox doesn’t support it.  The number one reason I bought the XBox was because most of my friends have it and they play on line.  I haven’t yet had time to play on-line, so maybe that wasn’t the wisest decision </li> <li>Don’t buy a USB Wireless card for a desktop PC.  Waste of money. </li> <li>ITunes doesn’t play well with anything.  If you think you will be able to backup your ITunes library to your home server, then play your playlists on your stereo, you will be sadly disappointed.  ITunes playlists are a proprietary format, and not compatible with Windows Media Server.  So don’t promise your wife that this is possible. </li> <li>If you want to stream music from your media server to your stereo, and you have a TV like mine, you may have to leave your TV on all the time while listening to music, and you’ll have to watch those seizure inducing graphics.  My TV doesn’t pass audio through when the TV isn’t on, and I haven’t yet invested in the XBox to component out audio connector. </li> <li>Your life will be more complicated with this setup.  Instead of just checking your queue on Netflix and seeing what’s on TV / your DVR, you’ll have to do the following: <ol> <li>Check your Netflix DVD queue </li> <li>Check your Netflix Instant Play Queue </li> <li>Check your PC to see what is on your DVR </li> <li>Copy the shows you don’t have time to watch now over to you media server so your PC doesn’t run out of space. </li> <li>Look through Hulu for stuff to watch </li> <li>See what you can watch on-line that can be streamed through the XBox.  Not everything can be.  To me, there’s a whole lot of collusion going on out there that is preventing the internet from being THE source of entertainment content, but the FTC is in the hip pocket of big business, and not going to do what is best for consumers, which would be to give everyone a choice of how to get their content.  My hope is that over time, more content will be integrated into PlayOn so that everything I want to watch is in one place. </li> </ol> </li> <li>Be prepared for things to not work right the first time.  In fact, if you are doing this just to save money, forget it.  You won’t at least not right way, unless you already have most of this hardware. </li> </ol> <p>What’s really weird is that since we’ve started setting this up, I’ve barely had time to watch TV, and I haven’t really missed it. </p> <p>So what’s on the table for 2010?</p> <ol> <li>Add more disk to my Dell XPS.  Disk is cheap now, and if I added a couple of TB into it, it would go a long way to allowing my to record everything I want to. </li> <li>Add a second cable splitter into the line coming in to the Dell 410 so I can have both HD and analog feeds, and choose which format to watch / record. </li> <li>Clean up the directory structure on the Home Server to make things easier to find. </li> <li>Develop a Home TV guide for everything we might want to watch (how to get to it, restrictions, etc.) </li> <li>Figure out if I can access my Windows Media Center remotely to allow me to set up recordings while I am away. </li> <li>Test my backup strategy.  It’s a common saying that you don’t have true backups unless they have been tested. </li> <li>Replace the ACER 1420P.  We’ll see how long I can cope with this one. </li> </ol> <p>Give me a few more weeks, and we’ll see if I get this all working just right, or get outsourced as the VP of technology in my own home.</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-62339868148518785372009-12-23T10:03:00.001-08:002009-12-23T10:03:17.771-08:00New Year’s Technical Resolutions – 2010<p>I’m a goal oriented person.  Always have been.  I hear management really likes that in developers, and now that I am more management than developer, I know I like that in my developers.   The key is to make sure that the developer and management have the same goals.</p> <p>To that end,  I’ve spent some time over the past few weeks looking forward to 2010 and planning the technology goals for the company for 2010, so that we can take those goals and make sure that they both mesh with the vision for the company’s growth in 2010, and with the career goals of the developers for 2010 and beyond.</p> <p>Personally, I want to maintain my technical edge over the next few years, to delay the inevitable full time move to management.  It’s not just my backup plan.  As an architect, I need to be able to see around the next corner.  I may not have to delve deep into how exactly JQuery Validators work, but I’d better at least be able to read JQuery and know what it’s capable of doing.</p> <p>To that end, here are my technical goals for 2010:</p> <ol> <li>Visual Studio 2010 / TFS 2010 – I can’t wait for this release.  I believe this will have the single biggest impact of any technology on my day to day work life in 2010.  We have already identified major areas where our processes fall short, and hope that technology can help to address those issues.</li> <li>Entity Framework 4 – After spending the last two days debugging a large project written with EF 1.0, I really hope that this version justifies the immense amount of time we’ve invested into EF and fixes the many aspects of EF that I would currently give a score of' ‘WTF’ to.</li> <li>Azure – 2010 should be a huge year for Azure, with the full production release, and the stabilization of the environment.  As an early adopter, I’ve seen a lot of breaking changes smack me in the face every Thursday morning, and I’m hoping that the pace of these slow (stop would be nice) so I can begin to recommend this platform to my customers as a viable solution for their products.  I will also be doing deep dives into SQL Azure, the Service Bus, AppFabric and WIF as part of extending my Azure expertise</li> <li>SharePoint 2010 – I really liked what I saw at PDC, and we’re champing at the bit to get going.</li> <li>Windows Mobile 7 – I’ve never done mobile device work before, but I have high expectations of WM7.  I’ve actually had some great ideas for IPhone apps that’s I’ve had to discard because I have no access to a Mac to do the development, and the more I work with Apple products (and their inability to work with anything else), the more I despise them.  If WM7 delivers, I can see dropping my IPhone and going to a Windows based phone so I can actually work with it.  I’d have to pry my wife’s IPhone from her hands with a crowbar, but we’ll see what options come out before I even suggest it.</li> <li>RIA – I think this is a year away from being Prod ready, but there’s definitely power there, and something I want to play with in 2010</li> <li>WCF Data Services – Ditto above</li> <li>Learn JQuery - I was supposed to do that this year, didn’t make it.</li> </ol> <p>My technical reading list has been fairly vacant the last few months as I put the finishing touches on my novel “The Forgotten Road” and the sequel “Nowhere Home”.  But with the release of VS2010 coming up in the 2nd quarter of 2010, I expect that the list will fill back up.  Here are some of the titles I’m looking forward to reading:</p> <p><a title="Introducing .NET 4.0- with Visual Studio 2010" href="http://www.amazon.com/gp/product/images/143022455X/sr=8-2/qid=1261590065/ref=dp_image_0?ie=UTF8&n=283155&s=books&qid=1261590065&sr=8-2">Introducing .NET 4.0- with Visual Studio 2010</a></p> <p><a title="Pro C# 2010 and the .NET 4.0 Platform, Fifth Edition" href="http://www.amazon.com/gp/product/images/1430225491/ref=dp_image_z_0?ie=UTF8&n=283155&s=books">Pro C# 2010 and the .NET 4.0 Platform, Fifth Edition</a></p> <p><a title="Pro ASP.NET 4.0 in C# 2010, Fourth Edition" href="http://www.amazon.com/gp/product/images/1430225297/ref=dp_image_z_0?ie=UTF8&n=283155&s=books">Pro ASP.NET 4.0 in C# 2010, Fourth Edition</a></p> <p><a title="Professional Application Lifecycle Management with Visual Studio 2010" href="http://www.amazon.com/gp/product/images/0470484268/sr=8-8/qid=1261590065/ref=dp_image_0?ie=UTF8&n=283155&s=books&qid=1261590065&sr=8-8">Professional Application Lifecycle Management with Visual Studio 2010</a></p> <p><a title="SharePoint 2010 as a Development Platform" href="http://www.amazon.com/gp/product/images/1430227060/sr=8-1/qid=1261590455/ref=dp_image_z_0?ie=UTF8&n=283155&s=books&qid=1261590455&sr=8-1">SharePoint 2010 as a Development Platform</a></p> <p><a title="Pro SharePoint 2010 Solution Development- Combining .NET, SharePoint, and Office" href="http://www.amazon.com/gp/product/images/1430227818/sr=8-3/qid=1261590455/ref=dp_image_z_0?ie=UTF8&n=283155&s=books&qid=1261590455&sr=8-3">Pro SharePoint 2010 Solution Development- Combining .NET, SharePoint, and Office</a></p> <p>I should also be able to blog more often.  Most of the NDA’s I’ve been working under will expire with the production release of Azure, so hopefully I will have topics to write about that are both timely and interesting. </p> <p>Happy Holidays!</p> JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-44302534177359741492009-12-15T11:42:00.000-08:002009-12-15T11:54:15.902-08:00ACER 1420P - Another ReviewAfter using this PC for a few weeks now, I have the following thoughts.<br /><br />1. The screen is so freakin glare prone that it's almost unusable while commuting with overhead flourescent lights on the train. I mean, you eventually get used to it, but it's like a railroad spike being slowly driven through your brain. You can't find a position for the screen where the view is still good, and the lights aren't right in your eyes.<br /><br />2. I really dislike the keyboard. I'm not the greatest typist in the world, and the sharp edges on the keys really catch my fingers and make bad typing worse. Combine that with the really small cursor keys in the right hand lower corner, and navigating a long Word document is pretty painful.<br /><br />3. I still get occasional character repetitions for no apparent reason, despite having turned down the character repeat speed in the configuration significantly, to the point where if you are using the aforementioned cursor keys, you have to wait almost a second for them to repeat, and by then, you've gone past where you wanted to go.<br /><br />4. On the plus side, I love the weight and the battery life. Definitely better than my Toshiba U405.<br /><br />5. I haven't tried to make use of any of the advanced features of the system, partially because I don't want to spend any more time staring at that screen than I absolutely have to.<br /><br />Based on the monitor, and the keyboard, and the fact that I never use the Touch screen, I would never buy this machine for myself or my family, and really miss my Toshiba, though I would probably buy the Toshiba T-135 if given a do-over. Maybe in the new year.JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com0tag:blogger.com,1999:blog-7949267671212594224.post-57570590177778327532009-11-22T16:14:00.000-08:002009-11-22T16:45:13.099-08:00Acer 1420P ReviewFully paid attendees of Microsoft PDC recevied a rather neat little treat: a new Acer 1420P Laptop. I've been playing with it for a couple of days, and while I haven't fully experienced the entire capabilities, I have seen the basics.<br /><br />The battery lasts forever. I've been synching my ITunes from my current Toshiba U405-2854, and I've had the Acer unpluggeed most of the day, but had to put the Toshiba on the grid after an hour and a half of use.<br /><br />This laptop is light. I'd almost say too light. At least the base is too light to support the display once the angle of the display to the verticle exceeds about 15 degrees, at which point the laptop flips over. The hinge on the screen is a little weak as well, and once past 25 degrees to vertical, the display slowly falls to horizontal.<br /><br />The keyboard is really different from my Toshiba. Not necessarily a bad thing, but I write novels, and I'm a bad typist. So every adjustment in key position is a double whammy. The keys are more comfortable for me now than I first thought they would be. They are a lot rougher in feel than the Toshiba, but a lot of people like that. Maybe I will too after a while.<br /><br />I haven't done any performance tests yet, so I can't give stats on that.<br /><br />It took me half a day to figure out how to disable the Tap to Click feature on the touchpad. It turns out that the version of the Synaptics drivers shipped with the unit are not up to date, and that by upgrading to the current version, you can get the option to turn it off. I sent this question to ACER support before I figured it out myself, but they were completely useless didn't read the question, and answered something I didn't ask). I also had a problem with my keys repeating while typing, and spent a few minutes changing the settings on the keyboard so I could type without every letter repeating twice.<br /><br />They've done a nice job keeping the bottom of the laptop cool while working. I'm wearing shorts right now, and while it's a little warm, it's a little better than the Toshiba, and a heck of a lot better than the old Dell my wife has been using.<br /><br />The screen is crisp and clear, so no issues there.<br /><br />I'm definitely going to pop a couple more GB of memory into it so I can run my usual suite of work apps. <br /><br />I think this is a keeper. Would I have bought it for myself? Probably not. I never had ambitions to have a tablet PC. It'll be interesting to see if I use it for what Microsoft intended.JBhttp://www.blogger.com/profile/08085754663631271944noreply@blogger.com5