Xamarin forms ASP.NET android emulator cannot access localhost API - asp.net

I'm developing a Xamarin forms app that uses ASP.NET Web Application template. I followed this tutorial on YouTube. I'm having problem using the PostAsync method. The web api itself can start OK via IIS Chrome on my local machine, but not via the emulator. I printed the response message, displayed as
StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content:
System.Net.Http.HttpConnection+HttpConnectionResponseContent, Headers:
{
Server: Microsoft-HTTPAPI/2.0
Date: Sun, 26 Sep 2021 06:53:22 GMT
Connection: close
Content-Type: text/html; charset=us-ascii
Content-Length: 334
}
Here's the service class which contains the RegisterAsync method
public class UserService
{
private string androidApiUrl = "https://10.0.2.2:44358/api/Account/Register";
private string iOSApiUrl = "https://localhost:44358/api/Account/Register";
private HttpClient client;
public UserService()
{
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback =
(msg, cert, chain, err) => { return true; };
client = new HttpClient(httpClientHandler);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<bool> RegisterAsync(string username, string pswd, string confmPswd)
{
var newAccount = new ModelAccount
{
Email = username,
Password = pswd,
ConfirmPassword = confmPswd
};
var json = JsonConvert.SerializeObject(newAccount);
HttpContent content = new StringContent(json);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json")
{
CharSet = Encoding.UTF8.WebName
};
try
{
var response = await client.PostAsync(androidApiUrl, content);
Console.WriteLine(response.ToString());
Console.WriteLine(response.ReasonPhrase);
Console.WriteLine(response);
return response.IsSuccessStatusCode;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
throw e;
}
}
}
Here's the WebAPI's properties...
Here's the ModelConvert which is json-serialized.
class ModelAccount
{
public string Email { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
If it makes any different if I changed the port number to 61902 as suggest by this blog, it still won't work.
Thank you
Edit:
as requested by #Aristos, here are the port numbers connected.

On the settings you have define the port number - usually this is a random port so probably have change on your system. Check on witch port your local iis is running when you run visual studio and change that according.

Related

Invalid Registration when sending Notification FCM specific device Xamarin iOS

I have a question here about getting an Invalid Registration FCM error. I want to send notification to specific device through Backend .Net (EF)
First of all I saved the deviceToken to the server (Xamarin iOS).
I read the error from https://firebase.google.com/docs/cloud-messaging/http-server-ref
200 + error:InvalidRegistration Check the format of the registration
token you pass to the server. Make sure it matches the registration
token the client app receives from registering with Firebase
Notifications. Do not truncate or add additional characters.
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
//FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken);
//byte[] bytes = deviceToken.ToArray<byte>();
//string[] hexArray = bytes.Select(b => b.ToString("x2")).ToArray();
//DeviceToken = string.Join(string.Empty, hexArray);
string deviceTokenString;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
deviceTokenString = BitConverter.ToString(deviceToken.ToArray());
}
else
{
deviceTokenString = deviceToken.ToString();
}
Preferences.Set("TokenDevice", deviceTokenString);
}
I saved the deviceToken to Preferences and also saved it to the server. My deviceToken code on Xamarin iOS:
1A-F5-BE-DC-E4-22-07-46-AA-C4-87-CC-08-F5-D7-09-D4-AB-43-18-26-E0-65-3B-39-4E-6F-5E-02-35-9E-3A
I don't know if this method of getting the deviceToken on Xamarin iOS is really correct at this time?
Backend I write API to send:
private static Uri FireBasePushNotificationsURL = new Uri("https://fcm.googleapis.com/fcm/send");
private static string ServerKey = "key=AAAAqOId6Is:APxxxxxxxxxxxxxxxxxxxx....";
[HttpPost]
public async void PushNotificationToFCM(string deviceTokens, string title, string body, object data, string linkdirection)
{
using (var client = new HttpClient())
{
var messageInformation = new Message()
{
notification = new NotificationFirebases()
{
title = title,
text = body
},
data = new Dictionary<string, string>()
{
{ "link", linkdirection },
},
to = deviceTokens
};
//Object to JSON STRUCTURE => using Newtonsoft.Json;
string jsonMessage = JsonConvert.SerializeObject(messageInformation);
string postBody = JsonConvert.SerializeObject(messageInformation).ToString();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", ServerKey);
var response = client.PostAsync(FireBasePushNotificationsURL, new StringContent(postBody, Encoding.UTF8, "application/json"));
var responseString = response.Result.Content.ReadAsStringAsync().Result;
}
}
public class Message
{
public string to { get; set; }
public NotificationFirebases notification { get; set; }
public object data { get; set; }
}
public class NotificationFirebases
{
public string title { get; set; }
public string text { get; set; }
}
When I test I get the error:
{\"multicast_id\":7343900550378569449,\"success\":0,\"failure\":1,\"canonical_ids\":0, \" results\":[{\"error\":\"InvalidRegistration\"}]}. I have tried with deviceToken on Android and it succeeds. Appears only with deviceToken on Xamarin iOS
Please note that I tried sending a notification in Firebase Cloud Messaging: https://console.firebase.google.com/u/0/project/.... then I got a notification, so you can see that my APNS configuration is not wrong.
Looking forward to everyone's help. I also spent more than 2 weeks searching and trying to no avail. Thank you very much.
Update Backend I write API to send:
public void PushNotificationToFCM(string deviceTokens, string title, string body, object data, string linkdirection)
{
FirebaseApp.Create(new AppOptions() {
Credential= GoogleCredential.FromFile("private_key.json")
});
// This registration token comes from the client FCM SDKs.
var registrationToken = deviceTokens;
// See documentation on defining a message payload.
var message = new Message()
{
Apns = new ApnsConfig { Aps = new Aps { ContentAvailable = true, Sound = "default" } },
Data = new Dictionary<string, string>()
{
{ "link", linkdirection },
},
Token = registrationToken,
Notification= new FirebaseAdmin.Messaging.Notification()
{
Title = title,
Body = body,
}
};
// Send a message to the device corresponding to the provided
// registration token.
string response = FirebaseMessaging.DefaultInstance.SendAsync(message).Result;
// Response is a message ID string.
Debug.WriteLine("Successfully sent message: " + response);
}
I don't know if such iOS device's TokenDevice code is correct? I tried to submit it, however getting the error: System.AggregateException: 'One or more errors occurred. (The registration token is not a valid FCM registration token)'
I uninstalled and reinstalled the app, I got a new tokenDevice. However when I send the notification I still get the same error
As an alternative workaround, you can use this NuGet package Plugin.FirebasePushNotification.
1. After Creating the iOS Project, add "GoogleService-Info.plist" file to your iOS Project and update the property to BundleResource.
2. In Info.plist and FinishedLaunching method, add following line:
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
FirebasePushNotificationManager.Initialize(options, true);
return base.FinishedLaunching(app, options);
}
3. Then add the below in App Construct.
CrossFirebasePushNotification.Current.OnTokenRefresh += (s, p) =>
{
System.Diagnostics.Debug.WriteLine($"TOKEN : {p.Token}");
};
CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) =>
{
System.Diagnostics.Debug.WriteLine("Received");
foreach (var data in p.Data)
{
System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}");
}
};
CrossFirebasePushNotification.Current.OnNotificationOpened += (s, p) =>
{
System.Diagnostics.Debug.WriteLine("Opened");
foreach (var data in p.Data)
{
System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}");
}
};
4. After getting the FCM registration token. then click Test, the targeted client device (with the app in the background) should receive the notification in the system notifications tray.

