Client.ExecuteAsync loses variable data before saving to database - c#

I have below code to send email to multiple email ids and am using RestSharp request and response with MailGun API
var emodel = model as EmailViewModel;
var context = HttpContext.Current;
var from = "KG <" + emodel.FromEmail[0] + ">";
var client = new RestClient
{
BaseUrl = new Uri("https://api.mailgun.net/v3"),
Authenticator = new HttpBasicAuthenticator("api", WebConfigurationManager.AppSettings["MGKey"])
};
foreach(var to in emodel.EmailID)
{
var request = new RestRequest();
request.AddParameter("domain",
"domain.com", ParameterType.UrlSegment);
request.Resource = "{domain}/messages";
request.AddParameter("from", from);
request.AddParameter("subject", emodel.Subject ? ? "No Subject");
var body = emodel.Message ? ? "Empty Message";
request.AddParameter("html", body);
request.Method = Method.POST;
request.AddParameter("to", to);
var json = new JavaScriptSerializer();
client.ExecuteAsync(request, r => {
var content = json.Deserialize<Dictionary<string,string >>(r.Content);
if (content != null && r.ResponseStatus == ResponseStatus.Completed && r.StatusCode == HttpStatusCode.OK)
{
msgId=content.msgID;
}
if (msgId != "")
{
using(_db = new DBcontext())
{
var message = new tblMsg {
MDSent = DateTime.Today.Date,
MMsg = WebUtility.HtmlEncode(emodel.Message),
MMsgStatus = EventTypes.Stored.ToString(),
MMsgType = true,
MSByID = from,
MSByUser = loggedInUser,
MSID = msgId,
MSub = emodel.Subject ? ? "No subject",
MToID = to
};
_db.Entry(message).State = EntityState.Added;
_db.SaveChanges();
}
}
else {
LogError.LogMessage(r.ErrorMessage, context);
}
});
}
EmailViewModel.cs
public class EmailViewModel
{
public string[] EmailID { get; set; }
public SelectList Emails { get; set; }
public string[] Names { get; set; }
public string Message { get; set; }
public string[] FromEmail { get; set; }
public SelectList FromEmails { get; set; }
public bool HasAttachment { get; set; }
public string AttachmentPath { get; set; }
public int AttachmentCount { get; set; }
public string Subject { get; set; }
}
The problem over here is when I send an email to multiple ids, because of client.ExecuteAsync line which is inside for-loop, it will fetch async response multiple times and store it in content and before message record saves into database, it gets replaced with the next async response from API and hence only one record gets saved in database. Is there any mechanism in C#, wherein I can hold variable message value until its saved to database? I tried using lock on content variable, but it did not help.. Hoping to find some help.

Related

Send post data to api in C#

