【问题标题】:Consume WCF service in Xamarin Cross Platform Application在 Xamarin 跨平台应用程序中使用 WCF 服务
【发布时间】:2014-11-03 06:13:57
【问题描述】:

我创建了一个 WCF 服务,该服务从 SQL 数据库中检索数据,并且可以将数据更新和修改到 SQL 数据库中。我正在尝试从 xamarin for android 和 xamarin for iOS 调用 WCF 方法。我搜索了很多关于如何通过 xamarin for android 和 xamarin for iOS 从 WCF 服务调用 PUT 和 POST 方法的示例,但没有运气。我在下面添加了 WCF 代码以供参考。 ...甚至创建了 Web API,但所有使用 Web API 的示例和教程都是关于如何调用 GET 方法的。我没有看到任何参考文档显示如何跨平台从 WCF 或 Web api 调用 PUT 或 Post 方法。我已经通过 Fiddler 测试了 WCF 服务并且工作正常。下一步是什么..我已经使用 SlsvcUtil.exe 为这个 Web 服务创建了代理,如 xamarin 文档中所述。有人可以发布一个 xamarin.Android 的示例,它将从下面的 wcf 服务调用更新或删除方法。拼命寻找帮助。服务包含 webHttp 绑定。

WCF

Service1.svc.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.ServiceModel.Web; 
using System.Text;

public class Service1 : IService1 
{ 
    public List GetDeptsList() 
    { 
        using (DeptDBEntities entities = new DeptDBEntities()) 
        { 
            return entities.Depts.ToList(); 
        } 
    }

    public Dept GetDeptByID(string no)
    {
        try
        {
            int deptId = Convert.ToInt32(no);

            using (DeptDBEntities entities = new DeptDBEntities())
            {
                return entities.Depts.SingleOrDefault(dept => dept.no == deptId);
            }
        }
        catch
        {
            throw new FaultException("Something went wrong");
        }
    }

    public void AddDept(string name)
    {
        using (DeptDBEntities entities = new DeptDBEntities())
        {
            Dept dept = new Dept { name = name };
            entities.Depts.Add(dept);
            entities.SaveChanges();
        }
    }

    public void UpdateDept(string no, string name)
    {
        try
        {
            int deptId = Convert.ToInt32(no);

            using (DeptDBEntities entities = new DeptDBEntities())
            {
                Dept dept = entities.Depts.SingleOrDefault(b => b.no == deptId);
                dept.name = name;
                entities.SaveChanges();
            }
        }
        catch(Exception e)
        {
            throw new FaultException(e.Message);

        }
    }

    public void DeleteDept(string no)
    {
        try
        {
            int deptId = Convert.ToInt32(no);

            using (DeptAppDBEntities entities = new DeptAppDBEntities())
            {
                Dept dept = entities.Depts.SingleOrDefault(b => b.no == deptId);
                entities.Depts.Remove(dept);
                entities.SaveChanges();
            }
        }
        catch
        {
            throw new FaultException("Something went wrong");
        }
    }

}

web.config

   <?xml version="1.0"?>
      <configuration>
      <configSections>
       <section name="entityFramework"   type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
     </configSections>
     <system.web>
     <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      </assemblies>
      </compilation>
      <pages controlRenderingCompatibilityVersion="4.0"/>
      </system.web>
      <system.serviceModel>
                 <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
      </behaviors>
      <services>
      <service name="WcfWithJsonP.Service1" behaviorConfiguration="restfulBehavior">
        <endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" bindingConfiguration="" contract="WcfWithJsonP.IService1"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/Service1"/>
          </baseAddresses>
        </host>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
       </services>
      <behaviors>
      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp defaultOutgoingResponseFormat="Json"/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="restfulBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      </behaviors>
      <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
      </system.serviceModel>
     <system.webServer>
     <modules runAllManagedModulesForAllRequests="true"/>
        <directoryBrowse enabled="true"/>
     </system.webServer>
     <entityFramework>
     <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory,   EntityFramework">
      <parameters>
        <parameter value="v12.0"/>
      </parameters>
     </defaultConnectionFactory>
     </entityFramework>
    </configuration

>