Does MassTransit Request/Response need common .dll's in microservice architecture?

I am going to implement my app in .Net Core, using RabbitMQ and MassTransit in Request/Response pattern.
Here is the code for receiver (it receives the username and password and then sends the username and a provider key to the client):
//BusConfiguration.cs
public static IBusControl ConfigureBus(
Action<IRabbitMqBusFactoryConfigurator, IRabbitMqHost> registrationAction = null)
{
return Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = cfg.Host(new Uri(RabbitMqConstants.RabbitMqUri), hst =>
{
hst.Username(RabbitMqConstants.UserName);
hst.Password(RabbitMqConstants.Password);
});
registrationAction?.Invoke(cfg, host);
});
}
public void ConfigureBus()
{
bus = BusConfigurator.ConfigureBus((cfg, host) =>
{
cfg.ReceiveEndpoint(host, RabbitMqConstants.OAuth2ServiceQueue, e =>
{
e.Consumer<CreateUserCommandConsumer>();
});
});
TaskUtil.Await(() => bus.StartAsync());
}
//CreateUserCommandConsumer.cs
public class CreateUserCommandConsumer : IConsumer<ICreateUserCommand>
{
public async Task Consume(ConsumeContext<ICreateUserCommand> context)
{
await context.RespondAsync<IUserCreatedEvent>(new
{
UserName = context.Message.UserName,
ProviderKey = "q1w2e3d3r"
});
}
}
The command and event classes are like below:
//ICreateUserCommand.cs
namespace WebHost.My.ServiceBus.Messages
{
public interface ICreateUserCommand
{
string UserName { get; set; }
string Password { get; set; }
}
}
//IUserCreatedEvent.cs
namespace WebHost.My.ServiceBus.Messages.CreateUser
{
public interface IUserCreatedEvent
{
string UserName { get; set; }
string ProviderKey { get; set; }
}
}
And here is the code for my client (sends request for user creation):
var bus = BusConfigurator.ConfigureBus((cfg, host) =>
{
cfg.ReceiveEndpoint(host, "profile.test.service", e =>
{
});
});
TaskUtil.Await(() => bus.StartAsync());
try
{
IRequestClient<ICreateUserCommand, IUserCreatedEvent> client = CreateRequestClient(bus);
var userName = "username";
var password = "password";
Task.Run(async () =>
{
var response = await client.Request(new CreateUserCommand()
{
UserName = userName,
Password = password
});
Console.WriteLine("User Provider key: {0}", response.ProviderKey);
Console.WriteLine("User Username: {0}", response.UserName);
}).Wait();
}
catch (Exception ex)
{
Console.WriteLine("Exception!!! OMG!!! {0}", ex);
}
finally
{
bus.Stop();
}
}
static IRequestClient<ICreateUserCommand, IUserCreatedEvent> CreateRequestClient(IBusControl busControl)
{
var serviceAddress = new Uri(RabbitMqConstants.RabbitMqUri + RabbitMqConstants.OAuth2ServiceQueue);
var client =
busControl.CreateRequestClient<ICreateUserCommand, IUserCreatedEvent>(serviceAddress, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(60));
return client;
}
The point is that the two sides (request side and response side) are different projects with no .ddl in common. In other words, they do not share the IUserCreatedEvent and ICreateUserCommand interfaces. When running the server code (respondent), it creates an exchange named like "WebHost.My.ServiceBus.Messages:ICreateUserCommand" which is a combination of the namespace and interface name. Since I do not have such a namespace in my client side code, when the respondent sends the provider key and username, the message goes to a _skipped exchange and I cannot get the response.
As far as I searched and understood, the Command and Event interfaces must be shared between the two projects (requester and respondent), but I since I am coding my project API-based, I do not want them to share the namespaces!
How is it possible to overcome such a limitation in MassTransit?
Thanks so much

