HttpClient nie działa z WebApi Service - Android Client

0

Witam, chciałbym połączyć się do WebApi i wywołać akcję z kontrolera przy użyciu klienta Android app, jednak nie działa Przy HttpResponseMessage rzuca błędem.
Co może być powodem ?

{System.TypeInitializationException: The type initializer for 'System.Net.Http.FormattingUtilities' threw an exception. ---> System.NotImplementedException: The method or operation is not implemented.
  at System.Runtime.Serialization.XsdDataContractExporter..ctor () [0x00006] in <3a79d7e511364d8cb549424699c1a7bb>:0 
  at System.Net.Http.FormattingUtilities..cctor () [0x000e6] in <dd5d13035e4d4a2e812d07ec2f066876>:0 
   --- End of inner exception stack trace ---
  at System.Net.Http.Formatting.JsonMediaTypeFormatter..ctor () [0x0000b] in <dd5d13035e4d4a2e812d07ec2f066876>:0 
  at System.Net.Http.HttpClientExtensions.PostAsJsonAsync[T] (System.Net.Http.HttpClient client, System.String requestUri, T value, System.Threading.CancellationToken cancellationToken) [0x00000] in <dd5d13035e4d4a2e812d07ec2f066876>:0 
  at System.Net.Http.HttpClientExtensions.PostAsJsonAsync[T] (System.Net.Http.HttpClient client, System.String requestUri, T value) [0x00008] in <dd5d13035e4d4a2e812d07ec2f066876>:0 
  at SpotifySearchEngine.MainActivity+<Method2>d__4.MoveNext () [0x000fe] in C:\Users\KOMP\source\repos\SpotifySearchEngine\SpotifySearchEngine\MainActivity.cs:74 }

Xamarin MainActivity:

[Activity(Label = "SpotifySearchEngine", MainLauncher = true)]
    public class MainActivity : Activity
    {
        private Button mBtnLogin;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            mBtnLogin = FindViewById<Button>(Resource.Id.btnLogin);

            mBtnLogin.Click += MBtnLogin_Click;
        }

        /// <summary>
        /// Button clicked event
        /// </summary>
        /// <param name="sender">obj sender</param>
        /// <param name="e">event</param>
        private async void MBtnLogin_Click(object sender, EventArgs e)
        {
            string foo = await Method1();
        }

        /// <summary>
        /// Get data string
        /// </summary>
        /// <returns></returns>
        public async Task<string> Method1()
        {
            var foo = await Method2();
            return foo;
        }

        /// <summary>
        /// Main method send email
        /// </summary>
        /// <returns></returns>
        public static async Task<string> Method2()
        {
            EmailConfigDetailsVM emildetails = new EmailConfigDetailsVM();
            emildetails.ToRecipients = "[email protected]";
            emildetails.FromRecipients = "[email protected]";
            emildetails.Body = "To jest opis";
            emildetails.Subject = "To jest tytul";


            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:59515");
            var serializedProduct = JsonConvert.SerializeObject(emildetails);
            var content = new StringContent(serializedProduct, Encoding.UTF8, "application/json");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            try
            {
                HttpResponseMessage response = await client.PostAsJsonAsync("/api/SendMailApi", emildetails);
                var resp = await response.Content.ReadAsStringAsync();

                return response.Headers.Location.ToString();
            }
            catch (System.OperationCanceledException oce)
            {
                return null;
                // Just pass
            }
            catch (Exception exc)
            {

                return null;
                // Just pass
            }
        }

        public class EmailConfigDetailsVM  
        {
            public string ToRecipients { get; set; }
            public string FromRecipients { get; set; }
            public string Body { get; set; }
            public string Subject { get; set; }
        }
    }

WebService:

Routes Web Api:

namespace EmployeeWS
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            // Configure Web API to use only bearer token authentication.
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API routes
            config.MapHttpAttributeRoutes();
            
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

WebApi:
SendMailApiController

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Mail;
using System.Web.Http;