Main.axml 用于

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minWidth="25px"
    android:minHeight="25px">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="134.1dp"
        android:layout_height="fill_parent"
        android:minWidth="25px"
        android:minHeight="25px">
        <TextView
            android:text="Enter No:"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:layout_width="163.4dp"
            android:layout_height="wrap_content"
            android:id="@+id/No"
            android:layout_marginBottom="27.5dp"
            android:layout_marginTop="0.0dp"
            android:layout_marginLeft="5dp" />
        <TextView
            android:text="Enter name:"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:layout_width="252.7dp"
            android:layout_height="wrap_content"
            android:id="@+id/Name"
            android:layout_marginBottom="27.5dp"
            android:layout_marginTop="0.0dp"
            android:layout_marginLeft="5dp"
            android:enabled="false"
            android:visibility="invisible" />
    </LinearLayout>
    <Button
        android:id="@+id/Get"
        android:layout_width="fill_parent"
        android:layout_height="36.6dp"
        android:text="Get" />
    <Button
        android:id="@+id/ADD"
        android:layout_width="fill_parent"
        android:layout_height="36.6dp"
        android:text="ADD" />
    <Button
        android:id="@+id/Update"
        android:layout_width="fill_parent"
        android:layout_height="36.6dp"
        android:text="Update" />
    <Button
        android:id="@+id/Delete"
        android:layout_width="fill_parent"
        android:layout_height="36.6dp"
        android:text="Delete" />
    <TextView
        android:text=""
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/ValueNo"
        android:layout_marginBottom="27.5dp"
        android:layout_marginTop="0.0dp"
        android:background="@android:color/holo_purple" />
    <TextView
        android:text=""
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/ValueName"
        android:layout_marginBottom="27.5dp"
        android:layout_marginTop="0.0dp"
        android:background="@android:color/holo_purple" />
</LinearLayout>

【问题讨论】:

  • 我已经添加了 config.file,我正在 Xamarin 中创建简单的 android 项目来使用这个服务。
  • 您是否按照 Xamarin 网站上的说明进行操作? developer.xamarin.com/guides/cross-platform/… 很详细。如果您对说明有疑问,能否更具体地说明哪些部分?
  • 是的,我做了,我创建了代理并添加到我的项目中。基本上,当我们单击按钮时,我想添加或删除记录。当点击添加按钮时,输入文本框中的值必须通过 wcf 服务添加到数据库中。如果单击获取按钮,则必须从 WCF 服务检索输入数字文本框中输入的值,即 GetDeptById,并且必须显示在文本框中。没有文本框必须显示没有。并且名称文本框必须显示名称。
  • 优秀。因此,您现在需要做的就是在您的 Xamarin.Android 项目中创建一些按钮和单击事件处理程序。在事件处理程序中或在类级别,创建在代理中定义的服务客户端的新实例,并调用 AddDept 或 DeleteDept 方法。代理的生成会根据创建代理的服务为您创建这些方法。
  • 我在这里添加我的 xml。但不知道如何开始或添加什么

标签: c# wcf xamarin xamarin.android


【解决方案1】:

首先您必须将服务添加到您的项目中 您可以使用以下命令执行此操作:

Cd C:\Program Files (x86)\Microsoft SDKs\Silverlight\v5.0\Tools\ SlSvcUtil.exe http://localhost:2323/HisDashboardService/ProfilerService.svc /directory:"C:\Folder"

然后添加到创建的项目文件中 要使用添加的服务必须遵循以下步骤

public class ServiceAccessor
{
    static string serviceUrl = "http://172.16.12.17:7698/HisDashboardService/";
    public static readonly EndpointAddress ProfilerServiceEndPoint = new EndpointAddress(serviceUrl + "ProfilerService.svc");

    private ProfilerServiceClient _profilerServiceClient;

    private static ServiceAccessor _instanceServiceAccessor;
    public static ServiceAccessor Instance
    {
        get { return _instanceServiceAccessor ?? (_instanceServiceAccessor = new ServiceAccessor()); }
    }

    ServiceAccessor()
    {
        InitializeServiceClient();
    }

    private void InitializeServiceClient()
    {
        BasicHttpBinding binding = CreateBasicHttp();

        #region ProfilerService
        _profilerServiceClient = new ProfilerServiceClient(binding, ProfilerServiceEndPoint);
        #endregion ProfilerService
    }

