Notification hub device registration with installation - xamarin.forms

After reading this I've been trying to create an installation in my xamarin.android app but I keep getting an 'Unauthorized error' I feel that I'm missing something. Any help is appreciated.
Previously I was able to register with the hub using
var regID = hub.Register(token, tags.ToArray()).RegistrationId;
so I'm sure my hub has been setup correctly and that I am using the correct connectionstring.
My installation object
install.installationId = installationId; //guid
install.tags = Tags;
install.platform = "gcm";
install.pushChannel = token; //refresh token from fcm
Call to Create installation
private async Task<HttpStatusCode> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation,
string hubName, string listenConnectionString)
{
if (deviceInstallation.installationId == null)
return HttpStatusCode.BadRequest;
// Parse connection string (https://msdn.microsoft.com/library/azure/dn495627.aspx)
ConnectionStringUtility connectionSaSUtil = new ConnectionStringUtility(listenConnectionString);
string hubResource = "installations/" + deviceInstallation.installationId + "?";
string apiVersion = "api-version=2015-04";
// Determine the targetUri that we will sign
string uri = connectionSaSUtil.Endpoint + hubName + "/" + hubResource + apiVersion;
//=== Generate SaS Security Token for Authorization header ===
// See, https://msdn.microsoft.com/library/azure/dn495627.aspx
string SasToken = connectionSaSUtil.getSaSToken(uri, 60);
using (var httpClient = new HttpClient())
{
string json = JsonConvert.SerializeObject(deviceInstallation);
httpClient.DefaultRequestHeaders.Add("Authorization", SasToken);
var response = await httpClient.PutAsync(uri, new StringContent(json, System.Text.Encoding.UTF8, "application/json"));
return response.StatusCode;
}
}

Related

using Cloud Firestore Database API to create cloud firestore database with`database_id` of '(default)' not working

I used Google.Apis.Firestore.v1 library to create a cloud firestore for my firebase project as follows, but when running my code I am getting an error related to the database naming I guess, and it has a regular expression format as shown in the error below, and how can I fix this issue?
using Google.Apis.Firestore.v1;
private static FirestoreService _firestoreService;
public static void IntializeFirestoreAdmin() {
GoogleCredential credential = GoogleCredential.GetApplicationDefault();
if (CloudManager.Credential.IsCreateScopedRequired)
{
credential = CloudManager.Credential.CreateScoped(FirestoreService.Scope.CloudPlatform);
}
_firestoreService = new FirestoreService(
new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = CloudManager.ApplicationName
});
}
public static void AddCloudFirestore() {
IntializeFirestoreAdmin();
var mydata = new GoogleFirestoreAdminV1Database {
LocationId = "nam5",
Type = "FIRESTORE_NATIVE",
Name = "projects/" + CloudManager.ProjectId + "/databases/(default)",
};
_firestoreService.Projects.Databases.Create(mydata, "projects/" + CloudManager.ProjectId).Execute();
}
Error :
Unhandled exception. The service firestore has thrown an exception.
HttpStatusCode is BadRequest.
Google.Apis.Requests.RequestError
database_id should be 4-63 characters, and valid characters are /[a-z][0-9]-/ [400]
Errors [
Message[database_id should be 4-63 characters, and valid characters are /[a-z][0-9]-/] Location[ - ] Reason[badRequest] Domain[global]
]
Google.GoogleApiException: The service firestore has thrown an exception. HttpStatusCode is BadRequest. database_id should be 4-63 characters, and valid characters are /[a-z][0-9]-/
at Google.Apis.Requests.ClientServiceRequest`1.ParseResponse(HttpResponseMessage response)
at Google.Apis.Requests.ClientServiceRequest`1.Execute()
If you go through the given method :
FirestoreService().Projects.Databases.Create it has parent as Parameter and databaseId as a Query parameter there is also a try this method section where you can verify your parameters are correct like for example :
using Google.Apis.Firestore.v1;
private static FirestoreService _firestoreService;
public static void IntializeFirestoreAdmin() {
GoogleCredential credential = GoogleCredential.GetApplicationDefault();
if (CloudManager.Credential.IsCreateScopedRequired)
{
credential = CloudManager.Credential.CreateScoped(FirestoreService.Scope.CloudPlatform);
}
_firestoreService = new FirestoreService(
new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = CloudManager.ApplicationName
});
}
public static void AddCloudFirestore() {
IntializeFirestoreAdmin();
var mydata = new GoogleFirestoreAdminV1Database {
LocationId = "nam5",
Type = "FIRESTORE_NATIVE",
Name = "projects/" + CloudManager.ProjectId + "/databases/my-database",
};
_firestoreService.Projects.Databases.Create(mydata, "projects/" + CloudManager.ProjectId).Execute();
}
var body = new GoogleFirestoreAdminV1Database
{
Type = "FIRESTORE_NATIVE",
LocationId = "nam5"
};
string parent = $"projects/{CloudManager.ProjectId}";
var request = _firestoreService.Projects.Databases.Create(body, parent);
request.DatabaseId = "(default)";
var response = request.Execute();
The issue was that I didn't add the databaseId as a query parameter. For more details go to this link https://groups.google.com/g/google-cloud-firestore-discuss/c/EQ-04MnPyLk