I have this api in php that works ok when sending data from an html form.
<?php
include_once 'apiAppMovil.php';
$api = new AppMovil();
$error = '';
if(isset($_POST["nombre"]) && isset($_POST["ape"]) && isset($_POST["email"]) && isset($_POST["pass"])){
if($api->subirImagen($_FILES['foto'])){
$item = array(
"nombre" => $_POST["nombre"],
"ape" => $_POST["ape"],
"email" => $_POST["email"],
"pass" => $_POST["pass"],
"foto" => $api->getImagen() //Not used
);
$api->add($item);
}else{
$api->error('Error con el archivo: ' . $api->getError());
}
}
else{
$api->error('Error al llamar a la API');
}
?>
I want to send data but from c#. My class is the following:
public partial class Root
{
[JsonProperty("items")]
public Item[] Items { get; set; }
}
public partial class Item
{/*
[JsonProperty("id")]
[JsonConverter(typeof(ParseStringConverter))]
public long Id { get; set; }*/
[JsonProperty("nombre")]
public string Nombre { get; set; }
[JsonProperty("ape")]
public string Ape { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("pass")]
public string Pass { get; set; }
[JsonProperty("foto")] //Not Used
public string Foto { get; set; }
}
and my method is:
private async Task SignUpApiPost()
{
var data = new Item
{
Nombre = "Eric",
Ape = "Pino",
Pass = "M2022",
Email = "ericpinodiaz#gmail.com",
Foto = "default.jpeg" //Not Used
};
// Serialize our concrete class into a JSON String
var json = JsonConvert.SerializeObject(data);
// Wrap our JSON inside a StringContent which then can be used by the HttpClient class
var httpContent = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
var httpClient = new HttpClient();
// Do the actual request and await the response
var response = await httpClient.PostAsync("https://app.domainexample.com/rest/add.php", httpContent);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
//do thing
}
}
But I can't get the data to arrive, I have the errors "Error al llamar a la API" from Api php.
I think the problem is that var data = new Item{ is not declared correctly, can you help me and tell me where I am going wrong?
Thank you.
Edit:
I add the html with which it works correctly:
You should try something like the one below.
client.BaseAddress = new Uri("your url");
//HTTP POST
var postTask = client.PostAsJsonAsync<StudentViewModel>("your parameter name", Item);
postTask.Wait();
var result = postTask.Result;
if (result.IsSuccessStatusCode)
{
//do something
}

Unable to get Department Name ,Manager Name and getting only limited users in response In Microsoft Graph API C#

I am using below code to get all the users from Active Directory:
static async Task Main(string[] args)
{
int Flag = 0;
// var message = await result;
try
{
var tenantId = "XXXXX.onmicrosoft.com";
string searchCriteria = "";
string searchString = "";
string tokenUrl = $"https://login.microsoftonline.com/XXXXX.onmicrosoft.com/oauth2/v2.0/token";
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
//I am Using client_credentials as It is mostly recommended
tokenRequest.Content = new FormUrlEncodedContent(new System.Collections.Generic.Dictionary<string, string>
{
["grant_type"] = "client_credentials",
["client_id"] = "XXX9",
["client_secret"] = "XXXXXX",
["scope"] = "https://graph.microsoft.com/.default"
});
dynamic json;
AccessTokenClass results = new AccessTokenClass();
//New Block For Accessing Data from Microsoft Graph Rest API
HttpClient client = new HttpClient();
var tokenResponse = await client.SendAsync(tokenRequest);
json = await tokenResponse.Content.ReadAsStringAsync();
results = JsonConvert.DeserializeObject<AccessTokenClass>(json);
HttpClient _client = new HttpClient();
string urlGraphUsers = "https://graph.microsoft.com/v1.0/users?$top=999";
// odata_nextlink
do
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format(urlGraphUsers));
//Passing Token For this Request
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", results.access_token);
//unable to get department name in response
HttpResponseMessage response = await _client.SendAsync(request);
string responseBody = await response.Content.ReadAsStringAsync();
dynamic objGpraphUserList = JsonConvert.DeserializeObject<dynamic>(await response.Content.ReadAsStringAsync());
var apiResponse = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<jsonModel>(apiResponse);
urlGraphUsers = data.odata_nextLink;
foreach (valueModel r in data.value.ToList())
{
//Print all the fields ,but unable to get Reporting Manager name and Department
Console.WriteLine(r.displayName);
Console.WriteLine(r.mail);
}
if (Flag == 0)
{
await context.PostAsync($"No Search results found! Please Try again");
}
}
while (urlGraphUsers != null);
}
catch
{
await context.PostAsync($"Unknown Exception Occurred. Unable to search results!");
context.Done(true);
}
Console.WriteLine(Flag);
Console.WriteLine("Flag");
context.Done(true);
}
public class jsonModel
{
public string #odata_context { get; set; }
public string #odata_nextLink { get; set; }
public List<valueModel> value { get; set; }
}
public class valueModel
{
public List<string> businessPhones { get; set; }
public string displayName { get; set; }
public string givenName { get; set; }
public string jobTitle { get; set; }
public string mail { get; set; }
public string mobilePhone { get; set; }
public string officeLocation { get; set; }
public string preferredLanguage { get; set; }
public string surname { get; set; }
public string userPrincipalName { get; set; }
public string id { get; set; }
}
I am unable to get Department name in response .Obviously something like r.departmentName doesn't work here.
And i am only getting 100 users ,even though i use odata.nextlink while loop. This do while loop runs only one time and shows only 100 users . Value of data.odata_nextLink; in the first loop itself is null.
How to fetch all the users using pagination and also department name and manager name or directReports.
Please help, as i am beginner.
As far as I know, the user just has property department but not departmentName, you can refer to this document.
In you code, when you do the "deserialize" operation, you need to let it know the odata_nextLink refers to #odata.nextLink field in json response. So please modify your code as below:
public class jsonModel
{
[JsonProperty("#odata.context")]
public string odata_context { get; set; }
[JsonProperty("#odata.nextLink")]
public string odata_nextLink { get; set; }
public List<valueModel> value { get; set; }
}
After that, your code will work fine, the data.odata_nextLink will not be null.
Hope it helps~
I recommend to leverage Microsoft .NET SDKs to avoid reinventing the wheel. This should work using Microsoft.Graph.Beta nuget package. This due MS Graph V1 not supporting user manager expands.
private static async Task PrintUsersWithManager()
{
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
.WithClientSecret(clientSecret)
.Build();
var token = await app.AcquireTokenForClient(new[] { ".default" }).ExecuteAsync();
var graphServiceClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
async (message) =>
{
var result = await app.AcquireTokenForClient(new[] { ".default" }).ExecuteAsync();
message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
}
)
);
var page = await graphServiceClient.Users.Request()
.Expand(u => u.Manager)
.GetAsync();
var users = new List<User>();
users.AddRange(page);
while (page.NextPageRequest != null)
{
page = await page.NextPageRequest
.Expand(u => u.Manager)
.GetAsync();
users.AddRange(page);
}
foreach (var item in users)
{
Console.WriteLine(JsonConvert.SerializeObject(new
{
item.Id,
item.DisplayName,
item.Department,
Manager = item.Manager != null ? new
{
item.Manager.Id,
displayName = ((User)item.Manager).DisplayName
} : null
}));
}
}