    private static BasicHttpBinding CreateBasicHttp()
    {
        BasicHttpBinding binding = new BasicHttpBinding
        {
            Name = "basicHttpBinding",
            MaxBufferSize = 2147483647,
            MaxReceivedMessageSize = 2147483647
        };
        TimeSpan timeout = new TimeSpan(1, 0, 0);
        binding.SendTimeout = timeout;
        binding.OpenTimeout = timeout;
        binding.ReceiveTimeout = timeout;
        return binding;
    }
}

【讨论】:

    【解决方案2】:

    这是一个简单的代码 sn-p 用作指导:

    //first at the class level, create a private variable for the client.
    private Service1Client _client;
    private Button _addButon;
    private TextView _txtDeptName;
    
    //Initialize the _client in the OnCreate() method.
    protected override void OnCreate(Bundle bundle)
    {
         base.OnCreate(bundle);
    
         var endpoint = new EndpointAddress("http://<ipAddress:port>/Service1.svc");
    
         var binding = new BasicHttpBinding{
            Name = "basicHttpBinding",
            MaxBufferSize = 2147483647,
            MaxReceivedMessageSize = 2147483647
        };
    
        TimeSpan timeout = new TimeSpan(0, 0, 30);
        binding.SendTimeout = timeout;
        binding.OpenTimeout = timeout;
        binding.ReceiveTimeout = timeout;
    
        _client = new Service1Client(binding, endpoint);
        _client.AddDeptCompleted += ClientAddDeptCompleted;
    
        _addButton = FindViewById<Button>(Android.Resources.Id.Add);
        _addbutton.Click += AddButton_Clicked;
    
        _txtDeptName = FindViewbyId<TextView>(Android.Resources.Id.Name);
    }
    
    //Then within the event handlers, do something like this
    public void AddButton_Clicked(object sender, EventArgs e)
    {
         _client.AddDeptAsync(_txtDeptName.Text);
    }
    
    //Handle the request completed event.
    private void ClientAddDeptCompleted(object sender, AddDeptCompletedEventArgs addDeptCompletedEventArgs)
    {
         //TODO: Something with the notification that the request has completed.
    }
    

    您也应该能够对其他按钮和服务调用遵循类似的模式。如果我犯了一些错别字,我深表歉意。我从一点记忆和 Xamarin 网站上的一些 WCF 指令开始。

    【讨论】:

    • 感谢您的帮助!但是我们是否需要再次添加绑定,因为我的配置文件包含 webHttpBinding.我们需要将文本框中的值分配给 ADD 方法的函数参数。
    • web.config 文件与 WCF 服务一起存在。我通常不会以这种方式生成代理,因此我不确定代理中包含哪些绑定信息。您可以在不显式创建新绑定的情况下尝试它。另外,我用一些代码更新了我的帖子,以从 TextView 中获取部门名称。
    • 再次感谢您的帮助。我已按照文档中提到的方向创建代理。有没有其他方法可以创建它。当您使用 xamarin 创建移动应用程序时,您建议使用 WCF 从 SQL 生成数据还是使用 Web api。我也创建了 Web API,但不确定如何在 xamarin 中使用它。没有合适的 WCF 或 Web api 示例......我们可以在其中使用 xamarin 编辑 SQL 数据库。
    • 这是一种可接受的创建代理的方式。我只是通常不使用 Xamarin 的 WCF 服务。不过,我在桌面或 Web 的许多其他应用程序中使用 WCF 服务。在 Xamarin 中,我倾向于使用 Web Api Web 服务,在其中创建 HTTP 请求以使用 HttpClient 类与它们交互。看一下那个类,比较容易理解。
    • 如果我们需要为 Web API 创建自定义媒体格式化程序,我会感到困惑。您能否分享一个示例,说明如何在点击事件时触发通过 Web api 获取或修改 SQL 数据的方法。我已经创建了 web api,但不确定如何在点击事件上调用方法。我们是否需要创建代理或如何添加参考。
    猜你喜欢
    • 2019-01-03
    • 2023-03-14
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    • 2020-08-15
    • 2015-06-20
    • 1970-01-01
    相关资源
    最近更新 更多