Windows Azure Blog Source Code from PDC
You can now download the source code as it stood at the end of my PDC talk.
There’s a README.txt in the source zip that explains what you need to do to get things running. Basically you need to provide StorageClient.dll (it’s not included, but you can build it from the SDK sample), and you need to manually run devtablegen to set up the local storage.
What does it do?
To catch everyone up who didn’t watch my talk, this demo is a Windows Azure application that has basic create/view functionality for blog posts (stored in table storage) and images (stored in blob storage). In addition, when you create a post that references an external image via an <img/> tag, a worker role fetches the remote image, copies into blob storage, and fixes up the references in the blog post to point to the copy. The idea is to avoid having blog posts with broken image tags when someone decides to remove the original (remote) image.
An SDK bug
Why do you have to run devtablegen manually? It’s actually a bug on our part. I reference the same data models from both the web role and the worker role. If you choose the “Create Test Storage Tables” option in Visual Studio, it will end up passing the DLL twice into devtablegen, which then dies with an ugly error. We’ll fix the bug, and in the mean time the workaround is to run devtablegen from the commandline.
My own bugs
Image replacement didn’t work when I tried it live at PDC, and unfortunately I deleted the data before getting back to this to investigate, so I’m not 100% sure what went wrong. One issue I’ve identified is that I don’t handle chunked transfer encoding. To fetch the image and put it in blob storage, I’m using the following code:
var response = WebRequest.Create(url).GetResponse(); var props = new BlobProperties(Guid.NewGuid().ToString()) { ContentType = response.ContentType }; container.CreateBlob(props, new BlobContents(Utilities.CopyStream(response.GetResponseStream(), (int)response.ContentLength)), false);
This code, it turns out, is a bit naïve. I need a smarter CopyStream utility that can handle not knowing the content length up front.
A second bug is that I’m not escaping a string I’m using in a regular expression. I use this code to replace existing <img/> tags with new ones referencing the copied image:
return Regex.Replace(html, string.Format("(<img[^>]*src\\s*=\\s*[\"']){0}", origUrl), string.Format("$1{0}", newUrl), RegexOptions.IgnoreCase);
Notice that I’m not escaping the string, so special characters (like question marks, which appear in a lot of URLs) will end up doing some strange things. Fortunately, there’s a Regex.Escape() method which should fix this problem quickly and easily. (But I left the broken version in here, since I wanted to show the code exactly as it was in my talk.)
It’s quite likely there are other bugs… drop me a note if you find something else.
Those links again
Comments
Thanks!
http://blog.smarx.com/atompub.svc/blog/posts/
and
http://blog.smarx.com/atompub.svc/blog/posts/?fmt=rss
Let me know if your browser doesn't automatically sniff those from the home page. (I should probably add a big orange button anyway.)
The WCF Syndication API made this really easy to do. I'm using AtomPub to enable blogging from Windows Live Writer, and the theory is that I'll clean up that code and make all that available too. But you know how the theory of "I'll clean up the code later" goes...
I have downloaded your source (btw thank you for sharing it)and have built the application. I am running Windows Server 2008 and I believe that I have all of the prerequisites setup correctly - obviously I am missing at least one because the app compiles but fails to run with this error -
Exception Details: System.Data.Services.Client.DataServiceClientException: System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:10002
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetRequestStream()
at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.BeginNextChange(Boolean replaceOnUpdate)
Source File: BlobStorage.cs Line: 205
Did you follow the step of running devtablegen manually? (See the README file.)
When you F5 from Visual Studio, you should see a dialog pop up showing the development storage services (blob, table, queue) all starting up.
When you see the error, go find the development storage service in the system tray, open up the UI, and take a look. If table storage isn't running, try starting it manually.
I had the same problem with the sample as David despite following the README.
Following your answer table storage was indeed not running - starting it has removed the problem. Subsequently running of the project does not recreate the problem it seems.
phentermine the same as amphetamine
plavix mouseo
how is ambien cr different from ambien
promethazine and pregnancy
antidepressant nearest to amphetamine act on brain uk
anadrol star cycle
actos sexuales
soma diego ca
soma heather
lottery on line
presentacion power point de actos juridicos
mix vicodin and ibuprofen
tramadol 2 dollars 30 cent
femulen and amoxicillin
flexerill
oxycontin conversion chart for methadone
pseudoephedrine as a diet pill
norco strike
what is the lethal amount of codeine
zofirax
can you inject xanax
also, I was unsure about:
Exception Details: System.Data.Services.Client.DataServiceClientException: System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:10002
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetRequestStream()
at System.Data.Services.Client.DataServiceContext.SaveAsyncResult.BeginNextChange(Boolean replaceOnUpdate)
did that get resolved?
Steve Marx works for Microsoft on Windows Azure.
A blog post is coming soon that describes how I added comments. It was quite simple.