API Calls and Fetching Data with C# and Xamarin

0

So I have a program that Calls an API once the user has entered a search term Like so:

        LoadTVShows load = new LoadTVShows();

        private async void searchShow(object sender, EventArgs e)
        {
            searchString = searchBox.Text;
            try
            {
                var getTvShow = await load.GetAPI(searchString).ConfigureAwait(false);

            }
            catch
            {

            }

            showName.Text = load.name;
            showSummary.Text = load.summary;
            airTime.Text = load.time;
            countryCode.Text = load.country;


        }

the var getTvShow simply calls the class to run the api and return true once done, storing the values needed within its own class for access outside.

However when I get to storing the data in the text fields, I am met with this error message.

System.Exception
  HResult=0x8001010E
  Message=The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
  Source=Windows
  StackTrace:
   at Windows.UI.Xaml.Controls.TextBlock.put_Text(String value)
   at Xamarin.Forms.Platform.UWP.LabelRenderer.UpdateTextPlainText(TextBlock textBlock)
   at Xamarin.Forms.Platform.UWP.LabelRenderer.UpdateText(TextBlock textBlock)
   at Xamarin.Forms.Platform.UWP.LabelRenderer.OnElementPropertyChanged(Object sender, PropertyChangedEventArgs e)
   at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
   at Xamarin.Forms.BindableObject.OnPropertyChanged(String propertyName)
   at Xamarin.Forms.Element.OnPropertyChanged(String propertyName)
   at Xamarin.Forms.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, Boolean silent)
   at Xamarin.Forms.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
   at Xamarin.Forms.BindableObject.SetValue(BindableProperty property, Object value, Boolean fromStyle, Boolean checkAccess)
   at Xamarin.Forms.Label.set_Text(String value)
   at MajorProjectTvApplication.SearchView.<searchShow>d__15.MoveNext() in D:\Tafe Work\Mobile Apps\wk12\MajorProjectTvApplication\MajorProjectTvApplication\MajorProjectTvApplication\SearchView.xaml.cs:line 70

Due to this I am quite unsure how to get around this, so any thoughts and ideas would be a big help.

LoadTvShows Class provided in case:

public class LoadTVShows
    {
        public string name;
        public string summary;
        public string time;
        public string country;

        public async Task<bool> GetAPI(string searchString)
        {
            string search = searchString;
            try
            {
                using (var client = new HttpClient())
                {
                    var response = await client.GetAsync("http://api.tvmaze.com/singlesearch/shows?q=" + search + "");
                    var responseString = await response.Content.ReadAsStringAsync();
                    var rawTvListings = JsonConvert.DeserializeObject<OpenTVGuideResponse>(responseString);

                    name = rawTvListings.Name;
                    time = rawTvListings.Schedule.Time;
                    summary = rawTvListings.Summary;
                    country = rawTvListings.Network.Country.Code;

                    return true;
                }
            }
            catch (HttpRequestException httpRequestError)
            {
                return false;
            }
        }
    }

    public class OpenTVGuideResponse
    {
        public string Name { get; set; } 

        public GetTime Schedule { get; set; }

        public string Summary { get; set; }

        public GetNetwork Network { get; set; }

    }
    public class GetTime
    {
        public string Time { get; set; }
    }

    public class GetNetwork
    {
        public GetCountry Country { get; set; }
    }

    public class GetCountry
    {
        public string Code { get; set; }
    }
c#
api
xamarin
uwp
asked on Stack Overflow Jun 17, 2020 by Mason Browne

2 Answers

0

Probably the error is on ConfigureAwait

it's not the error, but you must check response.IsSuccessStatusCode:

>

HttpResponseMessage response = await client.GetAsync("http://api.tvmaze.com/singlesearch/shows?q=" + search + "");
if (response.IsSuccessStatusCode)
{
    var responseString = await response.Content.ReadAsStringAsync();
    var rawTvListings = JsonConvert.DeserializeObject<OpenTVGuideResponse>(responseString);
}

You could read this article to improve the code.

https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-implementation

0

Firstly, using ConfigureAwait(false) in the below line of code is not at all required.

var getTvShow = await load.GetAPI(searchString).ConfigureAwait(false);

You are updating your UI from the non UI thread context. So one solution will be to wrap your UI related code inside the BeginInvokeOnMainThread method.

Device.BeginInvokeOnMainThread (() => 
{
  showName.Text = load.name;
  showSummary.Text = load.summary;
  airTime.Text = load.time;
  countryCode.Text = load.country;
};
answered on Stack Overflow Jun 17, 2020 by Dishant

User contributions licensed under CC BY-SA 3.0