Sending emails from Visual Studio using Exchange Web Service - visual-studio

I am trying to send email using Exchange Web Service (Microsoft.Exchange.WebServices.NETStandard) and it is working when I am using Linqpad.
But the same code does not send email when running in Visual Studio. There is no error either.
I am running either app as myself.
Appreciate any idea to troubleshoot this issue.
var service = new ExchangeService(ExchangeVersion.Exchange2016)
{
Url = new Uri("..."),
Credentials = CredentialCache.DefaultNetworkCredentials
};
var address = "...";
var message = new EmailMessage(service)
{
From = address,
Subject = "test",
Body = new MessageBody(BodyType.Text, "test")
};
message.ToRecipients.Add(address);
message.Send();

I changed the Nuget reference in Visual Studio to Microsoft.Exchange.WebService and that solved the issue.

Related

Microsoft.Office.Interop.Outlook does not work on web server but works on local machine

I am using below code in the button event, so that user can send mail through self machine outlook directly (nuget Microsoft. Office. Interop.Outlook). Code is working when I am debugging below code in my localhost and send mail from outlook. But problem is when I deployed the code into web server and browse through IE from my work station, mail not send through outlook.
This error message show in log:
Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
How can I resolve this issue?
Web application reside into web server and users will access the application from IE and then they will send mail through self machine outlook.
public void SendEmailOutlook(string mailToRecipients, string mailCCRecipients, string subjectLine, [Optional] string attachments, string HTMLBody)
{
try
{
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem oMsg = oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
Outlook.Recipients oRecips = oMsg.Recipients;
List<string> oTORecip = new List<string>();
List<string> oCCRecip = new List<string>();
var ToRecip = mailToRecipients.Split(',');
var CCRecip = mailCCRecipients.Split(',');
foreach (string ToRecipient in ToRecip)
{
oTORecip.Add(ToRecipient);
}
foreach (string CCRecipient in CCRecip)
{
oCCRecip.Add(CCRecipient);
}
foreach (string to in oTORecip)
{
Outlook.Recipient oTORecipt = oRecips.Add(to);
oTORecipt.Type = (int)Outlook.OlMailRecipientType.olTo;
oTORecipt.Resolve();
}
foreach (string cc in oCCRecip)
{
Outlook.Recipient oCCRecipt = oRecips.Add(cc);
oCCRecipt.Type = (int)Outlook.OlMailRecipientType.olCC;
oCCRecipt.Resolve();
}
oMsg.Subject = subjectLine;
if (attachments.Length > 0)
{
string sDisplayName = "MyAttachment";
int iPosition = 1;
int iAttachType = (int)Outlook.OlAttachmentType.olByValue;
var Sendattachments = attachments.Split(',');
foreach (var attachment in Sendattachments)
{
Outlook.Attachment oAttach = oMsg.Attachments.Add(attachment, iAttachType, iPosition, sDisplayName);
}
}
if (HTMLBody.Length > 0)
{
oMsg.HTMLBody = HTMLBody;
}
oMsg.Save();
oMsg.Send();
oTORecip = null;
oCCRecip = null;
oMsg = null;
oApp = null;
}
catch (Exception e)
{
//print(e.Message);
}
}
Outlook, just like every other Office app, cannot be used from a service (such as IIS).
The Considerations for server-side Automation of Office article states the following:
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.
As a possible workaround you may consider using EWS or any other REST API (for example, Graph API) if you deal with Exchange server profiles only. See Explore the EWS Managed API, EWS, and web services in Exchange for more information.
I've had this issue too."Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))."
Server environment:Windows server 2019&iis
Local machine:Windows 10&iis
Tip:The Microsoft office doesn't support that use OutWork IIS or Asp.net
So,I give you right answer(It's worked):
1、Run "win+R" ,then inuput 'Dcomcnfg'
2、As this pic:
enter image description here

Accessing User Credential Value from Azure.Identity

I have connected my Visual studio to Azure Active Directory by setting and manually entering pass/email.
This credential shows when I go to Azure Serice Authenticator in Visual Studio under tools.
I want to access the ID associated.
I came across this doc , and I want the AZURE_USERNAME , which must be associated with the id logged in.
I am unable to get a way by which I can access this value.
Does it mean that I can only access it if I explicitly set such value ?
--
Alternatively , is there any way by which I can access the Email ID of user signed in to Visual studio / or signed into Windows and not just User name
Yes of course we should preset environment variables.
Then we can use them for EnvironmentCredential authentication. The reverse will not work.
You can call Microsoft Graph API to get the user information.
Sample reference here.
You can implement the graphServiceClient like this:
var credential = new DefaultAzureCredential();
var token = credential.GetToken(
new Azure.Core.TokenRequestContext(
new[] { "https://graph.microsoft.com/.default" }));
var accessToken = token.Token;
var graphServiceClient = new GraphServiceClient(
new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage
.Headers
.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.CompletedTask;
}));
A blog for your reference.