How to write to csv file and attach it to email using Mail kit - Dotnet 6.0?

I want to know how to write my response - filtered Response to a csv file and attach it to an email using Mail kit. I can send an email with a body but I am unable to add an attachment.
//My Object
var result = await _thunderheadReportRepository.GetMembershipOfferDetailsAsync(searchDate, cancellationToken);
var filteredResponse = result.Select(o => new MembershipOfferDetailsResponse { CreationDate = o.CreationDate!, CorrelationId = o.CorrelationId!, PolicyCode = o.PolicyCode!, AnnualPremium = o.AnnualPremium! }).ToList();
return filteredResponse;
//My email body
var emailMessage = new MimeMessage();
emailMessage.From.Add(new MailboxAddress("email", _appSettings.EmailConfiguration.From));
emailMessage.To.AddRange(message.To);
emailMessage.Subject = message.Subject;
var bodybuilder = new BodyBuilder { HtmlBody = string.Format("<h2 style='color:red'>{0}</h2>", message.Content) };
emailMessage.Body = bodybuilder.ToMessageBody();
return emailMessage;
You just need to call:
bodyBuilder.Attachments.Add ("filename.csv");

Oauth 401 Error invalid signature when requesting to woocommerce rest api with httpclient .net core

First of all I know I can use trusted libraries to generate oAuth header signature but I spent a lot of time to generate this signature and I want to know why it's not working.
I have ConsumerKey and ConsumerSecret to access woocommerce rest api.
I write a method to generate BaseSignatureString and another method to get HMAC-SHA1 :
public static string GetoAuthToken(string conKey, string conSecret)
{
string timestamp = ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString();
string nonce = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(timestamp
+ timestamp + timestamp));
var signatureBaseString = "GET&" + Uri.EscapeDataString("https://loomina.ir/wp-json/wc/v3/products") + "&";
signatureBaseString += Uri.EscapeDataString($"oauth_consumer_key={conKey}&");
signatureBaseString += Uri.EscapeDataString($"oauth_nonce={nonce}&");
signatureBaseString += Uri.EscapeDataString($"oauth_signature_method=HMAC-SHA1&");
signatureBaseString += Uri.EscapeDataString($"oauth_timestamp={timestamp}&");
signatureBaseString += Uri.EscapeDataString($"oauth_version=1.0");
string SHA1HASH = GetSha1Hash(conSecret + "&" , signatureBaseString);
string Header = $"oauth_consumer_key=\"{conKey}\",oauth_timestamp=\"{timestamp}\",oauth_signature_method=\"HMAC-SHA1',oauth_nonce=\"{nonce}\",oauth_version=\"1.0\",oauth_signature=\"{SHA1HASH}\"";
return Header;
}
Get SHA1 Hash :
public static string GetSha1Hash(string key, string baseSignatureString)
{
var encoding = new ASCIIEncoding();
byte[] keyBytes = encoding.GetBytes(key);
byte[] messageBytes = encoding.GetBytes(baseSignatureString);
string Sha1Result = string.Empty;
using (HMACSHA1 SHA1 = new HMACSHA1(keyBytes))
{
var Hashed = SHA1.ComputeHash(messageBytes);
Sha1Result = Convert.ToBase64String(Hashed);
}
return Sha1Result;
}
Request part :
var oAuthSignature = Utility.GetoAuthToken(websites.CustomerKey, websites.CustomerSecret);
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OAuth", oAuthSignature);
var response = await _client.GetAsync($"{websites.Url}/wp-json/wc/v3/products/");
var result = await response.Content.ReadAsStringAsync();
The status of request is 401 Not Authorized (Invalid signature)