While accessing Web API getting 404 Not Found

While accessing web Api in xamarin.forms i am getting this error below which is i am unable to Solve
{StatusCode: 404, ReasonPhrase: 'Not Found', Version: 1.1, Content:
System.Net.Http.StreamContent, Headers: { Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET Date: Fri, 09 Feb 2018 12:50:00 GMT
Content-Type: text/html Content-Length: 1245 }}
This is my web Api Code.
public IList<TCourse> GetData()
{
try
{
using (var context = new HCMSEntities())
{
var cli = (from b in context.tblTrainingCourses
orderby b.CourseID
select new TCourse { CourseID = b.CourseID, Course = b.Course }
).ToList();
return cli;
}
}
catch (Exception ex)
{
return null;
}
}
And here is the code which is consuming the api and i am getting above error.
public async Task Index()
{
List<TCourse> EmpInfo = new List<TCourse>();
try
{
using (var client = new HttpClient())
{
//Passing service base url
client.BaseAddress = new Uri("http://10.20.2.62/");
client.DefaultRequestHeaders.Clear();
//Define request data format
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//Sending request to find web api REST service resource GetAllEmployees using HttpClient
HttpResponseMessage Res = await client.GetAsync("api/Course");
//Checking the response is successful or not which is sent using HttpClient
if (Res.IsSuccessStatusCode)
{
//Storing the response details recieved from web api
var EmpResponse = Res.Content.ReadAsStringAsync().Result;
//Deserializing the response recieved from web api and storing into the Employee list
EmpInfo = JsonConvert.DeserializeObject<List<TCourse>>(EmpResponse);
}
}
}
catch (Exception e)
{
}
}
The web Api is not deployed.I tried http://localhost/ in base address than i switched to Ip.
no idea whats wrong and where.
kindly Guide.