namespace EmployeeWS.Controllers
{
    public class SendMailApiController : ApiController
    {
        [HttpPost]
        public HttpResponseMessage SendMail(EmailConfigDetailsVM vm)
        {
            bool responce = false;
            try
            {
                MailMessage mail = new MailMessage();
                SmtpClient smtpServer = new SmtpClient();
                string password = "123123123";
                mail.From = new MailAddress("[email protected]");
                string[] toRecipients = vm.ToRecipients.Split(',');
                foreach (string toRecipient in toRecipients)
                {
                    if (!string.IsNullOrEmpty(toRecipient))
                        mail.To.Add(new MailAddress(toRecipient));
                }

                mail.Subject = vm.Subject;
                mail.Body = vm.Body;
                vm.FromRecipients = "[email protected]";
                smtpServer.Host = "smtp.gmail.com";
                smtpServer.Port = 587;
                smtpServer.DeliveryMethod = SmtpDeliveryMethod.Network;
                smtpServer.EnableSsl = true;
                smtpServer.Timeout = 100000;
                smtpServer.Credentials = new System.Net.NetworkCredential(vm.FromRecipients, password);
                smtpServer.Send(mail);

                var Result = this.Request.CreateResponse(HttpStatusCode.OK, responce, new JsonMediaTypeFormatter());

                return Result;
            }
            catch (Exception ex)
            {
                HttpError Error = new HttpError(ex.Message) { { "IsSuccess", false } };
                return this.Request.CreateErrorResponse(HttpStatusCode.OK, Error);
            }

        }


        public class EmailConfigDetailsVM 
        {
            public string ToRecipients { get; set; }
            public string FromRecipients { get; set; }
            public string Body { get; set; }
            public string Subject { get; set; }
        }
    }
}

0

Masz, wygooglowałem za Ciebie ;):
https://stackoverflow.com/questions/40005413/could-not-load-type-system-net-http-formattingutilities

użyj PostAsync zamiast PostAsJsonAsync

0

Pierwsze uzylem postasync ale niestety nie dzialalo taki sam blad.

0

Chyba wysyłasz nie to, co powinieneś.

            // tutaj serializujesz obiekt i masz go w zmiennej serializedProduct

            var serializedProduct = JsonConvert.SerializeObject(emildetails);
            var content = new StringContent(serializedProduct, Encoding.UTF8, "application/json");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            try
            {
                // tutaj wysyłasz jako JSON obiekt, który nie jest zserializowany, więc on go chyba próbuje zserializować do XML
                HttpResponseMessage response = await client.PostAsJsonAsync("/api/SendMailApi", emildetails);
0

W tym przypadku akurat wysyłam obiekt przez PostAsJsonAsync dlatego też nie są potrzebne te linie były przygotowanie pod PostAsync:

var serializedProduct = JsonConvert.SerializeObject(emildetails);
            var content = new StringContent(serializedProduct, Encoding.UTF8, "application/json");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

i wtedy:

HttpResponseMessage response = await client.PostAsync("/api/SendMailApi", content);

Ale nie działa nawet z PostAsync

0

Czy jest jakiś sposób aby połączyć się z WebApi na localhost przez XamarinApp? Bo z tego co wyczytałem to po prostu maszyna wirtualna nie wykrywa WebApi. Stworzyłem projekt w WPF i tam normalnie wszystko działa ?

1

Maszyna wirtualna (chodzi o emulator?) jest oddzielnym komputerem, stąd jej localhost i twój localhost to kompletnie co innego.

W zależności od tego, jakiego używasz narzędzia do maszyn wirtualnych możesz na pewno jakoś połączyć maszynę hosta i maszynę gościa. Ja mam Visual Studio Emulator for Android, w nim maszyna wirtualna (emulator) ma połączenie z dwoma sieciami - jedną wewnętrzną (Windows Phone Internal Switch) oraz zewnętrzną, zapewniającą dostęp do internetu (External Switch) i sieć wewnętrzna jest również widoczna w maszynie-hoście (używa adresów IP automatycznych, postaci 169.254.80.80), ale mogę się połączyć przez sieć wewnętrzną z usługą, która stoi na hoście (aczkolwiek usługa ta musi nasłuchiwać również na 169.254.80.80, nie tylko na 127.0.0.1).

0

Dzięki wielkie :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1