How to send a notification to the OneSignal API with flurl - .net-core

I'm trying to send some data using the example in the page of onesignal
var request = WebRequest.Create("https://onesignal.com/api/v1/notifications") as HttpWebRequest;
request.KeepAlive = true;
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
request.Headers.Add("authorization", "Basic xxx");
var obj = new
{
app_id = "xxx",
contents = new { en = "English Message" },
included_segments = new string[] { "Active Users" }
};
var param = JsonConvert.SerializeObject(obj);
byte[] byteArray = Encoding.UTF8.GetBytes(param);
This coded works fine, but I'm using Flurl to make a request to onesignal like this:
var body = new
{
app_id = "xxx",
contents = new
{
es = "Mensaje prueba"
},
included_segments = new string[] { "All" }
};
string param = JsonConvert.SerializeObject(body);
var content = new System.Net.Http.ByteArrayContent(Encoding.UTF8.GetBytes(param));
var response = await new Flurl.Url(urlbase)
.AppendPathSegment("notifications")
.WithHeader("Content-Type", "application/json; charset=utf-8")
.WithHeader("Authorization", "Basic xxx")
.PostAsync(content)
.ReceiveString();
but I'm getting the "Bad request". Please someone could help to point how to make the same call with Flurl?

As mentioned in the first comment, you're doing more work than you need to. Flurl will serialize body for you, so remove these lines:
string param = JsonConvert.SerializeObject(body);
var content = new System.Net.Http.ByteArrayContent(Encoding.UTF8.GetBytes(param));
And post body directly using PostJsonAsync:
var response = await urlbase
...
.PostJsonAsync(body)
.ReceiveString();

Related

StatusCode error 500 when sending a POST resquest in XF

I'm writing an API in EF to send FCM notifications:
[HttpPost]
public void PushNotificationToFCM(string deviceTokens, string title, string body, object data, string linkdirection)
{
...
// 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 tried on Postman or Swagger everything works fine.
I proceed to write the send command in XF:
.xaml.cs
protected async void SendFirebase()
{
string devicetoken = listDeviceID.deviceidphone;
string titlefirebase = "Title";
string bodyfirebase = "Description";
string linkfirebase = "https://applink/..";
await _apiService.AddNotifyFirebase(devicetoken, titlefirebase, bodyfirebase, linkfirebase);
}
public async Task AddNotifyFirebase(string devicetoken, string titlefirebase, string bodyfirebase, string linkfirebase)
{
var model = new
{
devicetoken = devicetoken,
titlefirebase = titlefirebase,
bodyfirebase = bodyfirebase,
linkfirebase = linkfirebase,
};
var json = JsonConvert.SerializeObject(model);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var request = new HttpRequestMessage(HttpMethod.Post, "https://linkapi/api/SendNotifyDeviceFirebase");
request.Content = content;
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var responseBody = await response.Content.ReadAsStringAsync();
}
}
However I get the error: StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.NSUrlSessionHandler+NSUrlSessionDataTaskStreamContent, ....
Where did I go wrong? Looking forward to everyone's help. Thank you!
Update
I check on Swagger:
Everything seems fine!
I then changed the send command back:
public async Task AddNotifyFirebase(string devicetoken, string titlefirebase, string bodyfirebase, string linkfirebase)
{
var request = new HttpRequestMessage(HttpMethod.Post, "https://xxxxxx/api/SendNotifyDeviceFirebase?deviceTokens=" + devicetoken + "&title=" + titlefirebase + "&body=" + bodyfirebase + "&linkdirection=" + linkfirebase);
//request.Headers.Add("Accept-Encoding", "gzip");
//request.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain; charset=utf-8");
HttpResponseMessage response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var responseBody = await response.Content.ReadAsStringAsync();
}
}
I get the error again: StatusCode: 415, ReasonPhrase: 'Unsupported Media Type'
I have handled the problem. Thank you all
public async Task AddNotifyFirebase(NotifyFireBase NotifyFireBaseAdd)
{
var urlput = "......";
HttpClient client = new HttpClient();
var content = NotifyFireBaseAdd;
var stringContent = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
await client.PostAsync(urlput, stringContent);
}

How can I make proper request for the Identity Server Token Endpoint?

I tried to send an api call to the identity server via .net 6 console application.
Here is the request:
public static async Task<WorkflowResponse> PostRequestToIdentityAsync()
{
var url = "http://didentity/connect/token";
IdentityRequestDataVM identityRequestDataVM = new IdentityRequestDataVM();
identityRequestDataVM.username = "csm";
identityRequestDataVM.password = "MjAyMjox";
identityRequestDataVM.grant_type = "password";
identityRequestDataVM.scope = "m_gln m_msd";
string jsonString = JsonConvert.SerializeObject(identityRequestDataVM);
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(url),
Content = new StringContent(jsonString),
Headers =
{
{"X-Login","override"}
}
};
var user = "gclt";
var password = "glsrt";
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{user}:{password}")));
HttpResponseMessage message = await httpClient.SendAsync(request);
if (message.StatusCode == System.Net.HttpStatusCode.OK)
{
var contents = await message.Content.ReadAsStringAsync();
WorkflowResponse workflowResponse = JsonConvert.DeserializeObject<WorkflowResponse>(contents);
return workflowResponse;
}
else
{
throw new Exception(await message.Content.ReadAsStringAsync());
}
}
}
But, it returned 400 err code (Bad request), is there any mistake in the code snippet ?
It is working fine with postman.

How to send file with HttpClient post in xamarin forms

I want to send file through post request using httpclient
this what i tried but file didn't sent , when i tried in postman it works fine
string Url = $"http://ataprojects.net/test/products.php?request_type=add&company_name={BaseService.Company}&name={product.name}&barcode={product.barcode}&buy_price={product.buy_price}&sell_price={product.sell_price}";
try
{
using (HttpClient client = new HttpClient())
{
var content = new MultipartFormDataContent();
content.Headers.ContentType.MediaType = "multipart/form-data";
content.Add(new StreamContent(product._mediaFile.GetStream()),
"image",
product.image);
var response = client.PostAsync(Url, content).Result;
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
var contentdata = await response.Content.ReadAsStringAsync();
var Items = JsonConvert.DeserializeObject<AddProductReturnModel>(contentdata);
return Items;
}
else
{
return null;
}
}
}
what's the problem ?
Try This Code
var content = new MultipartFormDataContent();
content.Add(new StreamContent(product._mediaFile.GetStream()),
"\"file\"",
$"\"{product._mediaFile.Path}\"");

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);

Code header.add not working in .net core

How to add the header in the WebRequest .
HttpWebRequest tRequest = (HttpWebRequest)WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "POST";
tRequest.ContentType = "application/json";
var data = new
{
to = devicesId,
notification = new
{
body = "Fcm Test Notification",
title = "Test FCM",
sound = "Enabled"
},
priority = "high"
};
tRequest.Headers["Authorization: key={0}"] = appId;
tRequest.Headers["Sender: id={0}"] = senderId;
i need to add the header to create the web Request.
Thanks
Missing Add in HttpWebRequest is because have missing ISerializable in CoreFx (so you can not simply tRequest.Headers.Add("name", "value");). They working on it and you can follow at https://github.com/dotnet/corefx/issues/12669

Resources