Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Consume Web Api in xamarin CrossPlatform Application

I have created web api that retrieves data from SQL database. I need to consume web api in xamrin for android and xamarin for iOS. as of now xamarin for android. I am not sure how to call GET and Post method based on button click event.

Here is web api

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace MvcAppDept.Controllers
{
public class DeptController : ApiController
{
    // GET api/values
    public IEnumerable<Dept> Get()
    {
        AndroidAppDBEntities db = new AndroidAppDBEntities();
        var data = from dept in db.Depts orderby dept.no select dept;
        return data.ToList();
    }

    // GET api/values/5
    public Dept Get(int id)
    {
        AndroidAppDBEntities db = new AndroidAppDBEntities();
        var data = from dept in db.Depts where dept.no == id select dept;
        return data.SingleOrDefault();
    }

    // POST api/values
    public void Post(Dept obj)
    {
        AndroidAppDBEntities db = new AndroidAppDBEntities();
        db.Depts.Add(obj);
        db.SaveChanges();
    }

    // PUT api/values/5
    public void Put(int id,Dept obj)
    {
        AndroidAppDBEntities db = new AndroidAppDBEntities();
        var data = from dept in db.Depts where dept.no == id select dept;
        Dept old = data.SingleOrDefault();
        old.no = obj.no;
        old.name = obj.name;
        db.SaveChanges();
    }

    // DELETE api/values/5
    public void Delete(int id)
    {
        AndroidAppDBEntities db = new AndroidAppDBEntities();
        var data = from dept in db.Depts where dept.no == id select dept;
        Dept obj = data.SingleOrDefault();
        db.Depts.Remove(obj);
        db.SaveChanges();

    }
 }
}


Global.asax.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

 namespace MvcAppDept
{


public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();


    }
   }

}

MainActivity.cs

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
namespace DeptAndroidApp
{
    [Activity(Label = "DeptAndroidApp", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {


        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);
            Button GetButton = FindViewById<Button>(Resource.Id.GetButton);
            var txtValue1 = FindViewById<EditText>(Resource.Id.txtValue1);
            int id = Convert.ToInt32(txtValue1.Text);
            var No = FindViewById<TextView>(Resource.Id.No);
            var Name = FindViewById<TextView>(Resource.Id.Name);
            //GetButton.Click += GetDept(id); 
            GetButton.Click+=async(sender,args)=>{
           //error  Cannot await 'DeptAndroidApp.dept                  
           Dept dept=await GetDept(id);
                No.Text=dept.No;
                Name.Text=dept.name}
        }
        //Error The return type ofasync method must be void,task orTask<T>
        public async Dept GetDept(int id)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://****.***/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new               System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
                var result= await client.GetAsync(string.Format("/api/dept/{0}",id));
               return JsonConvert.DeserializeObject<Dept>(await result.Content.ReadAsStringAsync());                }       
        }

    }
}
like image 992
user2897967 Avatar asked Sep 10 '14 13:09

user2897967


1 Answers

Here is how I would use this service from just about any project (including Xamarin projects).

First, get rid of the line in your Global.asax file that says this:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

Generally speaking this is bad practice. You want to have at least the XML and JSON formatters available because in a restful environment it is up to the consumers to determine what type of serialization they need/want.

Next, I would use the System.Net.Http.HttpClient class to interact with this service.

Interacting with the Web Api service from this point is fairly straightforward. Here are some examples.

public async List<Dept> GetDepts()
{
     using(var client = new HttpClient())
     {
          client.BaseAddress = new Uri("http://<ipAddress:port>/");
          client.DefaultRequestHeaders.Accept.Clear();
          client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

          return await client.GetAsync("/api/dept");
     }
}

public async Task<Dept> GetDept(int id)
{
     using(var client = new HttpClient())
     {
          client.BaseAddress = new Uri("http://<ipAddress:port>/");
          client.DefaultRequestHeaders.Accept.Clear();
          client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

          var result = await client.GetAsync(string.format("/api/dept/{0}", id));

          return JsonConvert.DeserializeObject<Dept>(await result.Content.ReadAsStringAsync());
     }
}

public async Task AddDept(Dept dept)
{
     using(var client = new HttpClient())
     {
          client.BaseAddress = new Uri("http://<ipAddress:port>/");

          await client.PostAsJsonAsync("/api/dept", dept);
     }
}

public async Task UpdateDept(Dept dept)
{
     using(var client = new HttpClient())
     {
          client.BaseAddress = new Uri("http://<ipAddress:port>/");

          await client.PutAsJsonAsync(string.format("/api/dept/{0}", dept.no), dept);
     }
}

public async Task DeleteDept(int id)
{
     using(var client = new HttpClient())
     {
          client.BaseAddress = new Uri("http://<ipAddress:port>/");

          client.DeleteAsync(string.format("/api/dept/{0}", id));
     }
}

That should get you started in the right direction anyway. This could definitely get cleaned up and I wrote it freehand so there may be some typos.

Update

Update your MainActivity.cs

Instead of int id = Convert.ToInt32(txtValue1)

Use

int id = Convert.ToInt32(txtValue1.Text);

Instead of GetButton.Click += GetDept(id);

Use

GetButton.Click += async (sender, args) => {
   var dept = await GetDept(id);

   No.Text = dept.no;
   Name.Text = dept.name
}
like image 127
jensendp Avatar answered Oct 19 '22 22:10

jensendp