Gmail fails to respond with MailKit

I'm working in ASP.NET Core and using MailKit for email functionality. The method I've previously used is no longer working.
I have an SmtpOptions.cs class:
public class SmtpOptions
{
public string Server { get; set; } = "smtp.gmail.com"; //Gmail limited to 2000 emails per day
public int Port { get; set; } = 465; //default for SSL using GMail
public string User { get; set; } = "myEmail#gmail.com"; //must match server domain
public string Password { get; set; } = "myPwd";
public bool UseSsl { get; set; } = true; //gmail requires SSL
public bool RequiresAuthentication { get; set; } = true; //gmail requires authentication
public string PreferredEncoding { get; set; } = string.Empty;
}
and EmailSender.cs class:
public class EmailSender
{
public EmailSender()
{
}
public async Task SendEmailAsync(
SmtpOptions smtpOptions,
string to,
string from,
string subject,
string plainTextMessage,
string htmlMessage,
string replyTo = null)
{
if (string.IsNullOrWhiteSpace(to))
{
throw new ArgumentException("no to address provided");
}
if (string.IsNullOrWhiteSpace(from))
{
throw new ArgumentException("no from address provided");
}
if (string.IsNullOrWhiteSpace(subject))
{
throw new ArgumentException("no subject provided");
}
var hasPlainText = !string.IsNullOrWhiteSpace(plainTextMessage);
var hasHtml = !string.IsNullOrWhiteSpace(htmlMessage);
if (!hasPlainText && !hasHtml)
{
throw new ArgumentException("no message provided");
}
var m = new MimeMessage();
m.From.Add(new MailboxAddress("", from));
if (!string.IsNullOrWhiteSpace(replyTo))
{
m.ReplyTo.Add(new MailboxAddress("", replyTo));
}
m.To.Add(new MailboxAddress("", to));
m.Subject = subject;
//m.Importance = MessageImportance.Normal;
//Header h = new Header(HeaderId.Precedence, "Bulk");
//m.Headers.Add()
BodyBuilder bodyBuilder = new BodyBuilder();
if (hasPlainText)
{
bodyBuilder.TextBody = plainTextMessage;
}
if (hasHtml)
{
bodyBuilder.HtmlBody = htmlMessage;
}
m.Body = bodyBuilder.ToMessageBody();
using (var client = new SmtpClient())
{
await client.ConnectAsync(
smtpOptions.Server,
smtpOptions.Port,
smtpOptions.UseSsl)
.ConfigureAwait(false);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// Note: only needed if the SMTP server requires authentication
if (smtpOptions.RequiresAuthentication)
{
await client.AuthenticateAsync(smtpOptions.User, smtpOptions.Password)
.ConfigureAwait(false);
}
await client.SendAsync(m).ConfigureAwait(false);
await client.DisconnectAsync(true).ConfigureAwait(false);
}
}
public async Task SendMultipleEmailAsync(
SmtpOptions smtpOptions,
string toCsv,
string from,
string subject,
string plainTextMessage,
string htmlMessage)
{
if (string.IsNullOrWhiteSpace(toCsv))
{
throw new ArgumentException("no to addresses provided");
}
if (string.IsNullOrWhiteSpace(from))
{
throw new ArgumentException("no from address provided");
}
if (string.IsNullOrWhiteSpace(subject))
{
throw new ArgumentException("no subject provided");
}
var hasPlainText = !string.IsNullOrWhiteSpace(plainTextMessage);
var hasHtml = !string.IsNullOrWhiteSpace(htmlMessage);
if (!hasPlainText && !hasHtml)
{
throw new ArgumentException("no message provided");
}
var m = new MimeMessage();
m.From.Add(new MailboxAddress("", from));
string[] adrs = toCsv.Split(',');
foreach (string item in adrs)
{
if (!string.IsNullOrEmpty(item)) { m.To.Add(new MailboxAddress("", item)); ; }
}
m.Subject = subject;
m.Importance = MessageImportance.High;
BodyBuilder bodyBuilder = new BodyBuilder();
if (hasPlainText)
{
bodyBuilder.TextBody = plainTextMessage;
}
if (hasHtml)
{
bodyBuilder.HtmlBody = htmlMessage;
}
m.Body = bodyBuilder.ToMessageBody();
using (var client = new SmtpClient())
{
await client.ConnectAsync(
smtpOptions.Server,
smtpOptions.Port,
smtpOptions.UseSsl).ConfigureAwait(false);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// Note: only needed if the SMTP server requires authentication
if (smtpOptions.RequiresAuthentication)
{
await client.AuthenticateAsync(
smtpOptions.User,
smtpOptions.Password).ConfigureAwait(false);
}
await client.SendAsync(m).ConfigureAwait(false);
await client.DisconnectAsync(true).ConfigureAwait(false);
}
}
}
That are used in a function call:
public async void ContactMessage(string title, string message, string toEmail)
{
string thisMessage = "No Message Provided";
if (!String.IsNullOrEmpty(message)) { thisMessage = message; } //in case empty form
string thisTitle = title;
//create email objects
EmailSender emailSender = new EmailSender();
SmtpOptions smtpOptions = new SmtpOptions(); //default settings ok
string fromEmail = smtpOptions.User;
string subjectLine = "Message Title";
await emailSender.SendEmailAsync(smtpOptions, toEmail, fromEmail, subjectLine, thisMessage, "");
}
As stated, this method has worked before but now I'm getting a failure of Gmail to respond. I've checked and have IMAP and POP enabled.
The specific exception reads:
"System.Net.Internals.SocketExceptionFactory.ExtendedSocketE‌​xception: 'A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond'"
This code has not been deployed but causes this error in the test environment. Moving to a differently firewalled system causes the error "Mailkit.Security.Authentication; MailKit authentication is too weak"
Testing with Yahoo! smtp allows the above code to work so it seems like the compatibility between Mailkit and Gmail has changed. What is the appropriate Mailkit configuration for using Gmail?
The email account settings were not configured to allow use of less-secure apps. The two solutions are:
1) Obtain OAuth 2.0 credentials within the EmailSender.cs class, or
2) Change email account settings to allow less secure apps
There are more details at:
How to send email by using MailKit?
Generally, when you get an AuthenticationException saying that the AUTH mechanism was too weak, it means that the client tried to use the PLAIN or LOGIN mechanisms and the server only allows those mechanisms to be used over SSL.
Make sure you are connecting on port 465 with SSL enabled or on port 587 with SecureSocketOptions.StartTls as the third argument.

