1

I'm consuming WCF soap web services in xamarin.forms. I've added the service reference from the visual studio which generated the asynchronous operations. I've used the following code for consuming the web service

    Service1Client dataCommunicator = new Service1Client();
                                dataCommunicator.GiveFeedbackCompleted += new EventHandler<GiveFeedbackCompletedEventArgs>(GiveFeedbackCallback);
                                dataCommunicator.GiveFeedbackAsync(editPhoneF.Text, monuments[pickerMonument.SelectedIndex], editRemarks.Text, imei);
}
    private async void GiveFeedbackCallback(object sender, GiveFeedbackCompletedEventArgs e)
            {
                if (e.Result)
                {
                    await DisplayAlert("Success", "Thank you for your valuable comments", "Ok");
                }
                else
                {
                    await DisplayAlert("Oops!!", "Internal server error, please try again later", "Ok");
                }
            }

When I test it on simulator, I just sit and wait for the reply and when I try to use a phone like an android phone then there is an error i.e. targetinvocationexception. What should I do to resolve the issue?

vishgarg
  • 445
  • 1
  • 9
  • 24

2 Answers2

1

That is not a good implementation for several reasons. First, you are using async void to handle the async completion event which will silently ignore any exceptions raised. Second, the Async/Completed pattern is not appropriate for single-shot async calls. Third, the code that results from Async/Completed pattern is just really messy for most situations (including this one).

What you should be using instead is the Task.Factory.FromAsync<>() helper, which will greatly simplify your code and resolve those problems. It would look something like this for you:

<Button Click="Button_Click" Text="Click Me"/>

...

async void Button_Click(object sender, EventArgs eventArgs) {
    Service1Client dataCommunicator = new Service1Client();
    try {
        bool result =
            await Task.Factory.FromAsync<string, Monument, string, IMEI, bool>(
                dataCommunicator.BeginGiveFeedback,
                dataCommunicator.EndGiveFeedback,
                editPhoneF.Text,
                monuments[pickerMonument.SelectedIndex],
                editRemarks.Text,
                imei);
        if (e.Result) {
            await DisplayAlert("Success", "Thank you for your valuable comments", "Ok");
        } else {
            await DisplayAlert("Internal server error", "Please try again later.", "Ok");
        }
    } catch (Exception ex) {
        await DisplayAlert("Server communication error", "Please try again later. ERROR: " + ex.GetType().Name, "Ok");
    }
}

Note that I'm using async void here, and you might think that I was contradicting myself by doing so. It is OK to use async void for the event handler of a control when you manually trap exceptions within that handler (as I have done in the example code).

Keith Rome
  • 3,208
  • 19
  • 15
  • Thanks Keith for the help. I tried the changes you've mentioned, there are two problems come, first the problem as targetinvocation exception and second I always need to switch the profile of xamarin.forms project to 4.5 #7 means it'll not support windows phone 8.1. Do you know about that? – vishgarg Mar 09 '16 at 04:34
  • TargetInvocationException will have an InnerException that will point to the real problem. TargetInvocationException itself is just a wrapper around the originating crash. – Keith Rome Mar 09 '16 at 05:54
  • The default PCL Profile when creating a Xamarin Forms project under Xamarin Studio is Profile "78". As you noticed, this does not include support for Windows Phone 8.1. If you need Windows Phone 8.1 support then you need to switch it to profile 259. Keep in mind that some nuget packages you might be relying one might not properly support that profile. However most mainstream packages support it. – Keith Rome Mar 09 '16 at 05:57
  • I posted the stack trace in a comment in an answer maybe someone has removed that. In the inner exception there was an exception in the references.cs file which was generated by visual studio when we add a new service reference. The exception was coming when the response was coming. What I'm doing now is, I've created a soap request and I'm consuming the webservice manually without adding the service reference. Its working fine. I think there some bug or issue with adding service reference or something that. I even tried to add the service reference in xamarin studio but there was same problem – vishgarg Mar 09 '16 at 07:19
  • I see. For WCF service proxy code, I've directly used the svcutil.exe tool from the Silverlight 5 Client SDK, and haven't tried using Add Service Reference from Visual Studio. The scvutil tool generates a single .cs file that we can include in our project. We usually work in Xamarin Studio (which does not have "Add Service Reference"), and so it works better that way. – Keith Rome Mar 09 '16 at 21:51
0

I think, there is a bug in the Xamarin.Forms right now which is creating the problem. I've removed the service reference and now consuming the service manually. I found the clue from the below link and using the same way to consume the web service.

https://stackoverflow.com/questions/14336414/httpclient-soap-c/20108971#20108971

Community
  • 1
  • 1
vishgarg
  • 445
  • 1
  • 9
  • 24