Writing data to the cloud (SQL Data Services)
In a previous post I talked about setting up the environment for SQL Data Services. Now I’ll show you something I’ve done with it and hopefully it will help somebody thru.
I’ll use my Goomez project cause that’s like my sand box and also, and since it’s available online, you could download it and also play with it. I used the SQL Data Service to store and query the information, so instead of using Lucene.net I used SDS for this implementation, which I believe it’s a good scenario for SDS. That said, the changes you’ll see here were not committed to the svn repository.
But let’s get down to business. SDS has two interfaces, one is through web services, which implies importing the wsdl like any other web service which, if you do it with Visual Studio, it will create all the necessary proxy classes. The other way is REST and since I hadn’t tried anything with it before I thought it’d be a good idea to give that a try too (I must say it’s not a recommended practice, since if you crewed up, it’d be harder to know where).
One thing that I found missing is a good old REST API for .net. I don’t know if this is planed to stay like this, but it’s pretty crapy. You have to create a HttpWebRequest, HttpWebResponse and so forth… not something I enjoy doing. It was fun though (just for this time).
So, here’s the code of the function that actually saves the info of one of the indexed files (FileInfo) to the cloud.
Firts of all, create the request and response objects and set a few properties to the request
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(m_url);
HttpWebResponse response = null;
MemoryStream stm = null;
request.Credentials = new NetworkCredential("<YourSolution>", "<Password>");
request.Method = "POST";
request.ContentType = "application/x-ssds+xml";
In my example, m_url has the value https://goomez.data.database.windows.net/v1/goomezindex because goomez is the authority I created and goomezindex is the container. So now, the entities.
StringBuilder builder = new StringBuilder("<File xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:x=\"http://www.w3.org/2001/XMLSchema\" xmlns:s=\"http://schemas.microsoft.com/sitka/2008/03/\">");
builder.AppendFormat("<s:Id>{0}</s:Id>", Guid.NewGuid());
builder.AppendFormat("<file xsi:type=\"x:string\">{0}</file>", file.Name);
builder.AppendFormat("<folder xsi:type=\"x:string\">{0}</folder>", file.Directory.FullName);
builder.AppendFormat("<extension xsi:type=\"x:string\">{0}</extension>", file.Extension.Replace(".", string.Empty));
builder.AppendFormat("<size xsi:type=\"x:decimal\">{0}</size>", file.Length.ToString());
builder.AppendFormat("<content xsi:type=\"x:string\">{0}</content>", GoomezSearchHelper.Tokenizer.TokenizeToIndex(file.FullName));
builder.Append("</File>");
Here I’m writing the xml which represents an entity, in my case, called File. The file variable you see here is the FileInfo I passed as a parameter to this function.
Now the ‘magic’:
XElement entity = XElement.Parse(builder.ToString(), LoadOptions.SetLineInfo);
stm = new MemoryStream();
entity.Save(stm);
request.ContentLength = stm.Length;
using (Stream stream2 = request.GetRequestStream())
{
stream2.Write(stm.GetBuffer(), 0, (int)stm.Length);
}
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.Created)
{
throw new WebException(string.Format(CultureInfo.InvariantCulture, "Unexpected status code returned: {0}", new object[] { response.StatusCode }));
}
Create the entity element, save it at a MemoryStream and get the response.
So, what was that? what did that do? if you go to the SDS Explorer and query the index you’ll see the file you just ‘uploaded’.