ChatBot did not work in Web Emulator but work well in Local Bot Framework emulator

I developed the ChatBot that integrates with SharePoint On Premise. When I debug the ChatBot in emulator, it work. But When I debug on Web Emulator in Azure and Website Hosted in Company Website by using DirectLine, it did not work.
Does anyone know how to solve it?
Herewith my screenshot.
Left hand side is from Web Emulator, Right hand side is from local Bot Framework Emulator
Update with Source Code (09 December 2019)
XmlNamespaceManager xmlnspm = new XmlNamespaceManager(new NameTable());
Uri sharepointUrl = new Uri("https://mvponduty.sharepoint.com/sites/sg/daw/");
xmlnspm.AddNamespace("atom", "http://www.w3.org/2005/Atom");
xmlnspm.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
xmlnspm.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
NetworkCredential cred = new System.Net.NetworkCredential("engsooncheah#mvponduty.onmicrosoft.com", "Pa$$w0rd", "mvponduty.onmicrosoft.com");
HttpWebRequest listRequest = (HttpWebRequest)HttpWebRequest.Create(sharepointUrl.ToString() + "_api/lists/getByTitle('" + "data#work" + "')/items?$filter=Keywords%20eq%20%27bloomberg%27");
listRequest.Method = "GET";
listRequest.Accept = "application/atom+xml";
listRequest.ContentType = "application/atom+xml;type=entry";
listRequest.Credentials = cred;
//LINE 136 start from below
HttpWebResponse listResponse = (HttpWebResponse)listRequest.GetResponse();
StreamReader listReader = new StreamReader(listResponse.GetResponseStream());
XmlDocument listXml = new XmlDocument();
listXml.LoadXml(listReader.ReadToEnd());
if (listResponse.StatusCode == HttpStatusCode.OK)
{
Console.WriteLine("Connected");
await turnContext.SendActivityAsync("Connected");
}
// Get and display all the document titles.
XmlElement root = listXml.DocumentElement;
XmlNodeList elemList = root.GetElementsByTagName("content");
XmlNodeList elemList_title = root.GetElementsByTagName("d:Title");
XmlNodeList elemList_desc = root.GetElementsByTagName("d:Description");
//for LINK
XmlNodeList elemList_Id = root.GetElementsByTagName("d:Id");
XmlNodeList elemList_Source = root.GetElementsByTagName("d:Sources");
XmlNodeList elemList_ContentTypeId = root.GetElementsByTagName("d:ContentTypeId");
var attachments = new List<Attachment>();
for (int i = 0; i < elemList.Count; i++)
{
string title = elemList_title[i].InnerText;
string desc = elemList_desc[i].InnerText;
string baseurllink = "https://mvponduty.sharepoint.com/sites/sg/daw/Lists/data/DispForm.aspx?ID=";
string LINK = baseurllink + elemList_Id[i].InnerText + "&Source=" + elemList_Source[i].InnerText + "&ContentTypeId=" + elemList_ContentTypeId[i].InnerText;
//// Hero Card
var heroCard = new HeroCard(
title: title.ToString(),
text: desc.ToString(),
buttons: new CardAction[]
{
new CardAction(ActionTypes.OpenUrl,"LINK",value:LINK)
}
).ToAttachment();
attachments.Add(heroCard);
}
var reply = MessageFactory.Carousel(attachments);
await turnContext.SendActivityAsync(reply);
Update 17 December 2019
I had try using Embedded and Direct Line. But the Error still same.
The Bot is not hosted in SharePoint.
Update 06 January 2020
Its did not work in Azure Bot Services
Based on your description, you can fetch data from it locally. This means your code and logic are all right.
I noticed that your sharePoint URL is : https://mvponduty.sharepoint.com/sites/sg/daw/ and I tried to access it, and also tried to access your whole request URL : https://mvponduty.sharepoint.com/sites/sg/daw/_api/lists/getByTitle('data#work')/items?$filter=Keywords eq 'bloomberg' the response of the two are all 404.
And you said this is an on-prem site , so could you pls have a check that if this site can be reached from a public network?
I assume when you test your code locally, you can access this site as you are in your internal network which will be able to access the on-prem site. However, when you publish your code to Azure, it is not in your internal work anymore: it is in public network so that can't access your on-prem sharePoint site which caused this error.
As we know, bot code is hosted on Azure app service, if this error is caused by the above reason, maybe Azure App Service Hybrid Connections feature will be helpful in this scenario.
ChatBot seems to be working fine? it's sending and receiving messages. There's some code you have that is behaving differently when run locally versus hosted. There's Xml, is it a file or generated? You need check that it's following the same logic and using same data as when it is run locally. Maybe if you paste some of the (non confidential) code where it crashes, we can have more ideas how to help
When you publish your bot, there will be an option as below :
Select Edit App Service Settings. Add only the following details, nothing else :
MicrosoftAppId : <xxxxx>
MicrosoftAppPassword : <xxxxx>
Click Apply, Ok.
Make sure you remove the Microsoft App Id and Microsoft App Password from appsettings.json, so that it works in bot emulator as well.
Now Publish the bot. It will work at both places.
Hope this is helpful.

