hi i wrote following code for save some mails (already imported to data grid using MAPI) to selected inbox folder in button click
Outlook.MAPIFolder oMailFolder = null;
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace oNS = oApp.GetNamespace("MAPI");
MailItem moveFilteredMails = null;
oMailFolder = oNS.PickFolder();
oApp = null;
oNS = null;
List<UnreadEmails> filteredList = (List<UnreadEmails>)dgvUnreadMails.DataSource;
foreach (UnreadEmails item in filteredList)
{
moveFilteredMails.Move(oMailFolder);
}
but after selecting inbox folder from pickfilder method it gives a exception saying that
NullReferenceExceptionException was unhandled and Object reference not set to an instance of an object.
pls help to find the error
You wrote moveFilteredMails = null.
Since moveFilteredMails is null, you're getting a NullReferenceException when you try to move an item into it.
Related
On CRM 2013 on-premise, I'm trying to write a plugin that triggers when an update is made to a field on Quote. The plugin then creates a new custom entity "new_contract".
My plugin is successfully triggered when the update to that field is made. However I keep getting an error message "The given key was not present in the dictionary" when trying to create the new custom entity.
I'm using a "PostImage" in this code. I confirm that it's registered using the same name in Plugin Registration.
Here is the code
var targetEntity = context.GetParameterCollection<Entity>
(context.InputParameters, "Target");
if (targetEntity == null)
{throw new InvalidPluginExecutionException(OperationStatus.Failed,
"Target Entity cannot be null")}
var postImage = context.PostEntityImages["PostImage"];
if (postImage == null)
{throw new InvalidPluginExecutionException(OperationStatus.Failed,
"Post Image is required");}
var quote = context.GenerateCompositeEntity(targetEntity, postImage);
//throw new InvalidPluginExecutionException(OperationStatus.Failed, "Update is captured");
//Guid QuoteId = (Guid)quote.Attributes["quoteid"];
var serviceFactory = (IOrganizationServiceFactory)serviceProvider
.GetService(typeof(IOrganizationServiceFactory));
var service = serviceFactory.CreateOrganizationService(context.UserId);
var contractEntity = new Entity();
contractEntity = new Entity("new_contract");
if (quote.Attributes.Contains("portfolio"))
{
var quotePortfolio = (EntityReference)quote.Attributes["new_portfolio];
contractEntity[Schema.new_contract.PortfolioName] =
new EntityReference(quotePortfolio.LogicalName, quotePortfolio.Id);
}
if (quote.Attributes.Contains(Schema.Quote.QuoteName))
{
var quoteName = (string)quote.Attributes["name"];
contractEntity[Schema.new_contract.contractName] = quoteName;
}
var contractId = service.Create(contractEntity);
I think context does not contain "PostImage" attribute.You should check context to see whether it contains the attribute before getting the data.
Looking at this line in your post above:
var service = serviceFactory.CreateOrganizationService(context.UserId);
I am deducing that the type of your context variable is LocalPluginContext (since this contains the UserId value) which does not expose the images (as another answer states).
To access the images, you need to get to the Plugin Execution Context:
IPluginExecutionContext pluginContext = context.PluginExecutionContext;
Entity postImage = null;
if (pluginContext.PostEntityImages != null && pluginContext.PostEntityImages.Contains("PostImage))
{
postImage = pluginContext.PostEntityImages["PostImage"];
}
In the below code segment, you are checking for the attribute "portfolio" and using "new_portfolio". Can you correct that and let us know whether that worked.
if (quote.Attributes.Contains("portfolio"))
{
var quotePortfolio = (EntityReference)quote.Attributes["new_portfolio];
contractEntity[Schema.new_contract.PortfolioName] = new EntityReference(quotePortfolio.LogicalName, quotePortfolio.Id);
}
First, you don't say what line is throwing the exception. Put in the VS debugger and find the line that is throwing the exception.
I did see that you are trying to read from a dictionary here without first checking if the dictionary contains the key, that can be the source of this exception.
var postImage = context.PostEntityImages["PostImage"];
if (postImage == null)
throw new InvalidPluginExecutionException(OperationStatus.Failed,
"Post Image is required");
Try this:
if(!context.PostEntityImages.Contains("PostImage") ||
context.PostEntityImages["PostImage"] == null)
InvalidPluginExecutionException(OperationStatus.Failed, "Post Image is required");
var postImage = context.PostEntityImages["PostImage"];
Although, I don't think that a PostEntityImage Value will ever be null, if it passes the Contains test you don't really need the null check.
I am working on a project and part of this project is to send emails to a list of email addresses located in SQL.
I am using the following code, which, when sent, just throws a "Sending Failed" error. Nothing else.
Can anyone please help me out with this one? I would really appreciate it.
'Connect to SQL Server database and query out only Address column to fill into DataTable
Dim con As SqlConnection = New SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=FigClubs;Integrated Security=True;Pooling=False")
Dim cmd As SqlCommand = New SqlCommand("SELECT Email FROM Members", con)
con.Open()
Dim myDA As SqlDataAdapter = New SqlDataAdapter(cmd)
Dim myDataTable As DataTable = New DataTable
myDA.Fill(myDataTable)
con.Close()
con = Nothing
'New a MailMessage instance
Dim mailMessage As MailMessage = New MailMessage()
mailMessage.From = New MailAddress(TextBox4.Text.Trim())
' Determine the mailMessage.To property based on CheckBox checked status
If CheckBox1.Checked = True Then
For Each dr As DataRow In myDataTable.Rows
mailMessage.To.Add(New MailAddress(dr.Item(0).ToString))
Next
Else
mailMessage.To.Add(New MailAddress(TextBox3.Text.Trim()))
End If
mailMessage.Subject = TextBox1.Text.Trim()
mailMessage.Body = TextBox2.Text.Trim()
Dim smtpClient As SmtpClient = New SmtpClient("smtp.google.com")
smtpClient.Port = ("587")
smtpClient.Credentials = New System.Net.NetworkCredential("HIDDEN", "HIDDEN")
smtpClient.Send(mailMessage)
Try
smtpClient.Send(mailMessage)
Catch smtpExc As SmtpException
'Log errors
MsgBox(smtpExc.Message)
Catch ex As Exception
'Log errors
MsgBox(ex.Message)
End Try
I got that code from a google search.
Any help you can provide to get this working would be so appreciated.
Thanks in advance,
Dan
EDIT - Got it to work:
Got it to work using the following. Just in case anyone else needs it:
Try
Dim Smtp_Server As New SmtpClient
Dim e_mail As New MailMessage()
Smtp_Server.UseDefaultCredentials = False
Smtp_Server.Credentials = New Net.NetworkCredential("HIDDEN", "HIDDEN")
Smtp_Server.Port = 587
Smtp_Server.EnableSsl = True
Smtp_Server.Host = "smtp.gmail.com"
e_mail = New MailMessage()
e_mail.From = New MailAddress(TextBox4.Text)
e_mail.To.Add(TextBox3.Text)
e_mail.Subject = TextBox1.Text
e_mail.IsBodyHtml = False
e_mail.Body = TextBox2.Text
Smtp_Server.Send(e_mail)
MsgBox("Mail Sent")
Catch error_t As Exception
MsgBox(error_t.ToString)
End Try
Thanks guys. Hope all is well :)
Okay, here's a great solution for you...
Imports System.Net.Mail 'Namespace for sending the email
Public Class Form1 'Whatever class your doing this from...
'I tested with a button click event...
Private Sub btnSendEmail_Click(sender As Object, e As EventArgs) Handles btnSendEmail.Click
Dim dtEmails As New DataTable
Dim strEmails() As String = {"testing#yahoo.com", "testing#gmail.com"}
Dim strBuilder As New System.Text.StringBuilder 'Can be used to build a message
'This was only for my testing...
dtEmails.Columns.Add("EmailAddress")
For Each Str As String In strEmails
dtEmails.Rows.Add(Str)
Next
'Loop through our returned datatable and send the emails...'
If dtEmails.Rows.Count > 0 Then
strBuilder.AppendLine("Emails Confirmation")
strBuilder.AppendLine(" ")
For i As Integer = 0 To dtEmails.Rows.Count - 1 'Whatever your datatbale is called'
Try
Dim newMail As New Mail 'Use our new mail class to set our properties for the email'
newMail.MailMessageTo = dtEmails.Rows(i).Item("EmailAddress") 'What your email address column name is in the data table'
newMail.MailSubject = "Just a Test email!"
newMail.MailMessage = "Did you get this email, please let me know!"
If Mail.SendMail(newMail) Then
strBuilder.AppendLine("SENT - " & dtEmails.Rows(i).Item("EmailAddress").ToString.ToUpper)
Else
strBuilder.AppendLine("FAILED - " & dtEmails.Rows(i).Item("EmailAddress").ToString.ToUpper)
End If
Catch ex As Exception
Continue For
End Try
Next
End If
If strBuilder.Length > 0 Then
MessageBox.Show(strBuilder.ToString())
End If
End Sub
End Class
'You can put this class at the bottom of your class your using...This handles the emails...
Public Class Mail
Public Property MailMessageTo As String
Public Property MailMessage As String
Public Property MailSubject As String
'This will send your mail...
Public Shared Function SendMail(ByVal oMail As Mail) As Boolean
Dim Smtp_Server As New SmtpClient
Dim e_mail As New MailMessage()
Try
Smtp_Server.UseDefaultCredentials = False
Smtp_Server.Credentials = New Net.NetworkCredential("EMAIL", "PASSWORD")
Smtp_Server.Port = 587
Smtp_Server.EnableSsl = True
Smtp_Server.Host = "smtp.gmail.com"
e_mail = New MailMessage()
e_mail.From = New MailAddress("EMAIL") 'Whatever you want here'
e_mail.To.Add(oMail.MailMessageTo)
e_mail.Subject = oMail.MailSubject
e_mail.IsBodyHtml = False
e_mail.Body = oMail.MailMessage
Smtp_Server.Send(e_mail)
Return True
Catch error_t As Exception
Return False
Finally
Smtp_Server = Nothing
e_mail = Nothing
End Try
End Function
End Class
This works really well, you can edit as needed to. This is much more organized and easier to maintain for what you would need. Also another good note to remember your looping through a DataTable sending emails, you may want to put some of this on a BackgroundWorker as this can lock up the UI thread... Another thing to check when looping through your DataTable, you may want to check if the email your referencing isn't 'DBNull.value', I didn't check for that, other wise it will throw an exception.
Happy Coding!
I have a plugin in post-operation witch need to create a folder on sharepoint via webservice, to do that, my plugin calls a webservice to execute a FechXML to get the info from the entity, but the problem is that entity still not exist, and it give me Null.
How do i force the plugin to submit/save the data to my FechXml to work?
PLUGIN CODE:
try
{
Entity entity;
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
entity = (Entity)context.InputParameters["Target"];
if (entity.LogicalName != "fcg_processos")
{
throw new InvalidPluginExecutionException("Ocorreu um erro no PlugIn Create Folder.");
}
}
else
{
throw new InvalidPluginExecutionException("Ocorreu um erro no PlugIn Create Folder.");
}
processosid = (Guid)((Entity)context.InputParameters["Target"])["fcg_processosid"];
string processoid2 = processosid.ToString();
PluginSharepointProcessos.ServiceReference.PrxActivityResult result = log.CreateFolderSP("Processo", processoid2);
string resultado = result.xmlContent;
if (result.retCode > 0)
{
throw new InvalidPluginExecutionException("Ocorreu um erro na criação do Folder do Processo.");
}
WEBSERVICE CODE:
{
//WEBSERVICE TO CALL XML FROM ENTITY
PrxActivityResult Processo = ProcessoFetch2("", "", guid);
string stxml;
stxml = Processo.XmlContent;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(stxml);
XmlNodeList nodeList = xmlDoc.SelectNodes("resultset/result");
List<string[]> lista = new List<string[]>();
string[] strs = new string[7];
if (nodeList.Count != 0)//verificar o numero de registos
{
foreach (XmlNode xmlnode in nodeList)
{
if (xmlnode.SelectSingleNode("//fcg_numero") != null)
strs[2] = xmlnode.SelectSingleNode("//fcg_numero").InnerText;
else
strs[2] = "";
if (xmlnode.SelectSingleNode("//Concurso.fcg_numero") != null)
strs[3] = xmlnode.SelectSingleNode("//Concurso.fcg_numero").InnerText;
else
strs[3] = "";
}
}
IwsspClient FmwSharepoint = new IwsspClient();
PrxActivityResult folderresult = new PrxActivityResult();
List<ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave> arrayfields = new List<ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave>();
ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave nprocesso = new ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave();
nprocesso.Key = "FCG_Numero_Processo";
nprocesso.value = strs[2];
arrayfields.Add(nprocesso);
ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave npconcurso = new ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave();
npconcurso.Key = "FCG_Numero_Concurso";
npconcurso.value = strs[3];
arrayfields.Add(npconcurso);
ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave npguid = new ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave();
npguid.Key = "FCG_Guid_CRM";
npguid.value = guid;
arrayfields.Add(npguid);
folderresult = FmwSharepoint.CreateFolder("http://localhost/folder", "Processos", strs[2], arrayfields.ToArray());
res = folderresult;
}
When a plugin runs on the Post-Operation, it is still within the database transaction, and it hasn't actually been committed to the database. Any calls done with the service reference passed in as a part of the Plugin Context will be executed within the context on the database transaction and you will be able to retrieve the newly created/updated values. If you create a brand new OrganizationServiceProxy (Which I'm guessing is what you're doing), it will execute outside of the database transaction, and will not see the newly created / updated values.
As #AndyMeyers suggests in his comment (which really should be an answer IMHO), grabbing the data from the plugin context either via a pre/post image or the target is ideal since it eliminates another database call. If you're having to lookup records that may have been created by another plugin that fired earlier, you'll need to use the IOrganizationService that is included in the plugin context.
I had no option and I used this code to run webservice based on image and forget the FecthXml, as mentioned, i get all info from the Image on the post operation and send back to the WebService. Thanks, here is the code:
entity = (Entity)context.InputParameters["Target"];
concursid = (Guid)entity.Attributes["fcg_concursid"];
guid = concursid.ToString();
string npconcurs = (string)entity.Attributes["fcg_numer"];
nconcurs= npconcurs;
EntityReference nprograma = (EntityReference)entity.Attributes["fcg_unidadeorganica"];
program = nprogram.Name;
if (entity.LogicalName != "fcg_concurs")
I am attempting to insert an invoice into Quickbooks Online using IPP.NET. The problem seems to be in setting the item.
Here is a snippet of my VB code for the first line, which works fine...
Dim qboInvoiceLine1 as new intuit.ipp.data.qbo.invoiceline
qboInvoiceline1.desc="Desc1"
qboInvoiceLine1.amount=10
qboInvoiceLine1.AmountSpecified=True
If I add the following code for setting the item, I get an error forming the XML...
Dim items1 as List(Of Intuit.Ipp.Data.Qbo.Item)=New List(Of Intuit.Ipp.Data.Qbo.Item)
Dim item1 as new intuit.ipp.data.qbo.item
item1.id=new intuit.ipp.data.qbo.idtype
item1.id.value="1"
items1.add(item1)
qboInvoiceLine1.Items=items1.ToArray
I do not even understand why the item ID seems to be some kind of array or list of items. One source of documentation suggests there is an itemID property of the invoice line, but this does not seem to be the case. Can anyone give me code for setting the itemID for an invoice line?
ItemsChoiceType2[] invoiceItemAttributes = { ItemsChoiceType2.ItemId, ItemsChoiceType2.UnitPrice,ItemsChoiceType2.Qty };
object[] invoiceItemValues = { new IdType() { idDomain = idDomainEnum.QB, Value = "5" }, new decimal(33), new decimal(2) };
var invoiceLine = new InvoiceLine();
invoiceLine.Amount = 66;
invoiceLine.AmountSpecified = true;
invoiceLine.Desc = "test " + DateTime.Now.ToShortDateString();
invoiceLine.ItemsElementName = invoiceItemAttributes;
invoiceLine.Items = invoiceItemValues;
invoiceLine.ServiceDate = DateTime.Now;
invoiceLine.ServiceDateSpecified = true;
listLine.Add(invoiceLine);
I have a c# class which was written to read the lotus emails for any attachments and save it to the local drive. It was working fine when I pass "" as first parameter to GetDataBase method and full path of .nsf file of my local system as second argument. But, if I remove "" and I specify my local system full name as first argument it is returning null value.
Is it problem with any permissions? If so, it should not work even when I pass "" as first parameter. Otherwise, should I have any other permissions at system/server level?
Please help me in this issue.
Finally, I could do it in the following way. And I thought of posting it to some one can atleast not to suffer again.
Following code is to read the attachment from the lotus emails and save it to the physical location.
string lotusServerName = ConfigurationSettings.AppSettings["Lotus_Server"].ToString();
string lotusDBFilePath = ConfigurationSettings.AppSettings["Lotus_DB_File_Path"].ToString();
string password = ConfigurationSettings.AppSettings["Password"].ToString();
string sourceFolder = ConfigurationSettings.AppSettings["Source_Folder"].ToString();
string targetFolder = ConfigurationSettings.AppSettings["Target_Folder"].ToString();
string documentsFolder = ConfigurationSettings.AppSettings["Documents_Folder"].ToString();
//Creating the notes session and passing password
NotesSession session = new NotesSession();
session.Initialize(password);
//Getting the DB instance by passing the servername and path of the mail file.
//third param "false" will try to check the DB availability by opening the connection
//if it cannot open, then it returns null.
NotesDatabase NotesDb = session.GetDatabase(lotusServerName, lotusDBFilePath, false);
//Get the view of the source folder
NotesView inbox = NotesDb.GetView(sourceFolder);
//looping through each email/document and looking for the attachments
//if any attachments found, saving them to the given specified location
//moving the read mails to the target folder
NotesDocument docInbox = null;
int docCnt = inbox.EntryCount;
for (int currDoc = 0; currDoc < docCnt; currDoc++) {
docInbox = inbox.GetFirstDocument();
object[] items = (object[])docInbox.Items;
foreach (NotesItem nItem in items) {
if (nItem.Name == "$FILE") {
NotesItem file = docInbox.GetFirstItem("$File");
string fileName = ((object[])nItem.Values)[0].ToString();
NotesEmbeddedObject attachfile = (NotesEmbeddedObject)docInbox.GetAttachment(fileName);
if (attachfile != null) {
attachfile.ExtractFile(documentsFolder + fileName);
}
}
}
docInbox.PutInFolder(targetFolder, true);//"true" creates the folder if it doesn't exists
docInbox.RemoveFromFolder(sourceFolder);
}
//releasing resources
if (session != null)
session = null;
if (NotesDb != null)
NotesDb = null;
if (inbox != null)
inbox = null;
if (docInbox != null)
docInbox = null;
Following is values read from .config file.
The above code will work properly if you alredy have lotus mail client in your system and you are able to access mails from your mail server. You don't require any other previliges.