The request was missing an Authentication Key. Please, refer to section "Authentication" with IHttpClientFactory

I'm trying to send an HTTP request from .NET Core 3.1 REST API to another API but below Exception keep appeared Although I'm already added the Authentication Key :
The request was missing an Authentication Key. Please, refer to section "Authentication"
here is my code :
public class AppService
{
private readonly IHttpClientFactory _clientFactory;
string key = "key=llllll ......";
string webAPIKey = "......";
string Id = "......";
public AppService(IHttpClientFactory clientFactory) {
_clientFactory = clientFactory;
}
public async Task<string> sendBroadCastNotification()
{
Data _data = new Data();
_data.title = "test data Ttile";
_data.detail = "test data detail";
Notification _notification = new Notification();
_notification.title = "test notification Ttile";
_notification.body = "test notification body";
MyNotification NotifcationData = new MyNotification {
data=_data,
notification=_notification,
to= "/topics/all"
};
try {
var client = _clientFactory.CreateClient();
client.DefaultRequestHeaders.Add("project_id", Id );
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", key);
StringContent bodyOfRequest = new StringContent(System.Text.Json.JsonSerializer.Serialize(NotifcationData ), Encoding.UTF8, "application/json");
using var httpResponse =
await client.PostAsync("https://.......", bodyOfRequest);
var result = httpResponse.Content.ReadAsStringAsync().Result;
return result;
}
catch (Exception ex)
{
throw new System.ArgumentException(ex.Message.ToString(), "original");
}
//return null;
}
}
I found the answer here in this link:
I add the key by using the below line:
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", key);
the below way that I was trying to add the authorization header wasn't understandable as an authorization header :
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", key);

Xamarin Forms HttpClient Multipart/FormData returns 403 Forbidden