How to send a message to a user with the same attachments that he sent me using VkNet?

I get a message from a user in a chatbot that contains an attachment in the form of a document. I need to identify this document, convert it and send it back. But first, I just need to send the same document to the sender. How can i do this?
var msg = Message.FromJson(new VkResponse(updates.Object));
try
{
if (msg.Attachments.Count > 0)
{
//
var attachment = msg.Attachments.First();
//
if (attachment.Type == typeof(Document))
{
var doc = attachment.Instance as Document;
var attachments = new List<MediaAttachment>{doc};
//attachments.Add(attachment);
_vkApi.Messages.Send(new MessagesSendParams
{
RandomId = new DateTime().Millisecond,
PeerId = msg.PeerId.Value,
Message = "true",
Attachments = attachments
});
return Ok("ok");
}
else
{
_vkApi.Messages.Send(new MessagesSendParams
{
RandomId = new DateTime().Millisecond,
PeerId = msg.PeerId.Value,
Message = "false"
});
return Ok("ok");
}
}
}
Class Updates.cs:
[Serializable]
public sealed class Updates
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("object")]
public JObject Object { get; set; }
[JsonProperty("group_id")]
public long GroupId { get; set; }
}

How to assign Room to an Event for meeting using Microsoft Graph API in a UWP App

I am calling the API for creating a meeting on a fixed date & time. I am using Microsoft Graph API for this. Here is the URL
var url = "https://graph.microsoft.com/v1.0/me/events";
I have taken care of the Authentication part and my code does the following thing to send the JSON response to the API
private async void sendInvites_Click(object sender, RoutedEventArgs e)
{
var httpClient = new System.Net.Http.HttpClient();
System.Net.Http.HttpResponseMessage response;
var url = "https://graph.microsoft.com/v1.0/me/events";
CIBC.Models.SendMeetingInvites.RootObject obj = new CIBC.Models.SendMeetingInvites.RootObject();
CIBC.Models.SendMeetingInvites.Location loc = new CIBC.Models.SendMeetingInvites.Location();
loc.displayName = GlobalVariables.MeetingRoomName;
//loc.RoomEmailAddress = GlobalVariables.meetingRoomEmailID.ToString();
obj.subject = "Maths";
CIBC.Models.SendMeetingInvites.Body body = new CIBC.Models.SendMeetingInvites.Body();
body.content = "Its a booking for follow up meeting";
body.contentType = "HTML";
obj.body = body;
List<CIBC.Models.SendMeetingInvites.Attendee> attens = new List<Models.SendMeetingInvites.Attendee>();
for(int i=0;i<GlobalVariables.NumberOfParticipant.Count;i++)
{
CIBC.Models.SendMeetingInvites.EmailAddress email = new CIBC.Models.SendMeetingInvites.EmailAddress();
CIBC.Models.SendMeetingInvites.Attendee atten = new CIBC.Models.SendMeetingInvites.Attendee();
email.address = GlobalVariables.NumberOfParticipant[i].ParticipantADdress;
atten.emailAddress = email;
atten.type = "Required";
attens.Add(atten);
}
CIBC.Models.SendMeetingInvites.Start start = new CIBC.Models.SendMeetingInvites.Start();
start.dateTime = GlobalVariables.sendMeetingInviteStartDate;
start.timeZone = "UTC";
obj.start = start;
CIBC.Models.SendMeetingInvites.End end = new CIBC.Models.SendMeetingInvites.End();
end.dateTime = GlobalVariables.sendMeetingInviteEndTime;
end.timeZone = "UTC";
obj.end = end;
obj.attendees = attens;
obj.location = loc;
string postBody = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
// var postBody1 = "{'Subject':'Testing Organizer - 12','Location':{'DisplayName':'Some place'}," +
//"'Start': {'DateTime': '2016-07-15T15:00:00.0000000', 'TimeZone':'UTC'}," +
//"'End': {'DateTime': '2016-07-15T15:30:00.0000000', 'TimeZone':'UTC'}," +
//"'Body':{'Content': 'This is a test of Grap API.', 'ContentType':'Text'}," +
//"'IsOrganizer':'False','Organizer':{'EmailAddress': " + "{'Address':'organizer#some.com'} }}";
// var requestString = #"{"subject":"My event","start":{"dateTime":"2017-09-25T07:44:27.448Z","timeZone":"UTC"},"end":{"dateTime":"2017-10-02T07:44:27.448Z","timeZone":"UTC"}}"";
var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, url);
//Add the token in Authorization header
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer",GlobalVariables.Token);
request.Content = new StringContent(postBody, UTF8Encoding.UTF8, "application/json");
response = await httpClient.SendAsync(request);
if (response.IsSuccessStatusCode)
{ }
// return await response.Content.ReadAsStringAsync();
else
{
}
//return "";
}
Here is the class file that I am using to pass to the HTTPResponse Message
namespace CIBC.Models.SendMeetingInvites
{
public class Body
{
public string contentType { get; set; }
public string content { get; set; }
}
public class Start
{
public DateTime dateTime { get; set; }
public string timeZone { get; set; }
}
public class End
{
public DateTime dateTime { get; set; }
public string timeZone { get; set; }
}
public class Location
{
public string displayName { get; set; }
//public string RoomEmailAddress { get; set; }
}
public class EmailAddress
{
public string address { get; set; }
public string name { get; set; }
}
public class Attendee
{
public EmailAddress emailAddress { get; set; }
public string type { get; set; }
}
public class RootObject
{
public string subject { get; set; }
public Body body { get; set; }
public Start start { get; set; }
public End end { get; set; }
public Location location { get; set; }
public List<Attendee> attendees { get; set; }
}
}
My requirement is to send a meeting invite to all the users and also mentioning the Room Details like Name& Email ID of the room.
I tried adding a RoomEmail address in the Request as under The Location class
public string RoomEmailAddress { get; set; }
When I tested this using Microsoft Graph Explorer website , i got the error message
{
"error": {
"code": "RequestBodyRead",
"message": "The property 'RoomEmailAddress' does not exist on type 'Microsoft.OutlookServices.Location'. Make sure to only use
property names that are defined by the type or mark the type as open
type.",
"innerError": {
"request-id": "1883d87d-a5d6-4357-a699-7c112da0e56b",
"date": "2017-09-26T12:03:50"
}
} }
How do I make sure that whenever I create a meeting request , I can assign a room to it?
Currently I am just able to pass DisplayName while sending the Request to the URL.
Once I remove the Email Address property (I added myself ), the code returns Success.
Any workarounds so that I can send the room email address also so that the room also receives a copy of the meeting invite ?
Add the room as an attendee with "type": "Resource". Then add the room's display name in the location property.