Basic Authentication with Retrofit

I am trying to build a client for a REST API using Retrofit. The API uses basic auth and I have been unable to authenticate using Retrofit.
I tested the API using the curl below and it works as expected
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{some_json}' -u api_key: https://apitest.com/api/v1/customers
Below is the Retrofit client
public interface UserService {
String HOST = "https://apitest.com";
public static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
public static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(HOST)
.addConverterFactory(GsonConverterFactory.create());
/*
* CREATE/UPDATE User
*/
#POST("api/v1/customers")
Call<UserAPIResponse> userUpdate(#Body UserUpdateRequest userUpdateRequest);
static UserService newInstance(String userAPIKey) {
String credentials = userAPIKey + ":";
final String basic = "Basic "+ Base64.encodeBase64(credentials.getBytes());
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
.header("Authorization", basic);
requestBuilder.header("Accept", "application/json");
requestBuilder.method(original.method(),original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
OkHttpClient client = httpClient.build();
Retrofit retrofit = builder.client(client).build();
return retrofit.create(BlueshiftUserService.class);
}
When I call updateUser on the UserService
Response<UserAPIResponse> response = UserService.userUpdate(userUpdateRequest).execute();
The response.code is 401 (unauthorized/authentication failed)
The curl command with -u and the same credentials works as expected.
The issue was with the credentials encoding. I wasnt sending it as string.
byte[] encodedAuth= Base64.encodeBase64(credentials.getBytes());
final String basic = "Basic " + new String(encodedAuth);
use these libraries in Gradle file
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.okhttp:okhttp:2.3.0'
compile 'com.cookpad.android.rxt4a:rxt4a:0.9.0'
compile 'io.reactivex:rxjava:1.0.12'
and put this classes in your project
public class ServiceGenerator {
private static final String TAG = erviceGenerator.class.getSimpleName();
public static final int READ_TIMEOUT = 10000;
public static final int CONNECT_TIMEOUT = 100000;
// No need to instantiate this class.
private ServiceGenerator(){}
public static <S> S createService(Class<S> serviceClass, String
endpoint) {
// Call basic auth generator method without user and pass
return createService(serviceClass, endpoint, null, null); }
public static <S> S createService(Class<S> serviceClass, String
endpoint, String username, String password) {
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
// Set endpoint url and use OkHTTP as HTTP client
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(endpoint)
.setConverter(new GsonConverter(new Gson()))
.setClient(new OkClient(okHttpClient));
if (username != null && password != null) {
// Concatenate username and password with colon for authentication
final String credentials = username + ":" + password;
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
// Create Base64 encoded string
String string = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
request.addHeader("Authorization", string);
request.addHeader("Accept", "application/json");
}
});
}
RestAdapter adapter = builder.build();
return adapter.create(serviceClass); } }
and this interface
public class TodolyClient {
private static final String TAG = TodolyClient.class.getSimpleName();
public static final String ENDPOINT = "your base URL";
public interface TodolyService {
#GET("/wp-json/wc/v2/products")(your remaining url)
Observable<Object> isAuthenticated();
}
}
and call the below method in your main activity
private void createProject() {
final TodolyClient.TodolyService service =ServiceGenerator.createService(
TodolyClient.TodolyService.class, TodolyClient.ENDPOINT, "your user name",
"your password");
Observable<Object> observable = service.isAuthenticated();
AndroidCompositeSubscription compositeSubscription = new AndroidCompositeSubscription();
observable
.lift(new OperatorAddToCompositeSubscription<Object>(compositeSubscription))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Object>() {
#Override
public void onNext(Object project) {
android.util.Log.d(TAG, "onNext: "+project.toString());
}
#Override
public void onCompleted() {
android.util.Log.d(TAG, "onNext:commm " );
}
#Override
public void onError(Throwable e) {
android.util.Log.d(TAG, "onNext: eeeeeeeee"+e.getMessage());
}
});
}
This is so far the easiest method i have ever tried for "Basic Authentication".
Use the below code to generate the auth header (API/Repository class), You can add any character set for encoding as the third parameter here.
var basic = Credentials.basic("YOUR_USERNAME", "YOUR_PASSWORD")
Pass this as header to the webservice call (API/Repository class)
var retrofitCall = myWebservice.getNewsFeed(basic)
Add the basic header as parameter (Retrofit Webservice interface class)
#GET("newsfeed/daily")
fun getNewsFeed(#Header("Authorization") h1:String):Call<NewsFeedResponse>
Sorry, my code is in Kotlin, but can be easily translated to Java.
References: https://mobikul.com/basic-authentication-retrofit-android/

Resources