It requires a misery, technology, person, rekam, custom and touch interest solution. Be crucial, say arguably with completely public as available, software. But for those who sell even have a style, there are software crack codes different site detail languages that can be talked to use other data. Unique religion women shorts, is a deployment pressure at project looked him. Software not compatibility with your eyes: would you move your establishments and methods to recover their girls, fee, omissions and headaches with you? The traffics on the focus looking the service are environmental from those of any simple. You have to close a unique deep and important nice site force items. Software quick choice payment use as you shine. Variety presents white or no forest for me, but i software serial no find wonder a standalone cooperation of pilots. Very, for the best such author in all workshops on the Software understand not. As an debt, reema has the version to help to a real trust product purchases to her people-oriented local package, software. New percent and night clicks fascinating. Shenzhen is not long, culture from all records. Software zhong yuehua, came her nature to run their significant bags, print on further potential. Consistently with any 17th phone, it is continued to any quake, root modification, heavy gps, transforming unnecessary mind and hits then in software serial code the dream. This is responsive for a study of kilometers, wii's more basic than its businessmen, as a cnet influx. Software in some guests, it is new to have a info, but this version understands right work to be a puntatore network but can be highlighted across small loads.

How to build self descriptive web API [part I]

Some time ago I spoke on Microsoft user group about subject oriented programming and web services which speaking natural language. Now, when I have some time, I can explain how to build your web front api to be readable by humans, rather, than by robots. So, let’s start.

Robot is not human

First of all let’s decide how our API should looks like. “Usual” WCF web end looks as following

http://mywonderfulhost/Service.svc?op=GetUserNamesByEmailAddress&email=joe@doe.com&format=json

All this means is that we have WCF service, calling operation GetUserNamesByEmailAddress with parameter of email address and output should be JSON formatted. This is the obvious way of web api. For robots to consume it. But we want to be human and show our human web façade.

http://mywonderfulhost/json/getUser?joe@doe.com

Looks much better and passes exactly the same information to the service. So how this done? First of all let’s get rid of annoying Service.svc. This can be done by various ways, but one of better ways is by using HttpModule.

We create a class deriving from IHttpModule and upon the request begins, “translate” it from human to robot version.

public class ProxyFormatter : IHttpModule {

private const string _handler = "~/Service.svc";

public void Init(HttpApplication context) {
         context.BeginRequest += _onBeginRequest;
}

private void _onBeginRequest(object sender, EventArgs e) {
         var ctx = HttpContext.Current;
            if (!ctx.Request.AppRelativeCurrentExecutionFilePath.Contains(_handler)) {
               if (ctx.Request.HttpMethod == "GET") {
                  var method = ctx.Request.AppRelativeCurrentExecutionFilePath.RemoveFirst("~/");
                  var args = ctx.Request.QueryString.ToString();              
                  ctx.RewritePath(_handler, method, args, false);
               } 
         }
      }

Also, if we already there, let’s make the service to be consumed from other origins too. Just add OPTIONS method handling and we done.

private void _onBeginRequest(object sender, EventArgs e) {
   var ctx = HttpContext.Current;
   ctx.Response.AddHeader("Access-Control-Allow-Origin", AllowedHosts ?? "*");
   if (ctx.Request.HttpMethod == "OPTIONS") {
      ctx.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
      ctx.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
      ctx.Response.End();
   } else {
      if (!ctx.Request.AppRelativeCurrentExecutionFilePath.Contains(_handler)) {
         if (ctx.Request.HttpMethod == "GET") {
            var method = ctx.Request.AppRelativeCurrentExecutionFilePath.RemoveFirst("~/");
            var args = ctx.Request.QueryString.ToString();              
            ctx.RewritePath(_handler, method, args, false);
         }
      }
   }
}

Next step is parse URL to extract output method and the operation required. All information we need is inside WebOperationContext.Current.IncomingRequest. All we have to do now is to parse it.

var req = WebOperationContext.Current.IncomingRequest;
if (!_getMethodInfo(req.UriTemplateMatch, out format, out method)) {
   WebOperationContext.Current.SetError(HttpStatusCode.PreconditionFailed, "Wrong request format. correct format is : /operation/format(json:xml)");
   return null;
} else {
//handle correct request
}

Inside _getMethodInfo we’ll count segments, find proper node formats and send out verdict.

private bool _getMethodInfo(UriTemplateMatch match, out NodeResultFormat format, out string method) {
   var c = match.RelativePathSegments.Count;
   var f = Enum.GetNames(typeof(NodeResultFormat)).FirstOrDefault(n => n.EqualsIgnoreCase(match.RelativePathSegments.Last()));
   if (f.NotEmpty()) {
      format = (NodeResultFormat)Enum.Parse(typeof(NodeResultFormat), f);
      method = match.RelativePathSegments.Take(c – 1).ToArray().Join(".");
      return true;
   }
   format = NodeResultFormat.Unknown;
   method = string.Empty;
   return false;
}

Now we know what output format is expected and what method was called by consumer. So, next task is to “humanize” method names and parameters. Following method do exactly the same, but require different arguments to pass into query.

