building a rest api and consuming it in wp8

As a mobile developer we often need to consume some API in order to get data. In a lot of cases that API is made available to us by some third party, for example Twitter, Facebook, Flickr, ...  However, in some cases we are ourselves responsible for the data. In order to get the data from our datastore to our app we’ll need to build an API. In this article I’ll walk you through creating a basic API with the CRUD operations and consume it in a Windows Phone app.

For this post I’ll be using

  • ASP.NET WebApi 2.1
  • Visual Studio 2013
  • Microsoft Azure Websites
  • Windows Phone

The API will be build in WebApi 2.1 and hosted on Azure Websites. I’ve chosen Azure Websites because they offer 10 free websites and have great integration in Visual Studio 2013 update 1. Feel free to choose any other webhost, as long as they support MVC 5 you should be fine.

Setting up the API project

All right, let’s get started by building the API. In Visual Studio 2013 select File > New Project > Web > ASP.NET Web Application. In the next window, select Web API. If you’re deploying to Azure, check the “Create remote resources” box. This will create either an Azure Website or an Azure Virtual Machine for you. We’re not doing any authentication for this post, I’m saving that for a future post Glimlach, so leave it at No Authentication and click OK.

Visual Studio will create your project, tell Azure to create a Website and setup publish profiles for you. If you run this project you’ll get an ASP.NET MVC application with the default template but underneath it has also fired up a WebAPI. If you click the API link in the default template it will show you all available API calls (the WebApi template has a demo controller to get you started).

Now, for our API we’re going to create a database that holds famous quotes. Nothing fancy, just a database with one table that holds quotes. This is the Quote class

Code Snippet
  1. public class Quotes
  2. {
  3.     public int ID { get; set; }
  4.     public string Quote { get; set; }
  5. }

Time to add our API controller. If you’re familiar with MVC then this will look very familiar. WebAPI is basically MVC without the V. You have Models, you have controllers but instead of returning a view, the controllers return a Rest result, by default in JSON.

Right-click the controllers folder > Add > Controller. Select “Web API 2 controller with actions, using Entity Framework”. In the Model class dropdown select the Quotes class we’ve just created. The Data context drop down is where we can select our Entity framework context but that hasn’t been created yet. Click the + button next to the dropdown, select a name and click Add. Now we do have a context. Click Add and let Visual Studio create your Controller for you.

The newly created controller features all CRUD operations using the context we’ve just created to get to our Entity Framework. Before testing this, have a look in the Web.config file. You should find something like this not far from the top of the file

Code Snippet
  1. <connectionStrings>
  2.   <add name="RestDemoContext" connectionString="Data Source=(localdb)\v11.0; Initial Catalog=RestDemoContext-20140327114532; Integrated Security=True; MultipleActiveResultSets=True; AttachDbFilename=|DataDirectory|RestDemoContext-20140327114532.mdf"
  3.     providerName="System.Data.SqlClient" />
  4. </connectionStrings>

This is the database connection that Entity Framework will use. It’s currently set to a local SQL Express database but a SQL Azure database has been created together with our project when we were first setting it up, so we’ll need to change this. Login to the Azure portal and go to Databases, find the created database for your project and select  “View SQL Database connection strings for ADO .Net, ODBC, PHP, and JDBC”.

Copy the ADO.NET connectionstring and paste it into the Web.config so that the line from before now looks like this

Code Snippet
  1. <connectionStrings>
  2.   <add name="RestDemoContext" connectionString="Server=tcp:tvez9dpih8.database.windows.net,1433;Database=RestDemo_db;User ID={Your_userID_here};Password={your_password_here};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;"
  3.     providerName="System.Data.SqlClient" />
  4. </connectionStrings>

Don’t forget to fill in your correct user ID and password. If you’ve set everything up, it’s time to try this out. Launch the project and navigate to the API link from the page header. It should now show you all available actions from your new controller. Click on the POST entry from the Quotes controller. This page shows you how a body from a POST request to this controller should look like. Let’s try it out in Fiddler.

Open Fiddler while your project is still running and go to the Composer tab. Set the method to POST from the dropdown and enter the url to your API endpoint. In my case this was http://localhost:36264/api/quotes. In the request headers field add this line

Content-Type: application/json

This will tell our API that the body contains JSON formatted data. In the request body we can copy/paste the sample data that the API page from the project gave us and fill in some nice quote.

{
  "ID": 1,
  "Quote": "you have failed me for the last time"
}