Having issue in conversation of UCMA with MS Bot Framework

I am working on MS Bot Framework Integration with UCMA(Skype For Business OnPremise aka SFB onPrimise) SDK.
I am using directline channel for connection and the Connection is successfully established between two, but when a dialog prompt with Yes, No options is returned From BOT to SFB, and when I send my answer as yes then BOT do not recognize it as my answer. It creates new conversation Id for every single statement. How to overcome this issue?
Below is my code from UCMA
static DirectLineClient client = null;
client = new Microsoft.Bot.Connector.DirectLine.DirectLineClient("DirectLineSecretKey");
botConversation = client.Conversations.NewConversation();
string message = e.TextBody;
Microsoft.Bot.Connector.DirectLine.Models.Message msg = new Microsoft.Bot.Connector.DirectLine.Models.Message
{
FromProperty = "AMOL",
Text = message
};
await client.Conversations.PostMessageAsync(botConversation.ConversationId, msg);
var messages = await client.Conversations.GetMessagesAsync(botConversation.ConversationId, watermark);
InstantMessagingFlow instantMessagingFlow = (InstantMessagingFlow)sender;
watermark = messages.Watermark;
foreach (var m in messages.Messages)
{
if (m.FromProperty != "AMOL")
instantMessagingFlow.BeginSendInstantMessage(m.Text, MyMethod, instantMessagingFlow);
}
I am doing the same and it works for me. The problem in your code is, you create conversation id for each and every request and bot is considering the request as new fresh new request.
Let me know if you need any help on this.

Push data from a web from into CRM 2015 online

I am trying to create a web from (web application) in Visual Studio 2012 to push data into CRM 2015 online. It keep saying Metadata Contains A Reference That Cannot Be Resolved, when the program tried to call OrgService.
Before that, I create a windows form to do so, it works fine. It can connect to CRM 2015 online and create a new entity record successfully. But when I move the code to Web Application. I does not work.
Code:
private void button1_Click(object sender, EventArgs e)
{
ClientCredentials cre = new ClientCredentials();
cre.UserName.UserName = "MyEmailAddress";
cre.UserName.Password = "Password";
Uri serviceUri = new Uri("https://QA.crm.dynamics.com/XRMServices/2011/Organization.svc");
OrganizationServiceProxy proxy = new OrganizationServiceProxy(serviceUri, null, cre, null);//Error occurs here!!!!!!
proxy.EnableProxyTypes();
IOrganizationService service = (IOrganizationService)proxy;
Entity contact = new Entity("contact");
contact["firstname"] = Convert.ToString(firstname.Text);
contact["lastname"] = Convert.ToString(lastname.Text);
contact["emailaddress1"] = Convert.ToString(email.Text);
contact["mobilephone"] = Convert.ToString(phone.Text);
proxy.Create(contact);
}
Error occurs at:
OrganizationServiceProxy proxy = new OrganizationServiceProxy(serviceUri, null, cre, null);
Is there anyone know what is going on here? I appreciate your help.
Thanks.
Try to use following code for initialization of service proxy:
IServiceManagement<IOrganizationService> orgServiceManagement =
ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri("https://democrm.api.crm5.dynamics.com/XRMServices/2011/Organization.svc"));
AuthenticationCredentials authCredentials = new AuthenticationCredentials();
authCredentials.ClientCredentials.UserName.UserName = _userName;
authCredentials.ClientCredentials.UserName.Password = _password;
AuthenticationCredentials tokenCredentials = orgServiceManagement.Authenticate(authCredentials);
IOrganizationService organizationProxy = new OrganizationServiceProxy(orgServiceManagement, tokenCredentials.SecurityTokenResponse);

Resources