While trying to upload video using daily motion API i got this error "The request was aborted: The request was canceled."

i am using daily motion API for uploading videos from my application but when try to upload more than 2 MB sized video i get this error "The request was aborted: The request was canceled." and this error invoked by this line of code var responseBytes = client.UploadFile(uploadUrl, fileToUpload);
and this is my code which i am using to upload video
public static void Main(MyVideo video)
{
var accessToken = GetAccessToken();
Authorize(accessToken);
var fileToUpload = video.Path;
var uploadUrl = GetFileUploadUrl(accessToken);
var response = GetFileUploadResponse(fileToUpload, accessToken, uploadUrl);
var uploadedResponse = PublishVideo(response, accessToken);
}
public class UploadResponse
{
public string format { get; set; }
public string acodec { get; set; }
public string vcodec { get; set; }
public int duration { get; set; }
public int bitrate { get; set; }
public string dimension { get; set; }
public string name { get; set; }
public int size { get; set; }
public string url { get; set; }
public string hash { get; set; }
public string seal { get; set; }
public override string ToString()
{
var flags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
System.Reflection.PropertyInfo[] infos = this.GetType().GetProperties(flags);
StringBuilder sb = new StringBuilder();
string typeName = this.GetType().Name;
sb.AppendLine(typeName);
sb.AppendLine(string.Empty.PadRight(typeName.Length + 5, '='));
foreach (var info in infos)
{
object value = info.GetValue(this, null);
sb.AppendFormat("{0}: {1}{2}", info.Name, value != null ? value : "null", Environment.NewLine);
}
return sb.ToString();
}
}
private static UploadResponse GetFileUploadResponse(string fileToUpload, string accessToken, string uploadUrl)
{
// ServicePointManager.DefaultConnectionLimit = 900000;
//HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(uploadUrl);
//wr.KeepAlive = false;
//wr.Timeout = System.Threading.Timeout.Infinite;
//wr.ProtocolVersion = HttpVersion.Version10;
var client = new WebClient();
client.Headers.Add("Authorization", "OAuth " + accessToken);
var responseBytes = client.UploadFile(uploadUrl, fileToUpload);
var responseString = Encoding.UTF8.GetString(responseBytes);
var response = JsonConvert.DeserializeObject<UploadResponse>(responseString);
return response;
}
and i have already tried al the possible solutionsu provided on Stackoverflow earlier also done with http execution time and we client time out but not working please someone help me

Categories