I'm trying to make chat app with XamarinForms and I'm trying to upload a file with parameters to server. But I'm getting always 403 Forbidden message. (There is no authentication, there is only token key for now).
If I try to get or send any data to server, it works as well. When I try to send a file with data it returns 403 Forbidden message. I also tried to send same data with Postman. it's worked as well. I'm writing part of code, Could you please tell me, I made it wrong where?
Thanks in advance.
private async Task<HttpClient> GetClient()
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("X-Token-Key", ServiceToken);
client.DefaultRequestHeaders.UserAgent.Add(new System.Net.Http.Headers.ProductInfoHeaderValue("Chrome", "41.0.2228.0"));
return client;
}
If I send text message, it works as well.
public async Task<MobileResult> SendConversationTextMessage(MessageModel message)
{
HttpClient client = await GetClient();
string param = JsonConvert.SerializeObject(message);
var response = await client.PostAsync(Url + "conversation/message_add_text", new StringContent(param, Encoding.UTF8, "application/json"));
var mobileResult = JsonConvert.DeserializeObject<MobileResult>(await response.Content.ReadAsStringAsync());
return mobileResult;
}
If I send message with data, it returns 403 Forbidden
public async Task<MobileResult> SendConversationFileMessage(
FileModel FileMessage,
int UserRemoteId,
int ConversationId,
int ToUserId,
string SendedTime,
MessageModel.MessageType Type,
MessageModel.MessageStatus Status,
string MessageType)
{
HttpClient client = await GetClient();
string PostUrl = Url + "conversation/message_add_" + MessageType;
MultipartFormDataContent content = new MultipartFormDataContent();
ByteArrayContent baContent = new ByteArrayContent(FileMessage.BinaryData);
StringContent UserIdContent = new StringContent(UserRemoteId.ToString());
StringContent ConversationIdContent = new StringContent(ConversationId.ToString());
StringContent ToUserIdContent = new StringContent(ToUserId.ToString());
StringContent SendedTimeContent = new StringContent(SendedTime.ToString());
StringContent TypeContent = new StringContent(Type.ToString());
StringContent StatusContent = new StringContent(Status.ToString());
content.Add(baContent, "AttachedFile", FileMessage.Name);
content.Add(UserIdContent, "serId");
content.Add(ConversationIdContent, "ConversationId");
content.Add(ToUserIdContent, "ToUserId");
content.Add(SendedTimeContent, "SendedTime");
content.Add(TypeContent, "Type");
content.Add(StatusContent, "Status");
try
{
var response = await client.PostAsync(PostUrl, content);
string result = await response.Content.ReadAsStringAsync();
var mobileResult = JsonConvert.DeserializeObject<MobileResult>(result);
return mobileResult;
}
catch (Exception e)
{
return new MobileResult
{
Result = false,
Data = null,
Message = e.ToString()
};
}
}
Postman-Screenshot
Edit: I've tested to send multipart/form-data different way but result is same I'm writing below code:
MultipartFormDataContent content = new MultipartFormDataContent();
var UserIdContent = new StringContent(UserId.ToString());
UserIdContent.Headers.Add("Content-Disposition", "form-data; name=\"UserId\"");
UserIdContent.Headers.Remove("Content-Type");
content.Add(UserIdContent, "UserId");
var ConversationIdContent = new StringContent(ConversationId.ToString());
ConversationIdContent.Headers.Add("Content-Disposition", "form-data; name=\"ConversationId\"");
ConversationIdContent.Headers.Remove("Content-Type");
content.Add(ConversationIdContent, "ConversationId");
var ToUserIdContent = new StringContent(ToUserId.ToString());
ToUserIdContent.Headers.Add("Content-Disposition", "form-data; name=\"ToUserId\"");
ToUserIdContent.Headers.Remove("Content-Type");
content.Add(ToUserIdContent, "ToUserId");
var SendedTimeContent = new StringContent(SendedTime.ToString());
SendedTimeContent.Headers.Add("Content-Disposition", "form-data; name=\"SendedTime\"");
SendedTimeContent.Headers.Remove("Content-Type");
content.Add(SendedTimeContent, "SendedTime");
var TypeContent = new StringContent(Type.ToString());
TypeContent.Headers.Add("Content-Disposition", "form-data; name=\"Type\"");
TypeContent.Headers.Remove("Content-Type");
content.Add(TypeContent, "Type");
var StatusContent = new StringContent(Status.ToString());
StatusContent.Headers.Add("Content-Disposition", "form-data; name=\"Status\"");
StatusContent.Headers.Remove("Content-Type");
content.Add(StatusContent, "Status");
var streamContent = new StreamContent(file.InputStream);
streamContent.Headers.Add("Content-Disposition", "form-data; name=\"AttachedFile\"; filename=\"" + file.FileName + "\"");
streamContent.Headers.Add("Content-Type", "video/mp4");
content.Add(streamContent, "AttachedFile", file.FileName);

Resources