This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
linq query and nulls
This throws a null exception if is some of elements in xml file missing - I don't want to get this exception - I would like just add empty string to list data beside missing element
InstrumentDescription inputFile = InstrumentDescription.Load(openFileDialog1.FileName);
var queryManufacturer = from dataManufaturer in
inputFile.Identification.Manufacturers.Manufacturer
select new
{
dataManufaturer.name,
dataManufaturer.cageCode,
dataManufaturer.FaxNumber,
dataManufaturer.URL.OriginalString
};
foreach (var a in queryManufacturer)
{
data.Add(a.name);
if (a.cageCode == null) data.Add("");
else data.Add(a.cageCode);
if (a.FaxNumber == null) data.Add("");
else data.Add(a.FaxNumber);
if (a.OriginalString == null) data.Add("");
else data.Add(a.OriginalString);
}
I tried somenthing like this - but it doesn't work
select new
{
name = dataManufaturer.name ?? "",
cageCode = dataManufaturer.cageCode ?? "",
FaxNumber = dataManufaturer.FaxNumber ?? "",
OriginalString = dataManufaturer.URL!=null ? dataManufaturer.URL.OriginalString : ""
};
I want to have a empty string if some of elements are missing, not to get exception.
I SOLVE IT !!!
In select I only use select new { dataManufacturer } not these all possible elements and when I am adding to list just test if for example dataManufacturer.name is null or not
I'm going to post this "comment" here as a CW to help give you a nudge in the right direction in finding the source of the problem.
There are way too many potential causes for where the null reference exception will happen here in this block of code alone. Looking at your responses in your other question, it's clear you have no idea how to find out where the problem is. So try this to find out. This is a rewritten form of the code you have shown us to facilitate finding out where the null is. Run it to find out where this happens and hopefully you'll be able to fix it yourself. If not, then please share the results of this test with us so we can better understand your problem and give you a better answer to help you fix your problem.
This assumes you are making a Windows Forms application or WPF application.
var dialog = openFileDialog1;
if (dialog == null)
{
MessageBox.Show("openFileDialog1 is null");
}
var filename = dialog.FileName;
if (filename == null)
{
MessageBox.Show("openFileDialog1.FileName is null");
}
InstrumentDescription input;
try
{
input = InstrumentDescription.Load(filename);
}
catch (NullReferenceException e)
{
MessageBox.Show("NullReferenceException in InstrumentDescription.Load():\n" + e.Message);
}
if (input == null)
{
MessageBox.Show("inputFile is null");
}
var id = input.Identification;
if (id == null)
{
MessageBox.Show("inputFile.Identification is null");
}
var mans = id.Manufacturers;
if (mans == null)
{
MessageBox.Show("inputFile.Identification.Manufacturers is null");
}
var man = mans.Manufacturer;
if (man == null)
{
MessageBox.Show("inputFile.Identification.Manufacturers.Manufacturer is null");
}
var i = 0L;
foreach (var dm in man)
{
if (dm == null)
{
MessageBox.Show("dataManufaturer at index "+i+" is null");
}
if (dm.name == null)
{
MessageBox.Show("dataManufaturer.name at index " + i + " is null");
}
if (dm.cageCode == null)
{
MessageBox.Show("dataManufaturer.cageCode at index " + i + " is null");
}
if (dm.FaxNumber == null)
{
MessageBox.Show("dataManufaturer.FaxNumber at index " + i + " is null");
}
var u = dm.URL;
if (u == null)
{
MessageBox.Show("dataManufaturer.URL at index " + i + " is null");
}
if (u.OriginalString == null)
{
MessageBox.Show("dataManufaturer.URL.OriginalString at index " + i + " is null");
}
i++;
}
How about
var queryManufacturer = from dataManufaturer in input.Identification.Manufacturers.Manufacturer
where dataManufaturer != null
select {...}
Related
I've got a legacy service that I need to emulate that uses Soap as the message format. Unfortunately, due to various circumstances, I'm stuck using asmx and .Net Framework (due to it's Soap handling capabilities)
My problem is that I now need to call a certain API from within the service, and having used NSWAG to auto generate the client api, I'm finding that when I try and call it, it's giving a 500 error. This isn't necessairly a problem, as I'm sort of expecting that at the moment.
The issue is that when it throws the auto generated ApiException message as part of the 500 processing, it's jumping to the 'Finally' section for the response and the client, and then just throws an object reference exception...somewhere.
There's very little detail at all in the Exception, with the only bit of interest (I think) being that it says "This exception was originally thrown at this call stack:
System.Web.ThreadContext.AssociateWithCurrentThread(bool)"
I'm sort of lost on where to start with this one, but I'm hoping it's a common enough problem that there's a solution out there somewhere!
[Edit - updated to include code]
public System.Threading.Tasks.Task<SomeDto> RetrieveAsync(string someIdentifier, string includePermissibleActions)
{
return RetrieveAsync(someIdentifier, includePermissibleActions, System.Threading.CancellationToken.None);
}
public async System.Threading.Tasks.Task<SomeDto> RetrieveAsync(string someIdentifier, string includePermissibleActions, System.Threading.CancellationToken cancellationToken)
{
if (someIdentifier == null)
throw new System.ArgumentNullException("someIdentifier");
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/v1/someName/{someIdentifier}?");
urlBuilder_.Replace("{someIdentifier}", System.Uri.EscapeDataString(ConvertToString(someIdentifier, System.Globalization.CultureInfo.InvariantCulture)));
if (includePermissibleActions != null)
{
urlBuilder_.Append(System.Uri.EscapeDataString("includePermissibleActions") + "=").Append(System.Uri.EscapeDataString(ConvertToString(includePermissibleActions, System.Globalization.CultureInfo.InvariantCulture))).Append("&");
}
urlBuilder_.Length--;
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<SomeDto>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
if (status_ == 401)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Unauthorized", status_, responseText_, headers_, null);
}
else
if (status_ == 403)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Forbidden", status_, responseText_, headers_, null);
}
else
if (status_ == 404)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("NotFound", status_, responseText_, headers_, null);
}
else
if (status_ == 500)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("InternalServerError", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
I have a project that uses Entity Framework. While calling SaveChanges on my DbEntityValidationException, I get the following exception:
System.Data.Entity.Validation.DbEntityValidationException: 'Validation
failed for one or more entities. See 'EntityValidationErrors' property
for more details.'
This is all fine and dandy, but I don't want to attach a debugger every time this exception occurs. More over, in production environments I cannot easily attach a debugger so I have to go to great lengths to reproduce these errors.
How can I see the details hidden within the DbEntityValidationException?
private void btnCreateLetter_Click(object sender, EventArgs e)
{
using (TransactionScope TS = new TransactionScope())
{
try
{
Letter TblLetter = new Letter();
TblLetter.Subject = txtSubject.Text.Trim();
TblLetter.Abstract = txtAbstract.Text.Trim();
TblLetter.Body = ckeCKEditor.TextEditor.Text.Trim();
{
var LastLetterID = (from Letter in Database.Letters orderby Letter.LetterID descending select Letter).First();
TblLetter.LetterNO = PublicVariable.TodayDate.Substring(0, 4).Substring(2, 2) + PublicVariable.gDetermineJobLevel + "/" + (LastLetterID.LetterID + 1);
}
TblLetter.CreateDate = lblCreateDate.Text;
TblLetter.UserID = PublicVariable.gUserID;
if (rdbClassification.Checked == true)
{
TblLetter.SecurityType = 1;
}
else if (rdbConfidential.Checked == true)
{
TblLetter.SecurityType = 2;
}
else if (rdbSeries.Checked == true)
{
TblLetter.SecurityType = 3;
}
if (rdbActionType.Checked == true)
{
TblLetter.UrgencyType = 1;
}
else if (rdbInstantaneous.Checked == true)
{
TblLetter.UrgencyType = 2;
}
else if (rdbAnnie.Checked == true)
{
TblLetter.UrgencyType = 3;
}
TblLetter.ArchivesType = 1;
if (rdbFollowHas.Checked == true)
{
TblLetter.FollowType = 1;
}
else if (rdbFollowHasnoot.Checked == true)
{
TblLetter.FollowType = 2;
}
if (rdbAttachmentHas.Checked == true)
{
TblLetter.AttachmentType = 1;
}
else if (rdbAttachmentHasnot.Checked == true)
{
TblLetter.AttachmentType = 2;
}
TblLetter.ReadType = 1;
TblLetter.LetterType = 1;
TblLetter.DraftType = 1;
if (rdbResponseDeadlineHas.Checked == true)
{
TblLetter.AnswerType = 1;
TblLetter.AnswerReadLine = String.Format("{0:yyyy/MM/dd}", Convert.ToDateTime(pdpSetResponseDeadline.Value.Year.ToString() +
"/" + pdpSetResponseDeadline.Value.Month.ToString() + "/" + pdpSetResponseDeadline.Value.Day.ToString()));
}
else if (rdbResponseDeadlineHasnot.Checked == true)
{
TblLetter.AnswerType = 2;
}
Database.Letters.Add(TblLetter);
Database.SaveChanges();
if (rdbAttachmentHas.Checked == true)
{
if (lblPath.Text != "")
{
FileStream ObjectFileStream = new FileStream(lblPath.Text, FileMode.Open, FileAccess.Read);
int Lenght = Convert.ToInt32(ObjectFileStream.Length);
byte[] ObjectData;
ObjectData = new byte[Lenght];
string[] strPath = lblPath.Text.Split(Convert.ToChar(#"\"));
ObjectFileStream.Read(ObjectData, 0, Lenght);
ObjectFileStream.Close();
AttachFile TableAttachFile = new AttachFile();
TableAttachFile.FileSize = Lenght / 1024;
TableAttachFile.FileName = strPath[strPath.Length - 1];
TableAttachFile.FileData = ObjectData;
TableAttachFile.LetterID = TblLetter.LetterID;
Database.AttachFiles.Add(TableAttachFile);
Database.SaveChanges();
}
}
TS.Complete();
MessageBox.Show("saved", "ok", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (InvalidCastException ex)
{
MessageBox.Show(ex.ToString());
MessageBoxIcon.Error);
return;
}
}
}
You have to get the validation errors from the db.SaveChanges() method of the DatabaseContext object -- you can't get them where you are.
You can either modify the SaveChanges() method of your database context and wrap it in a try-catch block, or (since the class is partial) you can extend the partial class within your application and just override the SaveChanges() method.
There is a nice blog post about this called Easy way to improve DbEntityValidationException of Entity Framework here.
The essence of it is something like this:
public partial class NorthwindEntities
{
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
}
}
The blogger explains:
That’s it! The rest of your code will automatically use the overridden
SaveChanges so you don’t have to change anything else. From now on,
your exceptions will look like this:
System.Data.Entity.Validation.DbEntityValidationException: Validation
failed for one or more entities. See 'EntityValidationErrors' property
for more details. The validation errors are: The field PhoneNumber
must be a string or array type with a maximum length of '12'; The
LastName field is required.
The DbEntityValidationException also contains the entities that caused
the validation errors. So if you require even more information, you
can change the above code to output information about these entities.
As mention, you need to check on your EntityValidationError when it throws the exception.
You should fix that validation error, instead of asking bypass this exception.
Normally these errors are table allow length, data type, column does not allow null and etc. There will be exact fiend name mention in your exception too.
I'm working with a POST method in my ASP.NET MVC + Web API project. The problem is that I want to filter the results of an IEnumerable collection applying a Regex to clear out non alphanumeric characters.
Whenever the program gets to that line it throws an "ArgumentNullException" which also says "Value cannot be null. Parameter name: input".
I understand that it has something to be with the parameters that a method is receiving so I suspect that there might be a problem with the Regex.Replace method so I tried to debug it with no success.
At the beginning I thought that I was using the repository to fill the IEnumerable collection in the wrong way because it's an static attribute declared outside the transaction scope. So then I created another repository instance inside the scope but that didn't resolve the issue.
Any help would be appreciated. Thank you.
Here's my the method with the problematic line (indicated with -------->):
[HttpPost]
public object Post(string token, [FromBody]ExternoApi externo)
{
var ValidateToken = TokensRepository.Validate(token);
if (ValidateToken == null)
throw new NotImplementedException(string.Format("El token ID = \"{0}\" no se encuentra habilitado o aun no se realizo el emparejamiento.", token));
if (externo == null)
throw new ParameterNullException(string.Format("Debe informar un externo."));
Externo externoNew;
var scope = new TransactionScope(TransactionScopeOption.RequiresNew,
new TransactionOptions()
{
IsolationLevel = IsolationLevel.ReadCommitted
}
);
using (scope)
{
IExternoRepository _repository = new ExternoRepository();
try
{
externoNew = new Externo()
{
dsNombre = externo.dsNombre,
dsApellido = externo.dsApellido,
dsDocumento = externo.dsDocumento,
IdCliente = externo.IdCliente,
dsPatente = externo.dsPatente,
dtCreado = DateTime.Now,
dtModificado = DateTime.Now
};
Regex rgx = new Regex("[^a-zA-Z0-9]");
string pattern = "[^a-zA-Z0-9]";
var _externos = _repository.GetAll();
//var _ExternoExistente = _externos.Where(x => rgx.Replace(x.dsDocumento, "") == rgx.Replace(externoNew.dsDocumento, "")
// && rgx.Replace(x.dsPatente, "") == rgx.Replace(externoNew.dsPatente, "")
// && rgx.Replace(x.IdCliente, "") == rgx.Replace(externoNew.IdCliente, "")).OrderBy(x => x.IdExterno).FirstOrDefault();
This line throws exception --------> var _ExternoExistente = _externos.Where(x => Regex.Replace(x.dsDocumento, pattern, "") == Regex.Replace(externoNew.dsDocumento, pattern, "")
&& Regex.Replace(x.dsPatente, pattern, "") == Regex.Replace(externoNew.dsPatente, pattern, "")
&& Regex.Replace(x.IdCliente, pattern, "") == Regex.Replace(externoNew.IdCliente, pattern, "")).OrderBy(x => x.IdExterno).FirstOrDefault();
if (_ExternoExistente == null)
{
externoNew = _repository.Add(externoNew);
}
else {
externoNew = _ExternoExistente;
}
if (!string.IsNullOrEmpty(externo.binaryImage))
{
var filename = string.Format("E{0}.jpg", externo.IdExterno);
string uploadFolder = WebConfigurationManager.AppSettings["UploadFolder"] != null ? WebConfigurationManager.AppSettings["UploadFolder"] : "upload";
string path = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, uploadFolder);
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
var imageExterno = ImageEngine.StringToImage(externo.binaryImage);
imageExterno.Save(Path.Combine(path, filename));
externoNew.dsPath = string.Concat("~/", uploadFolder, "/", filename);
_repository.Update(externoNew);
}
var externoDB = _repository.Get(externoNew.IdExterno);
string strPath = HostingEnvironment.ApplicationPhysicalPath;
scope.Complete();
return new ExternoApi()
{
IdExterno = externoDB.IdExterno,
dsNombre = externoDB.dsNombre,
dsApellido = externoDB.dsApellido,
dsDocumento = externoDB.dsDocumento,
IdCliente = externoDB.IdCliente,
binaryImage = !string.IsNullOrEmpty(externoDB.dsPath) ? ImageEngine.ImageToString(string.Concat(strPath, externoDB.dsPath.Replace("~/", "").Replace("/", "\\"))) : "",
dsPatente = externoDB.dsPatente,
};
}
catch (Exception ex)
{
scope.Dispose();
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
IApiLogRepository _repoLog = new ApiLogRepository();
var log = new ApiLog();
log.IdDispositivo = ValidateToken.IdDispositivo;
log.dsLog = string.Concat("Dispositivo: ", ValidateToken.IdDispositivo, "\n", ex.Message, "\n || \n", (ex.InnerException != null ? ex.InnerException.Message : ""), (ex.InnerException != null && ex.InnerException.InnerException != null ? ex.InnerException.InnerException.Message : ""));
log.dsRequest = serializer.Serialize(externo);
_repoLog.Add(log);
throw new DataRestrictDBException(string.Concat(ex.InnerException != null && ex.InnerException.InnerException != null ? ex.InnerException.InnerException.Message : (ex.InnerException != null ? ex.InnerException.Message : ex.Message), "Externo: ", externo));
}
}
}
either externo.dsDocumento or x.dsDocumento must be null
could do something like:
_externos.Where(x => x.dsDocumento != null && externoNew.dsDocumento != null && Regex.Replace(x.dsDocumento, pattern, "") == Regex.Replace(externoNew.dsDocumento, pattern, "")
I'm trying to search my inbox and all subfolders for a given string in the subject line. I found the following code online(https://www.add-in-express.com/creating-addins-blog/2012/05/31/outlook-search-csharp-vbnet/), but it returns zero results which is not the expected result.
I looked at the filter under view settings in outlook for a given search term that returns results in the outlook explorer and got this query: "http://schemas.microsoft.com/mapi/proptag/0x0037001f" LIKE '%Ticket%'
When I plug that in to the below code I likewise get zero results.
When I use LINQ to query those folders(LINQ is too slow to be a real solution here) I can get results so I'm guessing I'm making a syntactical error with advancedsearch. It is hard to find examples of usage on the web. I will appreciate anyone that can help me.
private Search RunAdvancedSearch(Outlook._Application OutlookApp, string wordInSubject)
{
string advancedSearchTag = "New Search";
string scope = "Inbox";
string filter = "\"urn:schemas:mailheader:subject\" LIKE '%"+ wordInSubject +"%'";
Outlook.Search advancedSearch = null;
Outlook.MAPIFolder folderInbox = null;
Outlook.MAPIFolder folderSentMail = null;
Outlook.NameSpace ns = null;
try
{
ns = OutlookApp.GetNamespace("MAPI");
folderInbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
folderSentMail = ns.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderSentMail);
scope = "\'" + folderInbox.FolderPath +
"\',\'" + folderSentMail.FolderPath + "\'";
advancedSearch = OutlookApp.AdvancedSearch(
scope, filter, true, advancedSearchTag);
System.Diagnostics.Debug.WriteLine(advancedSearch.Results.Count);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "An exception is thrown!");
}
finally
{
if (advancedSearch != null) Marshal.ReleaseComObject(advancedSearch);
if (folderSentMail != null) Marshal.ReleaseComObject(folderSentMail);
if (folderInbox != null) Marshal.ReleaseComObject(folderInbox);
if (ns != null) Marshal.ReleaseComObject(ns);
}
return advancedSearch;
}
I was not waiting long enough for the results. When AdvancedSearch(which runs in a separate thread) is finished it fires off an event called AdvancedSearchComplete. I had to tell the code to handle the event in order to wait for the search to complete.
In RunAdvancedSearch I do this in the Try with this:
Application.AdvancedSearchComplete += Application_AdvancedSearchComplete;
Here is the whole thing.
string advancedSearchTag = "MY FOOFOO Search";
//SEARCH Function
Search RunAdvancedSearch(Outlook.Application Application, string wordInSubject)
{
string scope = "Inbox";
string filter = "urn:schemas:mailheader:subject LIKE \'%" + wordInSubject + "%\'";
Outlook.Search advancedSearch = null;
Outlook.MAPIFolder folderInbox = null;
Outlook.MAPIFolder folderSentMail = null;
Outlook.NameSpace ns = null;
try
{
ns = Application.GetNamespace("MAPI");
folderInbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
folderSentMail = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
scope = "\'" + folderInbox.FolderPath + "\',\'" +
folderSentMail.FolderPath + "\'";
advancedSearch = Application.AdvancedSearch(
scope, filter, true, advancedSearchTag);
Application.AdvancedSearchComplete += Application_AdvancedSearchComplete;
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "An eexception is thrown");
}
finally
{
if (advancedSearch != null) Marshal.ReleaseComObject(advancedSearch);
if (folderSentMail != null) Marshal.ReleaseComObject(folderSentMail);
if (folderInbox != null) Marshal.ReleaseComObject(folderInbox);
if (ns != null) Marshal.ReleaseComObject(ns);
}
return advancedSearch;
}
//Handle AdvancedSearchComplete event
void Application_AdvancedSearchComplete(Outlook.Search SearchObject)
{
Outlook.Results advancedSearchResults = null;
Outlook.MailItem resultItem = null;
System.Text.StringBuilder strBuilder = null;
try
{
if (SearchObject.Tag == advancedSearchTag)
{
advancedSearchResults = SearchObject.Results;
System.Diagnostics.Debug.WriteLine("Count: " + advancedSearchResults.Count);
if (advancedSearchResults.Count > 0)
{
strBuilder = new System.Text.StringBuilder();
strBuilder.AppendLine("Number of items found: " +
advancedSearchResults.Count.ToString());
foreach (MailItem item in advancedSearchResults)
{
System.Diagnostics.Debug.WriteLine(item.Subject);
}
for (int i = 1; i <= advancedSearchResults.Count; i++)
{
resultItem = advancedSearchResults[i] as Outlook.MailItem;
if (resultItem != null)
{
strBuilder.Append("#" + i.ToString());
strBuilder.Append(" Subject: " + resultItem.Subject);
strBuilder.Append(" \t To: " + resultItem.To);
strBuilder.AppendLine(" \t Date: " +
resultItem.SentOn.ToString());
Marshal.ReleaseComObject(resultItem);
}
}
if (strBuilder.Length > 0)
System.Diagnostics.Debug.WriteLine(strBuilder.ToString());
else
System.Diagnostics.Debug.WriteLine(
"There are no Mail items found.");
}
else
{
System.Diagnostics.Debug.WriteLine("There are no items found.");
}
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "An exception is occured");
}
finally
{
if (resultItem != null) Marshal.ReleaseComObject(resultItem);
if (advancedSearchResults != null)
Marshal.ReleaseComObject(advancedSearchResults);
}
}
private void btnOutlookSrch_Click(object sender, EventArgs e)
{
Outlook.Application OLook = new Outlook.Application();
RunAdvancedSearch(OLook, "Hello?");
}
Your filter is working good, use Application:
private Search RunAdvancedSearch(Outlook.Application OutlookApp, string wordInSubject)
https://msdn.microsoft.com/en-us/library/office/microsoft.office.interop.outlook.application.aspx
Read about using _Application and Application in msdn "Remarks". There is very well written.
I have defined four custom user properties and i can not access to the in order to get their data, custom properties are present in outlook appointment but i can get to them :
My c# code below :
Outlook.ItemProperties itemProp = appointmentItem.ItemProperties;
foreach (Outlook.ItemProperty userprop in itemProp)
{
if (userprop.IsUserProperty)
{
MessageBox.Show(userprop.Name + "\t" + userprop.Value);
}
}
I have used an api(JWebServices) that creates appointment event into Outlook(2007 my version), in my code below i have created some CustomProperties, called in C# Addin Outlook UserPropertie.
I still can get the value of custom users properties that i have defined from the java side
PropertyName myRdvTypePropertyName = new PropertyName("RdvType", StandardPropertySet.PUBLIC_STRINGS);
ExtendedProperty myRdvTypeExtendedProperty = new ExtendedProperty(myRdvTypePropertyName, event.getTyperdv());
appointment.getExtendedProperties().add(myRdvTypeExtendedProperty);
PropertyName myRdvEmplacementPropertyName = new PropertyName("RdvEmplacement", StandardPropertySet.PUBLIC_STRINGS);
ExtendedProperty myRdvEmplacementExtendedProperty = new ExtendedProperty(myRdvEmplacementPropertyName, event.getLieu());
appointment.getExtendedProperties().add(myRdvEmplacementExtendedProperty);
PropertyName myRdvAdressePropertyName = new PropertyName("RdvAdresse", StandardPropertySet.PUBLIC_STRINGS);
ExtendedProperty myRdvAdresseExtendedProperty = new ExtendedProperty(myRdvAdressePropertyName, event.getEvent_location());
appointment.getExtendedProperties().add(myRdvAdresseExtendedProperty);
To be sure the custom user properties are created, i use Outlook SPY
the screenshot below:
the code below in the FormRegionShowing :
if (appointmentItem.UserProperties["RdvType"] != null)
{
this.TypeRdvComboBox.SelectedItem = appointmentItem.UserProperties["RdvType"].Value;
}
if (appointmentItem.UserProperties["RdvEmplacement"] != null)
{
this.emplacementRdvComboBox.SelectedItem = appointmentItem.UserProperties["RdvEmplacement"].Value;
}
if (appointmentItem.UserProperties["RdvAdresse"] != null)
{
this.adresseTextBox.Text = (string)appointmentItem.UserProperties["RdvAdresse"].Value;
}
Thanks for the inspiration, this works:
Outlook.MailItem mItem = (Outlook.MailItem)item;
string udpName = "";
string udpValueString = "";
Debug.Print(" mItem.UserProperties.Count: " + mItem.UserProperties.Count);
for (int i = 1; i <= mItem.UserProperties.Count; i++) {
udpName = mItem.UserProperties[i].Name;
var udpValue = mItem.UserProperties[i].Value;
udpValueString = udpValue.ToString();
Debug.Print(i + ": " + udpName + ": " + udpValueString);
}
Try using the UserProperties property and UserProperties class instead. Here is what MSDN states:
If you use UserProperties.Find to look for a custom property and the call succeeds, it will return a UserProperty object. If it fails, it will return Null. If you use UserProperties.Find to look for a built-in property, specify False for the Custom parameter. If the call succeeds, it will return the property as a UserProperty object. If the call fails, it will return Null. If you specify True for Custom, the call will not find the built-in property and will return Null.
using System.Runtime.InteropServices;
// ...
private void ShowUserProperties(Outlook.MailItem mail)
{
Outlook.UserProperties mailUserProperties = null;
Outlook.UserProperty mailUserProperty = null;
StringBuilder builder = new StringBuilder();
mailUserProperties = mail.UserProperties;
try
{
for (int i = 1; i < = mailUserProperties.Count; i++)
{
mailUserProperty = mailUserProperties[i];
if (mailUserProperty != null)
{
builder.AppendFormat("Name: {0} \tValue: {1} \n\r",
mailUserProperty.Name, mailUserProperty.Value);
Marshal.ReleaseComObject(mailUserProperty);
mailUserProperty = null;
}
}
if (builder.Length > 0)
{
System.Windows.Forms.MessageBox.Show(builder.ToString(),
"The UserProperties collection");
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
finally
{
if (mailUserProperties != null)
Marshal.ReleaseComObject(mailUserProperties);
}
}
Read more about that in the How To: Get Outlook e-mail item’s custom properties – C# and VB.NET samples article.