6

I have created a WCF service that retrieves data from SQL database and can update and modify data into SQL database. I am trying to call WCF methods from xamarin for android and xamarin for iOS. I searched alot for an example how to call PUT and POST method from WCF service through xamarin for android and xamarin for iOS but no luck. I have added the WCF code below for reference. ...even created Web API but all examples and tutorials to consume Web API are for how to call GET method . I don't see any reference document which will show how to call PUT or Post method from WCF or Web api across cross platform. I have tested WCF service through Fiddler and worked fine. What would be the next step ..I have created proxy for this web service using SlsvcUtil.exe as mentioned in xamarin documentation. Can somebody post a one example of xamarin.Android that will call Update or delete method from the below wcf service.Desperately looking for help.Service contains webHttp binding.

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 for

<?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>
user2897967
  • 337
  • 2
  • 8
  • 24
  • I have added the config.file and I am creating simple android project in Xamarin to consume this service. – user2897967 Sep 09 '14 at 19:20
  • Did you follow the instructions found on the Xamarin site? http://developer.xamarin.com/guides/cross-platform/application_fundamentals/web_services/walkthrough_working_with_WCF/ They are pretty detailed. If you are having issues with the instructions, can you be more specific as to with what parts? – jensendp Sep 09 '14 at 19:29
  • yes I did , I created proxy and added in my project. Basically I want add or delete record when we click on button. Value entered into the text box must be added through wcf service into database, when clicked on ADD button. If click on Get Button then value entered in Enter Number textbox must be retrieved that is GetDeptById from WCF service and must be display in to textbox. No text box must display no .and name textbox must display name. – user2897967 Sep 09 '14 at 19:54
  • Excellent. So all you need to do now is create some buttons and click event handlers in your Xamarin.Android project. Within the event handlers or at the class level, create a new instance of your service client that is defined within the proxy and call the either the AddDept or DeleteDept methods. The generation of the proxy creates those methods for you based on the service the proxy was created from. – jensendp Sep 09 '14 at 19:57
  • I am adding my xml here. But not sure how to start or what to add in – user2897967 Sep 09 '14 at 19:58
  • I'll create a code snippet with an example. – jensendp Sep 09 '14 at 19:59
  • thank you very much but just want make sure that I am using ADO.net entity frame work to retrieve SQLdatabase data – user2897967 Sep 09 '14 at 20:05

2 Answers2

0

Here is a simple code snippet to use as a guide:

//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.
}

You should be able to follow a similar pattern for the other buttons and service calls as well. I apologize if I have made some typos. I'm going from a bit of memory and some of the WCF instructions on the Xamarin site.

jensendp
  • 2,135
  • 15
  • 15
  • Thanks for help! but do we need to add bindings again as my config file contains webHttpBinding. And we need to assign values from text boxes to function parameters for ADD method. – user2897967 Sep 09 '14 at 20:25
  • The web.config file lives with the WCF service. I don't typically generate proxies this way so I'm not sure what binding information is contained within the proxy. You can try it without explicitly creating a new binding. Also, I updated my post with some code to get the department name from the TextView. – jensendp Sep 09 '14 at 20:32
  • Thanks again for your help. I have followed the direction which is mentioned in the documentation to create proxy. Is there any other way to create it . As you have created mobile apps using xamarin ..what do you recommend use WCF to generate data from SQL or use web api. I have created Web API as well but not sure how to use it in xamarin. There is no proper example of WCF or Web api ...where we can edit SQL database using xamarin. – user2897967 Sep 10 '14 at 12:25
  • 1
    That is an acceptable way to create the proxy. I just typically don't use WCF services from Xamarin. I use WCF services in many other applications from desktop or web though. From Xamarin I tend to use Web Api web services where I create HTTP Requests to interact with them using the HttpClient class. Take a look at that class, it is fairly easy to understand. – jensendp Sep 10 '14 at 13:16
  • I am confused if we need to create custom media formatters for Web API. Can you please share one example of how to trigger methods that fetches or modify SQL data through web api on click event. I have created web api but not sure how to call methods on click event. And do we need to create proxy or how to add reference. – user2897967 Sep 10 '14 at 13:34
  • I can't see your Web Api project but if it is anything like the WCF project/methods, I would have to say no you don't need custom formatters. The formatters are only for serialization and deserialization and by default Web Api gives you both XML and JSON which should be fine for you. – jensendp Sep 10 '14 at 13:40
  • Please see the link below – user2897967 Sep 10 '14 at 13:58
  • http://stackoverflow.com/questions/25767390/how-to-consume-web-api-in-xamarin-crossplatform-application – user2897967 Sep 10 '14 at 13:59
0

First you must add the service to your project You can do this using the following command:

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

Then add to a project file created To use the added service must follow the following procedure

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;
    }
}
Hadi Salehy
  • 260
  • 2
  • 6