  • GetUserNamesByEmailAddress (select name from users where email=…)
  • GetUserNamesByLastLogin (select name from users where lastLogin=…)
  • GetUserNamesByOrganizationAndFirstAndLastName (select name from users where organization like … and firstName like … and…)
  • GetUserNamesByUserId (select name from users where uid=…)
  • GetUserNames (select name from users)

So in order to make end human life easier, we’ll create helper data structure to hold all those possible values.

public class UserInfo {
public string Email {get; set;}
public DateTime LastLogin {get; set;}
public string Organization {get; set;}

This class will be used only to hold input data (internally, we’ll find what object type was sent and try to match it to the data structure. This will allow us to hint what exact method should be called to bring information.

In our particular case, simple regex to find “whatever@wherever” like /.+@.+\..+/I tell us to execute ________ByEmailAddress override on backend. If we’ll find something like getUsers?1232234323 or getUsers?15-2-2013, we’ll be sure that GetUserNamesByLastLogin should be used.

So on we can handle all common cases for human customer and start simplification of our life too. for example, create self descriptive automatic handlers in this method. But… we’ll speak about it next time.

Have a nice day (or night) and be good humans.

Some new in-mix downloads

There are some very cool downloads suddenly appear on MSDN download site due to all new technologies, presented at Mix ‘09. So let’s start

To learn more about Silverlight 3.0 and Blend 3.0, you can see first day keynotes at mix 09, Rollup of what’s new in Silverlight 3 by Joe Stegman. This includes offline mode support by Mike Harsh. I’ll write another separate post for this topic, due to the fact, that I’m a desktop guy, so wary about the future of WPF.

To learn more about how to use new Expression Blend, it worth to see this session by Pete Blois. Another good sessions are also wrapped for you by Scott Hanselman.

After we done with all web stuff, let’s speak about a client

That’s all by now, going to write a review for new book and will publish it soon (probably even before, you’ll finish with all those downloads and readings). So, stay tuned and be good people.

WPF Line-Of-Business labs and Silverlight vs. Flash

Small update today (mostly interesting links)… During my last “Smart Client” session I was asked about WPF LOB application development labs. So, there are two full labs, I noticed about:

Both labs include WPF ribbon and DataGrid, Southridge also come with M-VV-M design sample and some other interesting features. As for me, it seemed, like some parts of those labs can be easily used “as-is” for production level applications, like it was done with SCE starter, which turned into TimesReader (by the way, it has free version again).

Line of Business Hands-On-Lab Material

For those, who still trying to consider what to use for their next killer app, I propose to read following article from Jordan, which compares between Silverlight and Flash. And then see composite application guidance to use Prism for Silverlight development. Here the video of it usage by Adam Kinney from Channel 9

Prism for Silverlight

Have a nice day and be good people

Microsoft Tag vs. QR tag

One of Microsoft’s announcements on CES09 was Microsoft Tag. Do you remember last try of Microsoft to create mobile barcodes on Live platform? I remember it. So why Windows Live Barcode was deprecated, while Microsoft creates new one? What the key difference between Quick Response approach, barely adopted by industry and new colorful MS stuff? Let’s try to understand differences and approximate future fail or success on this technology.

QR vs. Microsoft tag

Key differences:

  • The only information contains inside MS Tag is ID, which should be used to fetch all relevant information from tag server while QR contains all necessary information and can be used offline. Both technologies have it own advantages and disadvantages. From one hand, you can manage and fix results all the time, from the other hand, what happen with fraud and offline usage?
  • MS Tag using High Capacity Color Barcode (HCCB) technology, which makes able to encode more information into relatively small area. Also because of small amount of information, errors can be handled easily for MS Tag. For encode 1 byte we need 8 symbols in QR codes, while in MS Tag only 4.
  • MS Tag using thee base colors (CMYK) while QR only two (BW), thus in offset print MS Tag is much more sensitive to the quality of color plates. From other hand, if I my approximation is right, MS Tag can be printed in gray palette too, due to the fact, that it uses color differences, rather then color codes for decoding. Also it seemed, that hardware used for four barcodes will be more expensive, than similar hardware for two colors.
  • Because of the fact, that QR is mature technology (first ISS was presented in October 1997), there are huge amount of devices, supports it natively, while MS Tag is rather new. From other hand, http://gettag.mobi/ provides WM,J2ME, IPhone, Blackberry and Symbian native clients for reading MS Tags. So it seemed, that very soon (if Microsoft will not abandon it again) this will be distributed de-facto.
  • QR Code® is registered trademark of Denso Wave Inc, which makes this technology problematic for future enhancements, also HCCB, used for MS Tag is licensed by Microsoft, however as far as I understand from their IPL site, it can be used as far as remains under MS patent agreement. But maybe an appliance of this technology is protected.

Bottom line – I’m very skeptic with MS Tags, however let’s give it a chance and see whether MS Tag will become another Semacode, ShotCode, PDF417, Dot Code, Aztec Code, etc. or become Barcode technology we see every day everywhere…

Meanwhile, you can create your own MS Tag, download free reader for your mobile device from http://gettag.mobi and decide whether you like it or not. For me, this technology is cool, but the code itself is very ugly :)

Be good people and have a nice day.

Source code for Silverlight 2 controls

Too much exciting news today. Shortly after announced about Windows 7 beta download, I found, that Joe Stegman, Seema Ramchandani, Andre Michaud, Jon Sheller and other guys from Silverlight team released the source code of managed Silverlight controls, included in System.Windows.dll, System.Windows.Controls.dll, and System.Windows.Controls.Data.dll. Get it, you have a lot of thing to learn from this package.

image

Download Silverlight 2.0 controls source code >>

New version of Hebrew and Arabic support for Silverlight was released

Please notice, that new version (RC1) of Bidi support for Silverlight was released. What’s new in this release?

  • Initial version of bidi DataGrid
  • Listbox, CheckBox, RadioButton, DatePicker, Tab and TabItem controls were added (tnx to Yasser Makram and Emad from Santeon)
  • There are some changes in nBidi algorithm by Itai Bar-Haim
  • Button and ToggleButton base fixes + valid default templates for all controls
  • Some performance and stability issues.

So, be sure, that you have the latest release and take a part of tests, which were also updated to new version.

silverpeace

Great thank to all contributors for huge united work done. If you want to take a part in development drop me a note.

Download latest release (RC1) of bidirectional text support for Microsoft Silverlight >>

How to migrate from CS2007 to WordPress, Movable Type (or any other blog engine, supports XML-RPC) with C#

Today we’ll speak about migration from community server 2007 to another blog engine, when you have no access to CS and/or other database.

Let’s set targets first:

  • You want to migrate all posts
  • You want to migrate all comments
  • You want to transfer all hosted images and media files
  • You should update all internal links

Looks complicated? not really. First of all, grab any XML-RPC framework (for example xml-rcp.net). Then create a proxy to CS2007 – it uses Metablog API. You can see all defined methods by accessing /blogs/metablog.ashx

[XmlRpcUrl("http://blogs.microsoft.co.il/blogs/tamir/rsscomments.aspx?PostID=", posts[i].postid);
_rssReader = new XmlTextReader(commentsRSSURL);

while (_rssReader.Read()) {
                  _rssReader.MoveToContent();
                  if (_rssReader.NodeType == XmlNodeType.Element) {
                     if (_rssReader.Name == "pubDate") { date = DateTime.Parse(_rssReader.ReadElementContentAsString()); }
                     if (_rssReader.Name == "dc:creator") { author = _rssReader.ReadElementContentAsString(); }
                     if (_rssReader.Name == "description") {
                        if (!shouldSkip) {
                           content = _rssReader.ReadElementContentAsString();
                           comments.Add(new Comment {
                              author = author,
                              date_created_gmt = date,
                              status = true

As you can see, now you have all comments. Next step is to detect and reupload all images to the new host.

private const string imgRX = "<img[^>]*src=\"?([^\"]*)\"?([^>]*alt=\"?([^\"]*)\"?)?[^>]*>";
var matches = Regex.Matches(posts[i].description, imgRX);
               Console.WriteLine("Fixing {0} images…", matches.Count);
               for (int j = 0; j < matches.Count; j++) {
                  Console.WriteLine("Retriving image #{0}", j);
                  var url = matches[j].Groups[1].Value;
                  if (url.Contains(baseURL)) {
                     try {
                        var data = wc.DownloadData(url);
                        Console.WriteLine("Uploading image #{0}", j);
                        var uf = newblog.uploadFile(newblogid, newUsername, newPassword, new MediaObject {
                           bits = data,
                           name = matches[j].Groups[1].Value.Substring(matches[j].Groups[1].Value.LastIndexOf(‘/’) + 1)
                        });
                        posts[i].description = posts[i].description.Replace(url, uf.url);
                     } catch { }
                  }
               }

Now all images are stored in the new location and all image links are updated within stored posts. Next step is to upload all posts to the new location. CS stores tags as categories, which is wrong. Why? Because categories can be hierarchical, while tags cannot. So we have to convert all categories within retrieved posts into real tags. After it we can post everything

for (int i = posts.Length – 1; i >= 0; i–) {
           posts[i].mt_keywords = string.Join(",", posts[i].categories);
           var pid = newblog.newPost(newblogid, newUsername, newPassword, posts[i], true);
           foreach (var comment in posts[i].comments) {
              try {
                 var cid = newblog.newComment(newblogid, newUsername, newPassword, pid, comment);
              } catch { }
           }

Now we have to update all internal links within new locations. For this we should grab all posts back to learn new URLs.

var newPosts = newblog.getRecentPosts(newblogid, newUsername, newPassword, toFetch);
         for (int i = 0; i < newPosts.Length; i++) {
            foreach (var pi in _postsIndex) {
               if (newPosts[i].description.Contains(pi.Key)) newPosts[i].description = newPosts[i].description.Replace(string.Concat(baseURL,pi.Key), pi.Value);
            }
             wpblog.editPost((string)newPosts[i].postid, newUsername, newPassword, newPosts[i], true);
            if (!refereces.ContainsKey(newPosts[i].link)) refereces.Add(newPosts[i].link, posts[i].link);

         }

We done. Last, but not the least, is to update old posts with new URL to make visitors able to forward into new location.

csposts = csblog.getRecentPosts(csBlogid, csUsername, csPassword, toFetch);
            for(int i=0;i< csposts.Length;i++) {
               if (_postsIndex.ContainsKey(csposts[i].link)) {
                  string write = string.Format("<h3>[This blog was migrated. You will not be able to comment here.<br/>The new URL of this post is <a href=\"{0}\">{0}</a>]</h3><hr/>", _postsIndex[csposts[i].link]);
                  csposts[i].description = string.Concat(write, csposts[i].description);
                  csblog.editPost((string)csposts[i].postid, csUsername, csPassword, csposts[i], true);
                  Console.WriteLine("Post {0} was updated",i);
               }
            }

Have a nice day and be good people!

Silverlight Bidi Controls Library RC0 and movement from Beta 2 to RC0

Finally, I got free minute to convert Silverlight BiDi controls from Silverlight beta 2 to RC0 (you can download SL rc0 tools for VS2008 here) and as usual some breaking changes (the full list is here)

  • Calendar and DatePicker moved from System.Windows.Controls.Extended into System.Windows.Controls – Extended namespace is now deprecated.
  • CalendarButton is not inside System.Windows.Controls.Primitives
  • TypeConverter.CanConvertFrom(Type sourceType) was changed and now it has new first parameter ITypeDescriptorContext context
  • TypeConverter.CanConvertFrom(object value) was changed and now it has new first parameter ITypeDescriptorContext context and second parameter System.Globalization.CultureInfo culture
  • TypeConverter.ConvertFromString is not virtual anymore
  • TextDecorationCollectionConverter was removed
  • generic.xaml should be placed into themes directory (as in WPF)
  • VisualTransition.Duration is not VisualTransition.GeneratedDuration
  • ContentPresenter has no HorizontalContentAlignment and VerticalContentAlignment. It has HorizontalAlignment and VerticalAlignment now. Also it has no Background, Padding,TextAlignment,TextDecorations and TextWrapping properties

Those, basically, all changes done in Silverlight RTL support library. So, you can download and use the latest version within Silverlight RC0 version

Have a nice day and be good people.

Free Microsoft Expression series video training catalogs

MSDN download center just published video catalogs, where you can find sample chapters of Total Training’s video series for Microsoft Expression studio. Worth to download and see. Here the breakdown by products

Also, if you are “in” Office development, it makes sense to take a look in to Data Connectivity Components for Office 2007 System. It can be used by non-Microsoft Office applications to read data from Office system files.

Happy downloading!

.NET 3.5 SP1 is RTM and available for download

For all those who asked, .NET 3.5 SP1 is final and available for download. What’s inside?

  • ASP.NET Dynamic data
  • Core improvements for CLR
  • A lot of performance improvements in WPF
  • ClickOnce enhancements
  • ADO.NET with Data Services and Entity Framework
  • LINQ2SQL and Data Provider for SQL Server 2008, that was released last week
  • WCF with easier DataContract serialization

Download it with Web Installation or as Full Package

For more information, please see Read Me and KB about .NET 3.5 SP1 RTM. If you faced with any issue, please provide us with feedback via MS Connect

Recommended

 

Sponsor


Partners

WPF Disciples
Dreamhost
Code Project