Click Execute and after a few seconds Fiddler should show a 201 result. HTTP code 201 means “Created” so our post was successful. Change the method to GET, clear the body and click execute again. Fiddler should show a 200. Select that line and the Inspectors Tab to see the result.

 

A closer look

Let’s take a closer look at the API methods.

Code Snippet
  1. // GET: api/Quotes/5
  2. [ResponseType(typeof(Quotes))]
  3. public async Task<IHttpActionResult> GetQuotes(int id)
  4. {
  5.     Quotes quotes = await db.Quotes.FindAsync(id);
  6.     if (quotes == null)
  7.     {
  8.         return NotFound();
  9.     }
  10.  
  11.     return Ok(quotes);
  12. }

The first line is a comment (obviously Glimlach) that shows you how to call this method. The second line is an attribute to specify the expected content type in the response. Skip ahead to lines 8 and 11. These are helper methods found in the ApiController base class. When called they create a response with the correct HTTP code, 404 for not found or 200 for ok in this case, and set the content of the response.

We could add a second attribute to this method called HttpGet. Each of the verbs (GET, PUT, POST, DELETE) have an attribute version. You can use them freely here but the default template is working with a convention. Every method where the name starts with Get will be a GET method by default, the same for PUT, POST and DELETE.

Publish to Azure Websites

