【问题标题】:How to Consume Web Api in xamarin CrossPlatform Application如何在 xamarin CrossPlatform 应用程序中使用 Web Api
【发布时间】:2014-11-04 05:14:57
【问题描述】:

我创建了从 SQL 数据库中检索数据的 web api。我需要在 xamrin for android 和 xamarin for iOS 中使用 web api。截至目前 xamarin for android。我不确定如何根据按钮单击事件调用 GET 和 Post 方法。

这里是 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());                }       
        }

    }
}

【问题讨论】:

    标签: android api xamarin


    【解决方案1】:

    这是我在几乎任何项目(包括 Xamarin 项目)中使用此服务的方式。

    首先,删除 Global.asax 文件中这样写的行:

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

    一般来说,这是不好的做法。您希望至少有可用的 XML 和 JSON 格式化程序,因为在安静的环境中,由消费者决定他们需要/想要的序列化类型。

    接下来,我将使用System.Net.Http.HttpClient 类与此服务进行交互。

    从这一点开始,与 Web Api 服务的交互相当简单。以下是一些示例。

    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));
         }
    }
    

    无论如何,这应该让您朝着正确的方向开始。这肯定会被清理干净,我是徒手写的,所以可能有一些错别字。

    更新

    更新您的 MainActivity.cs

    而不是int id = Convert.ToInt32(txtValue1)

    使用

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

    而不是GetButton.Click += GetDept(id);

    使用

    GetButton.Click += async (sender, args) => {
       var dept = await GetDept(id);
    
       No.Text = dept.no;
       Name.Text = dept.name
    }
    

    【讨论】:

    • 再次感谢您!我可以在 xamarin for android 项目中添加 Systen.net.http 吗?
    • 是的,您应该可以将其直接添加到您的 Xamarin.Android 项目中。
    • 嘿,你想让我用你的代码片段替换上面列出的我的 web api 方法,或者在哪里使用你的方法,我不明白。在哪里添加异步方法。
    • 不,让您的 Web Api 方法保持原样。获取我的代码并在您的 Xamarin.Android 项目中使用它。就像在您的 WCF 帖子中一样,当用户单击按钮添加部门时,在我的示例中调用 AddDept 方法。如果用户想要获取当前部门的列表,请在我的代码中调用 GetDepts 方法。这一切都应该从 Xamarin.Android 应用程序中完成。
    • 我的荣幸。我喜欢这个东西! :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-20
    • 2011-07-18
    相关资源
    最近更新 更多