MS Graph SendMail with attachment - microsoft-graph-api

I have problem to send an email with attachment.
Without attachment it works.
If I use the same function and add an attachment to the message I get the following error message:
Code: ErrorRequiredPropertyMissing Message: Required property is missing. ClientRequestId: 2af....
I am using MS Graph v4.0.30319
What am I doing wrong
public static async Task<String> SendMyMailAsync()
{
try
{
var FromSender = new Microsoft.Graph.Recipient()
{
EmailAddress = new Microsoft.Graph.EmailAddress
{
Address = "EarlyBird#mail.com"
}
};
byte[] contentBytes = System.IO.File.ReadAllBytes(#"C:\Users\me\Desktop\Test.pdf");
String bs64 = Convert.ToBase64String(contentBytes);
var attachment = new FileAttachment
{
AdditionalData = new Dictionary<string, object>()
{
{"#odata.type","#microsoft.graph.fileAttachment"}
},
//ODataType = "#microsoft.graph.fileAttachment",
ContentType = "application/pdf",
Name = "Test.pdf",
ContentBytes = Convert.FromBase64String(bs64),
IsInline = false,
Size = bs64.Length,
ContentId = "TestMail",
LastModifiedDateTime = DateTime.Now,
Id = "HSDJHEWuDSjfkkfGt",
};
Microsoft.Graph.Message message = new Microsoft.Graph.Message
{
Sender = FromSender,
From = FromSender,
Subject = "Mail no1",
Importance = Microsoft.Graph.Importance.Normal,
Body = new Microsoft.Graph.ItemBody
{
ContentType = Microsoft.Graph.BodyType.Html,
Content = "Hello World",
},
ToRecipients = new List<Microsoft.Graph.Recipient>()
{
new Microsoft.Graph.Recipient
{
EmailAddress = new Microsoft.Graph.EmailAddress
{
Address = "EarlyBird#MailNo2.com"
}
}
},
Attachments = new MessageAttachmentsCollectionPage(),
};
// -- If I comment this out I can send the mail without error but without attachment----
message.Attachments.Add(attachment);
message.HasAttachments = true;
//-----------------------------------------------------------------
var request = graphClient.Me.SendMail(message, true);
// Messages[message.Id].Send();// SendMail(message, null);
await request.Request().PostAsync();
return "Mail send OK";
}
catch (ServiceException ex)
{
Console.WriteLine($"Error getting events: {ex.Message}");
return "Send mail error";
}
}

The below code works perfectly fine for me
public static async Task<String> SendMyMailAsync()
{
try
{
var FromSender = new Microsoft.Graph.Recipient()
{
EmailAddress = new Microsoft.Graph.EmailAddress
{
Address = "Shiva#nishantsingh.live"
}
};
byte[] contentBytes = System.IO.File.ReadAllBytes(#"C:\Users\Shiva\Desktop\sample.pdf");
String bs64 = Convert.ToBase64String(contentBytes);
var attachment = new FileAttachment
{
AdditionalData = new Dictionary<string, object>()
{
{"#odata.type","#microsoft.graph.fileAttachment"}
},
ContentType = "application/pdf",
Name = "Test.pdf",
ContentBytes = Convert.FromBase64String(bs64),
IsInline = false,
Size = bs64.Length,
ContentId = "TestMail",
LastModifiedDateTime = DateTime.Now,
Id = "HSDJHEWuDSjfkkfGt",
};
Microsoft.Graph.Message message = new Microsoft.Graph.Message
{
Sender = FromSender,
From = FromSender,
Subject = "Mail no1",
Importance = Microsoft.Graph.Importance.Normal,
Body = new Microsoft.Graph.ItemBody
{
ContentType = Microsoft.Graph.BodyType.Html,
Content = "Hello World",
},
ToRecipients = new List<Microsoft.Graph.Recipient>()
{
new Microsoft.Graph.Recipient
{
EmailAddress = new Microsoft.Graph.EmailAddress
{
Address = "Shiva#nishantsingh.live"
}
}
},
Attachments = new MessageAttachmentsCollectionPage(),
};
message.HasAttachments = true;
message.Attachments.Add(attachment);
var request = graphClient.Me.SendMail(message, true);
await request.Request().PostAsync();
return "Mail send OK";
}
catch (ServiceException ex)
{
Console.WriteLine($"Error getting events: {ex.Message}");
return "Send mail error";
}
}
You need to make sure that you have the PDF file path correctly specified and the fromSender variable will obviously be yours as you are calling me/sendMail. If you want to send mail from other user's mailbox then you need to have client credential flow setup so that it can give you an App-only token which should have required permissions and you need to change the call something like this var request = graphClient.Users["userid/UPN"].SendMail(message, true);.

I have just updated the MS Graph preview version from
4.0.0-preview.1
to
4.0.0-preview.2
Now everything works as expected
I think it was a bug in preview.1

Related

How to change email file's extension?

I am using this class to send an email with a PDF attachment. The class has the following code:
using System.IO;
using System.Net;
using System.Net.Mail;
using DevExpress.XtraPrinting;
using DevExpress.XtraReports.Web.WebDocumentViewer;
using DevExpress.XtraReports.Web.WebDocumentViewer.DataContracts;
namespace DocumentOperationServiceSample.Services
{
public class CustomDocumentOperationService : DocumentOperationService {
public override bool CanPerformOperation(DocumentOperationRequest request)
{
return true;
}
public override DocumentOperationResponse PerformOperation(DocumentOperationRequest request, PrintingSystemBase initialPrintingSystem, PrintingSystemBase printingSystemWithEditingFields)
{
using (var stream = new MemoryStream()) {
printingSystemWithEditingFields.ExportToPdf(stream);
stream.Position = 0;
var mailAddress = new MailAddress(request.CustomData);
var recipients = new MailAddressCollection() { mailAddress };
var attachment = new Attachment(stream, System.Net.Mime.MediaTypeNames.Application.Pdf);
return SendEmail(recipients, "Enter_Mail_Subject", "Enter_Message_Body", attachment);
}
}
DocumentOperationResponse SendEmail(MailAddressCollection recipients, string subject, string messageBody, Attachment attachment) {
string SmtpHost = null;
int SmtpPort = -1;
if (string.IsNullOrEmpty(SmtpHost) || SmtpPort == -1) {
return new DocumentOperationResponse { Message = "Please configure the SMTP server settings." };
}
string SmtpUserName = "Enter_Sender_User_Account";
string SmtpUserPassword = "Enter_Sender_Password";
string SmtpFrom = "Enter_Sender_Address";
string SmtpFromDisplayName = "Enter_Sender_Display_Name";
using (var smtpClient = new SmtpClient(SmtpHost, SmtpPort))
{
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.EnableSsl = true;
if (!string.IsNullOrEmpty(SmtpUserName))
{
smtpClient.Credentials = new NetworkCredential(SmtpUserName, SmtpUserPassword);
}
using (var message = new MailMessage())
{
message.Subject = subject.Replace("\r", "").Replace("\n", "");
message.IsBodyHtml = true;
message.Body = messageBody;
message.From = new MailAddress(SmtpFrom, SmtpFromDisplayName);
foreach (var item in recipients)
{
message.To.Add(item);
}
try
{
if (attachment != null)
{
message.Attachments.Add(attachment);
}
smtpClient.Send(message);
return new DocumentOperationResponse
{
Succeeded = true,
Message = "Mail was sent successfully"
};
}
catch (SmtpException e)
{
return new DocumentOperationResponse
{
Message = "Sending an email message failed."
};
}
finally
{
message.Attachments.Clear();
}
}
}
}
protected string RemoveNewLineSymbols(string value)
{
return value;
}
}
}
It works fine, but when I receive the email it has attached an document named application/pdf.
I was trying to find out where the document's name comes from. As you can see in the below image, when I add the application type PDF, it appears exactly what I get attached in email.
The problem is that application/pdf cannot be opened with any PDF viewer app. I have to rename the document to application.pdf in order to be able to open it. Is there a way to change application/pdf with application.pdf?
If anyone is looking for the answer:
var attachment = new Attachment(stream, "report.pdf ", System.Net.Mime.MediaTypeNames.Application.Pdf);

how to Send payment to Custom payee in paypal using c# asp.net?

I am building a ecommerce c# mvc Asp.net app where i want that payer can pay on different accounts from which he/she has bought item.
I want to send payment from payer to custom payee i have used paypal.api sdk i added payee in it but it gives error i.e " exception detail :{"name":"MALFORMED_REQUEST","message":"Incoming JSON request does not map to API"
//// Pyapal.api sdk use
public PaypalHelper CreatePayment(CreatePaymentHelper helper)
{
var apiContext = GetApiContext();
string ProfileId = GetWebProfile(apiContext, helper.ExperienceProfileName).id;
//ItemList itemList = new ItemList();
//foreach (var i in helper.Items)
//{
// Item item = new Item()
// {
// description = i.Description,
// currency = i.Currency,
// quantity = i.Quantity.ToString(),
// price = i.Price.ToString(), /// decimal strng
// };
// itemList.items.Add(item);
//}
var payment = new Payment()
{
experience_profile_id = ProfileId,
intent = "order",
payer = new Payer()
{
payment_method = "paypal"
},
transactions = new List<Transaction>()
{
new Transaction()
{
description = helper.TransactionDescription,
amount = new Amount()
{
currency = helper.CurrencyName,
total = helper.TransactionAmount.ToString()/// decimal and must be string
},
// item_list = itemList,
item_list = new ItemList()
{
items = helper.Items.Select(x=> new Item()
{
description = x.Description,
currency = x.Currency,
quantity = x.Quantity.ToString(),
price = x.Price.ToString()
}).ToList()
},
},
},
redirect_urls = new RedirectUrls()
{
return_url = helper.ReturnUrl.ToString(),
cancel_url = helper.CancelUrl.ToString()
//Url.Action("action", "controller", "routeVaslues", Request.Url.Scheme);
},
payee = new Payee { email = "RecieverEmail"}
};
/// send payment to paypal
var createdPayment = payment.Create(apiContext);
///get approval url where we need to send our user
var ApprovalUrl = createdPayment.links.FirstOrDefault(x => x.rel.Equals("approval_url", StringComparison.OrdinalIgnoreCase));
return new PaypalHelper
{
CreatedPaymentId = createdPayment.id,
RedirectUrl = ApprovalUrl.href
};
}
Then i tried Chained method but couldn't get it! the request succeded somehow but couldnt get payment nor it authorize the payer!
public void AdaptiveChainedMethod()
{
ReceiverList receivers = new ReceiverList();
Receiver receiver = new Receiver();
receiver.email = "ReCIEVEREMAIL";
receiver.amount = Convert.ToDecimal(22.00);
receivers.receiver.Add(receiver);
ReceiverList receiverList = new ReceiverList(receivers.receiver);
PayRequest payRequest = new PayRequest();
payRequest.actionType = "CREATE";
payRequest.receiverList = receiverList;
payRequest.currencyCode = "USD";
payRequest.cancelUrl = "http://localhost:44382/cont/Act";
payRequest.returnUrl= "http://localhost:44382/cont/Act";
payRequest.requestEnvelope = new RequestEnvelope("en_US");
APIContext apiContext = GetApiContext();
Dictionary<string, string> config = new Dictionary<string, string>();
config.Add("mode", "sandbox");
config.Add("clientId", "id");
config.Add("clientSecret", "seceret");
config.Add("account1.apiUsername", "username");
config.Add("account1.apiPassword", "pass");
config.Add("account1.apiSignature", "signature");
config.Add("account1.applicationId", "APP-80W284485P519543T"); // static account id
AdaptivePaymentsService service = new AdaptivePaymentsService(config);
PayResponse response = service.Pay(payRequest);
}
then I tried PayPalCheckoutSdk.Core PayPalCheckoutSdk.Orders sdk but its API request got stuck every time i hit it and never answers!
public async static Task<string> test()
{
OrderRequest orderRequest = new OrderRequest()
{
CheckoutPaymentIntent = "CAPTURE",
ApplicationContext = new ApplicationContext
{
ReturnUrl = "http://localhost:44382/cont/act",
CancelUrl = "http://localhost:44382/cont/act"
},
PurchaseUnits = new List<PurchaseUnitRequest>
{
new PurchaseUnitRequest {
AmountWithBreakdown = new AmountWithBreakdown
{
CurrencyCode = "USD",
Value = "220.00"
},
Payee = new Payee
{
Email = "RecieverEmail"
}
}
}
};
var request = new OrdersCreateRequest();
// request.Prefer("return=representation");
request.RequestBody(orderRequest);
HttpResponse response = await client().Execute(request);
var statusCode = response.StatusCode;
Order result = response.Result<Order>();
return "string";
}
public static PayPalHttpClient client()
{
string clientId = "clientid";
string clientSecret = "secret";
// Creating a sandbox environment
PayPalEnvironment environment = new SandboxEnvironment(clientId, clientSecret);
// Creating a client for the environment
PayPalHttpClient client = new PayPalHttpClient(environment);
return client;
}

ASP.NET & Angular 7:POST a picture into database

I'm trying to upload an image using an API but the same error shows every time:
"Error reading bytes. Unexpected token: StartObject. Path 'picture'"
the picture is declared as a byte[] in the ASP.NET entity
and I use the formdata to post the picture in angular
Angular code:
onFileChanged(event) {
this.selectedFile = event.target.files[0]
}
adduser() {
this.fd = new FormData();
this.fd.append('picture', this.selectedFile)
this.user.firstname = this.firstname;
this.user.lastname = this.lastname;
this.user.password = this.pass;
this.user.userName = this.email;
this.user.type = this.role;
this.user.picture = this.fd;
alert(this.user.picture)
this.auth.adduser(this.user).subscribe(Response => {
console.log(Response);
this.route.navigate(['login']);
}, error => {
console.log(error)
});
}
.Net code:
[HttpPost]
public async Task < Object > PostAdmin([FromBody] UserModel model) {
{
var profile = new Profile() {
UserName = model.UserName,
lastname = model.lastname,
address = model.address,
firstname = model.firstname,
picture = model.picture,
phone = model.phone,
university = model.university,
Type = model.Type
};
using(var stream = new MemoryStream()) {
profile.picture = stream.ToArray();
}
var user = await _userManager.FindByNameAsync(profile.UserName);
if (user != null) {
return Ok(new {
status = false
});
}
try {
var result = await _userManager.CreateAsync(profile, model.Password);
var role = await _userManager.AddToRoleAsync(profile, model.Type);
return Ok(result);
}
catch (Exception e) {
return BadRequest(new {
status = false, message = e.Message
});
}

ASP.Net MVC File Upload and Attach to Email

I'm developing an ASP.Net MVC 3 web application. One of my Razor Views allows a user to upload a file (selected from their computer) and then this is attached to an outgoing email.
Below is my code to date, but unfortunately it does not work. By this I mean the email (and of course the attachment) never gets sent. Although, when I step threw/ debug my code locally no errors occur, and none as well on the live server.
Does anyone see what I'm missing? Any advice would be greatly appreciated.
Thanks.
Controller
[HttpPost]
public ActionResult CvUpload(HttpPostedFileBase file)
{
//Get logged in user
User user = _accountService.GetUser(_formsAuthService.GetLoggedInUserID());
if (file != null && file.ContentLength > 0)
{
_emailService.SendUpload(user, file);
return RedirectToAction("CvUpload", new { feedBack = "Success" });
}
return RedirectToAction("CvUpload", new { feedBack = "Failed" });
}
Email Service
public void SendUpload(User user, HttpPostedFileBase file)
{
string messageBody = "";
string subject = "Upload";
string[] toAddress = new string[1];
string ToBCC = "";
if (isProduction.Equals("true"))
{
toAddress[0] = "myemail#test.com";
sendEmail(toAddress, ToBCC, adminFromEmail, adminFromEmail, subject, messageBody, true, emailServer, file);
}
else
{
// DO NOT SEND EMAIL
}
}
private bool sendEmail(string[] toAddresses, string ToBCC, string fromAddress, string replyto, string subject, string body, bool ishtml, string emailHost, HttpPostedFileBase file)
{
bool mailSent = false;
try
{
MailMessage mail = new MailMessage();
foreach (string addresss in toAddresses)
mail.To.Add(addresss);
mail.From = new MailAddress(fromAddress);
mail.ReplyToList.Add(replyto);
mail.Bcc.Add(ToBCC);
mail.Subject = subject;
mail.Body = body;
if(file != null && file.ContentLength > 0)
{
string fileName = Path.GetFileName(file.FileName);
mail.Attachments.Add(new Attachment(file.InputStream, fileName));
}
if (ishtml)
mail.IsBodyHtml = true;
else
mail.IsBodyHtml = false;
SmtpClient smtp = new SmtpClient();
smtp.Host = emailHost;
smtp.Send(mail);
mailSent = true;
}
catch (Exception)
{
mailSent = false;
}
return mailSent;
}
I have a similar service and this is what I have although the attachments are saved so they can be reused later.
var attachment = new Attachment(path);
ContentDisposition disposition = attachment.ContentDisposition;
disposition.CreationDate = File.GetCreationTime(path);
disposition.ModificationDate = File.GetLastWriteTime(path);
disposition.ReadDate = File.GetLastAccessTime(path);
disposition.FileName = attachmentName.Name;
disposition.Size = new FileInfo(path).Length;
disposition.DispositionType = DispositionTypeNames.Attachment;
mailMessage.Attachments.Add(attachment);

send view in email body mvc

I want to send a view in email body in mvc.
please guide how to render view so that it can be sent as html email body.
thanks,
Consider using something like ActionMailer. You can download it using NuGet.
string path = ConfigurationManager.AppSettings["ProjectPath"] ;
string gmailpath = path + "/" + "Driver/VerificedAccount?code=" + root.Result.EmailVerificationCode;
var body= "<html><body><p></p><p><a href = "+gmailpath+" > Please click Verifed Account </a></p></body></html> ";
var st = EmailclassHtml(sendemail.Email, "Verification-Driver", body);
public string EmailclassHtml(string email, string subjectname, string messgae)
{
string ownemail = ConfigurationManager.AppSettings["SenderEmail"];
string ownname = ConfigurationManager.AppSettings["SenderName"];
string returnmessage = "success";
var senderEmail = new MailAddress(ownemail, ownname);
var receiverEmail = new MailAddress(email, "Receiver");
var password = ConfigurationManager.AppSettings["SenderPassword"];
var sub = subjectname;
var body = messgae;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = true,
Credentials = new NetworkCredential(senderEmail.Address, password)
};
using (var mess = new MailMessage(senderEmail, receiverEmail)
{
Subject = sub,
Body = body,
IsBodyHtml = true
})
try
{
smtp.Send(mess);
return returnmessage;
}
catch (Exception)
{
returnmessage = "fail";
}
return returnmessage;
}

Resources