Publishing to your Azure website is as easy as right-clicking your web project (NOT the solution) and selecting publish. Let Visual Studio do its thing, your browser will open and your API is live on the internet. We can even debug live on the azure website by opening Server Explorer in Visual Studio > Azure > Websites > right-click your site > Attach Debugger (note that this works best when you deployed a debug build of your site.

      <h2>Creating the app</h2>  <p>Time to consume our fancy API. Create a new blank Windows Phone 8 application and add the following Nuget packages</p>  <ul>   <li><strong> Install-Package Microsoft.Net.Http</strong> </li>    <li><strong> Install-Package Newtonsoft.Json </strong></li>    <li><strong> Install-Package MvvmLight</strong> </li> </ul>  <p>So what are these for? The first one gives us the HttpClient class which is a far superior way to do HTTP requests in Windows Phone than any class included in the SDK. It’s also a portable library so it makes your code very easy to port over to other platforms. Json.net because we’ll receive a JSON response from our API and we need to deserialize it back to an object. And MVVM Light because I just can’t live without it.</p>  <h2>Getting data</h2>  <p>We’ll start by requesting all quotes currently in the database. First, add the Quotes class from the API project to the phone project. Second, add a LongListSelector to the MainPage</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ae5fe5d1-27dc-4d44-8398-e599eacf2374" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">&lt;</span><span style="background:#ffffff;color:#a31515">phone</span><span style="background:#ffffff;color:#0000ff">:</span><span style="background:#ffffff;color:#a31515">LongListSelector</span><span style="background:#ffffff;color:#ff0000"> ItemsSource</span><span style="background:#ffffff;color:#0000ff">=&quot;{</span><span style="background:#ffffff;color:#a31515">Binding</span><span style="background:#ffffff;color:#ff0000"> Quotes}</span><span style="background:#ffffff;color:#0000ff">&quot;&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">&lt;</span><span style="background:#ffffff;color:#a31515">phone</span><span style="background:#ffffff;color:#0000ff">:</span><span style="background:#ffffff;color:#a31515">LongListSelector.ItemTemplate</span><span style="background:#ffffff;color:#0000ff">&gt;</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">&lt;</span><span style="background:#ffffff;color:#a31515">DataTemplate</span><span style="background:#ffffff;color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">&lt;</span><span style="background:#ffffff;color:#a31515">TextBlock</span><span style="background:#ffffff;color:#ff0000"> Style</span><span style="background:#ffffff;color:#0000ff">=&quot;{</span><span style="background:#ffffff;color:#a31515">StaticResource</span><span style="background:#ffffff;color:#ff0000"> PhoneTextNormalStyle}</span><span style="background:#ffffff;color:#0000ff">&quot;</span><span style="background:#ffffff;color:#ff0000"> Text</span><span style="background:#ffffff;color:#0000ff">=&quot;{</span><span style="background:#ffffff;color:#a31515">Binding</span><span style="background:#ffffff;color:#ff0000"> Quote}</span><span style="background:#ffffff;color:#0000ff">&quot; /&gt;</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">&lt;/</span><span style="background:#ffffff;color:#a31515">DataTemplate</span><span style="background:#ffffff;color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">&lt;/</span><span style="background:#ffffff;color:#a31515">phone</span><span style="background:#ffffff;color:#0000ff">:</span><span style="background:#ffffff;color:#a31515">LongListSelector.ItemTemplate</span><span style="background:#ffffff;color:#0000ff">&gt;</span></li> <li><span style="background:#ffffff;color:#0000ff">&lt;/</span><span style="background:#ffffff;color:#a31515">phone</span><span style="background:#ffffff;color:#0000ff">:</span><span style="background:#ffffff;color:#a31515">LongListSelector</span><span style="background:#ffffff;color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>  <p>Next, in the MainViewModel we’ll fetch the data and set it to Quotes (don’t forget to set MainViewModel as datacontext of MainPage).</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a309e73f-057d-4a8b-b774-a43c44d74424" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ObservableCollection</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#2b91af">Quotes</span><span style="background:#ffffff;color:#000000">&gt; _quotes;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ObservableCollection</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#2b91af">Quotes</span><span style="background:#ffffff;color:#000000">&gt; Quotes</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000"> { </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> _quotes; }</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">set</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (_quotes == </span><span style="background:#ffffff;color:#0000ff">value</span><span style="background:#ffffff;color:#000000">) </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">_quotes = </span><span style="background:#ffffff;color:#0000ff">value</span><span style="background:#ffffff;color:#000000">;</span></li> <li>        <span style="background:#ffffff;color:#000000">RaisePropertyChanged(() =&gt; Quotes);</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">}</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> Initializes a new instance of the MainViewModel class.</span></li> <li><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> MainViewModel()</span></li> <li><span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">FetchQuotes();</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">async</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000"> FetchQuotes()</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">HttpClient</span><span style="background:#ffffff;color:#000000"> client = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">HttpClient</span><span style="background:#ffffff;color:#000000">())</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">{</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> result = </span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> client.GetAsync(</span><span style="background:#ffffff;color:#a31515">&quot;http://restdemo.azurewebsites.net/api/quotes&quot;</span><span style="background:#ffffff;color:#000000">);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="background:#ffffff;color:#000000">result.EnsureSuccessStatusCode();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="background:#ffffff;color:#000000">Quotes = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">ObservableCollection</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#2b91af">Quotes</span><span style="background:#ffffff;color:#000000">&gt;(</span><span style="background:#ffffff;color:#2b91af">JsonConvert</span><span style="background:#ffffff;color:#000000">.DeserializeObject&lt;</span><span style="background:#ffffff;color:#2b91af">IEnumerable</span><span style="background:#ffffff;color:#000000">&lt;</span><span style="background:#ffffff;color:#2b91af">Quotes</span><span style="background:#ffffff;color:#000000">&gt;&gt;(</span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> result.Content.ReadAsStringAsync()));</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">}</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>          <p>Quotes is an ObservableCollection of type Quotes. FetchQuotes does all the heavy lifting here and is called upon initialization of the MainViewModel. It creates an instance of HttpClient (in a using statement, because HttpClient implements IDisposable). It calls our API endpoint that returns all quotes from the database. When it’s done fetching data we call EnsureSuccessStatusCode on the result. This method will throw an error if the returned HTTP code is not a success code, for example when we should receive a not found or bad request error. If everything went well we can read the result.Content as a string, this will give us the quotes in a JSON string format. We feed it into JSON.net his deserializer and we’re done!</p>  <p>Now what good is having our own API when all we do is reading from it? Time to post some quotes! Add a second page and a way to navigate to that page. To keep things simple I’ve hooked this AddPage up to MainViewModel as datacontext. So I have 2 pages and 1 viewmodel. In the Viewmodel I create a new property that will hold the new quote.</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3126d0ca-1ae8-4756-892e-c955ac22959f" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Quotes</span><span style="background:#ffffff;color:#000000"> NewQuote</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000"> {</span></li> <li>     <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000"> { </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> _newQuote; }</span></li> <li style="background: #f3f3f3">     <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">set</span></li> <li>     <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">         <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (_newQuote == </span><span style="background:#ffffff;color:#0000ff">value</span><span style="background:#ffffff;color:#000000">) </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">         <span style="background:#ffffff;color:#000000">_newQuote = </span><span style="background:#ffffff;color:#0000ff">value</span><span style="background:#ffffff;color:#000000">;</span></li> <li>         <span style="background:#ffffff;color:#000000">RaisePropertyChanged(() =&gt; NewQuote);</span></li> <li style="background: #f3f3f3">     <span style="background:#ffffff;color:#000000">}</span></li> <li><span style="background:#ffffff;color:#000000"> }</span></li> </ol> </div> </div> </div>  <p>The page contains a textbox that has a two-way binding to this property</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0e0020b6-235f-4587-8a03-f4019e4f7286" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">&lt;</span><span style="background:#ffffff;color:#a31515">StackPanel</span><span style="background:#ffffff;color:#ff0000"> x</span><span style="background:#ffffff;color:#0000ff">:</span><span style="background:#ffffff;color:#ff0000">Name</span><span style="background:#ffffff;color:#0000ff">=&quot;ContentPanel&quot;</span></li> <li style="background: #f3f3f3">           <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#ff0000"> Grid.Row</span><span style="background:#ffffff;color:#0000ff">=&quot;1&quot;</span></li> <li>           <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#ff0000"> Margin</span><span style="background:#ffffff;color:#0000ff">=&quot;12,0,12,0&quot;&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">&lt;</span><span style="background:#ffffff;color:#a31515">TextBlock</span><span style="background:#ffffff;color:#ff0000"> Style</span><span style="background:#ffffff;color:#0000ff">=&quot;{</span><span style="background:#ffffff;color:#a31515">StaticResource</span><span style="background:#ffffff;color:#ff0000"> PhoneTextNormalStyle}</span><span style="background:#ffffff;color:#0000ff">&quot;</span><span style="background:#ffffff;color:#ff0000"> Text</span><span style="background:#ffffff;color:#0000ff">=&quot;Quote&quot; /&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">&lt;</span><span style="background:#ffffff;color:#a31515">TextBox</span><span style="background:#ffffff;color:#ff0000"> Text</span><span style="background:#ffffff;color:#0000ff">=&quot;{</span><span style="background:#ffffff;color:#a31515">Binding</span><span style="background:#ffffff;color:#ff0000"> NewQuote</span><span style="background:#ffffff;color:#0000ff">.Quote,</span><span style="background:#ffffff;color:#ff0000"> Mode</span><span style="background:#ffffff;color:#0000ff">=TwoWay}&quot; /&gt;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">&lt;/</span><span style="background:#ffffff;color:#a31515">StackPanel</span><span style="background:#ffffff;color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>  <p>And to glue things together, there’s a save method in the Viewmodel that will POST this new quote to the API, clear the NewQuote property and refetch all properties, including the one we just saved.</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ba227720-adff-476f-9a34-f8b9ad769f7d" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">async</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000"> SaveQuote()</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">using</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">HttpClient</span><span style="background:#ffffff;color:#000000"> client = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">HttpClient</span><span style="background:#ffffff;color:#000000">())</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">{</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">HttpContent</span><span style="background:#ffffff;color:#000000"> content = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">StringContent</span><span style="background:#ffffff;color:#000000">(</span><span style="background:#ffffff;color:#2b91af">JsonConvert</span><span style="background:#ffffff;color:#000000">.SerializeObject(NewQuote));</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">content.Headers.ContentType = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">MediaTypeHeaderValue</span><span style="background:#ffffff;color:#000000">(</span><span style="background:#ffffff;color:#a31515">&quot;application/json&quot;</span><span style="background:#ffffff;color:#000000">);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> result = </span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> client.PostAsync(</span><span style="background:#ffffff;color:#a31515">&quot;http://restdemo.azurewebsites.net/api/quotes&quot;</span><span style="background:#ffffff;color:#000000">, content);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">result.EnsureSuccessStatusCode();</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000">NewQuote = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Quotes</span><span style="background:#ffffff;color:#000000">();</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> FetchQuotes();</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p>To do a POST we first need to prepare the content. In our case we’re going to send a JSON string so we need to convert our NewQuote into JSON and put it inside StringContent. Next step is setting the ContentType in the header, just like we did when using Fiddler a few steps ago. Call PostAsync on the HttpClient, ensure its success and we’re done. If all went well the api saved the quote, the app refetched all quotes and the new one should show up on the MainPage.</p>  <h2>Conclusion</h2>  <p>In this article I’ve shown the steps needed to build and consume a basic REST API using ASP.net WebApi and Windows Phone 8. The code from the WP8 app is very generic and can be used on a lot of platforms, even for platforms where HttpClient isn’t available, the way of working, the headers, the expected HTTP codes, should all be the same.</p>  <p>The code for both the API and the app can be found on my <a href="http://1drv.ms/O3MvNt" target="_blank">OneDrive.</a></p>

This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.

Leave a Comment