EWS how do I create a Searchfolder in my own mailbox? - c#

I use following Code to Create a SearchFolder but as it gets to the "Save" line it throws following error:
The email address associated with a folder Id does not match the
mailbox you are operating on.
private SearchFolder CreateSearchFolder( string email, SearchFilter filter)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
service.Credentials = new WebCredentials("mailboxworker", "password");
service.AutodiscoverUrl(email);
FolderId folderId = new FolderId(WellKnownFolderName.Inbox, new Mailbox(email));
FolderId searchFolderId = new FolderId(WellKnownFolderName.SearchFolders, new Mailbox(email));
// Create the folder.
SearchFolder searchFolder = new SearchFolder(service);
searchFolder.DisplayName = "Folder of " + email;
searchFolder.SearchParameters.SearchFilter = filter;
// Set the folder to search.
searchFolder.SearchParameters.RootFolderIds.Add(folderId);
// Set the search traversal. Deep will search all subfolders.
searchFolder.SearchParameters.Traversal = SearchFolderTraversal.Deep;
// Call Save to make the EWS call to create the folder.
searchFolder.Save(searchFolderId);
return searchFolder;
}
What am I doing wrong?

associated with a folder Id does not match the mailbox
All the times I've bumped into this I've fixed it using the Microsoft.Exchange.WebServices.Data WellKnownFolderName enum instead of a string folderId
Here is a working example from MSDN: Create a search folder by using the EWS Managed API
This example assumes that the ExchangeService object has been initialized with valid values in the Credentials and Url properties.
using Microsoft.Exchange.WebServices.Data;
static void CreateSearchFolder(string email)
{
// Create the folder.
SearchFolder searchFolder = new SearchFolder(service);
searchFolder.DisplayName = "From Developer";
// Create a search filter to express the criteria for the folder.
EmailAddress developer= new EmailAddress("Jeremy#stackoverflow.com");
SearchFilter.IsEqualTo fromManagerFilter = new SearchFilter.IsEqualTo(EmailMessageSchema.Sender, developer);
// Set the search filter.
searchFolder.SearchParameters.SearchFilter = fromManagerFilter;
// Set the folder to search.
searchFolder.SearchParameters.RootFolderIds.Add(WellKnownFolderName.Inbox);
// Set the search traversal. Deep will search all subfolders.
searchFolder.SearchParameters.Traversal = SearchFolderTraversal.Deep;
// Call Save to make the EWS call to create the folder.
searchFolder.Save(WellKnownFolderName.SearchFolders);
}
Here is another example on MSDN Creating search folders by using the EWS Managed API 2.0

Related

How do I check if folder and sub folder exist in Outlook using EWS Web Service & C#

I'm very new to C# development.
I'm trying to check and create a folder/ sub-folder exist in Outlook Mailbox using Exchange Web Service.
Folder Structure
MAIN_folder
Sub Folder-1
Sub Folder-2
Sub Folder-3
Implementation
public void checkFolderExistOrNot( String folder_name)
{
FolderView fv = new FolderView(100);
var findFoldersResults = exchangeService.FindFolders(
WellKnownFolderName.Inbox,
new SearchFilter.SearchFilterCollection(
LogicalOperator.Or,
new SearchFilter.ContainsSubstring(FolderSchema.DisplayName, folder_name)),
fv);
foreach (var folder in findFoldersResults)
{
if (folder is Folder)
{
if (folder.DisplayName == folder_name)
{
archiveFolderID = folder.Id;
}
}
}
//if archive folder not found create and assign the variable to the folderID
if (archiveFolderID == null)
{
Folder folder = new Folder(exchangeService);
folder.DisplayName = folder_name;
folder.Save(WellKnownFolderName.Inbox);
archiveFolderID = folder.Id;
}
}
checkFolderExistOrNot(MAIN_folder)
checkFolderExistOrNot(MAIN_folder.Sub Folder-1)
checkFolderExistOrNot(MAIN_folder.Sub Folder-2)
checkFolderExistOrNot(MAIN_folder.Sub Folder-3)
But this is only creating the Main folder under the inbox. It would be greatly appreciated if someone could help me to identify what is missing in my implementation.
Thanks in Advance.
The only way to tell if a folder exists is to search for it with your search because you don't specify the traversal in the Folderview it will always be shallow. If you specify a deep traversal in
FolderView fv = new FolderView(100);
fv.Traversal = FolderTraversal.Deep;
You should then be able to find the parent folder you want to create a new subfolder on. Your logic should work okay as long as you don't have any name clashes a different folder levels. Otherwise what I do is this Exchange Web Service FolderId for a folder created by user or Get to an Exchange folder by path using EWS
Have you given Microsoft Graph a look?
You can basically use it for anything in Microsoft 365. With you you can also achieve your goal.
You will need to create a GraphServiceClient and with it you can do the following to check if a folder exists:
string user = "emailAddressOfTheUser";
var parentFolderRequest = graphClient.Users[user].MailFolders.Inbox.ChildFolders
.Request()
.Filter($"startsWith(displayName, 'parentFolderName')");
var parentMailFolder = await parentFolderRequest.GetAsync(cancellationToken);
Once you have the parent folder you can get it's ID and once you know that you can search it for child folders:
var parentMailFolderID = parentMailFolder.First().Id;
var childFolderRequest = graphClient.Users[user].MailFolders[parentMailFolderID].ChildFolders
.Request()
.Filter($"startsWith(displayName, 'childFolderName')");
var childMailFolder = await parentFolderRequest.GetAsync(cancellationToken);
If the childMailFolder.Count > 0 then the folder exists, if not you create the child folder:
var childFolder = new MailFolder
{
DisplayName = "childFolderName",
IsHidden = false
};
await graphClient.Users[graphUser.Id]
.MailFolders[parentMailFolderID].ChildFolders
.Request()
.AddAsync(childFolder );

MOSS 2007, programmatically downloading document folder; Can't connect to Document folder

I'm attempting to programmatically download all files from a document folder on a Sharepoint 2007 site. So far, I'm able to connect to the site, but am having issues connecting to the folders and download them.
try{
using(SPSite site = new SPSite("http://mysharepointserver/sites/subsite")){
using(SPWeb web = site.OpenWeb()){
Console.Write("Connected to site");
SPFolder testFolder = web.Folder["testFolder"];
//example method downloading folder
downloadFolder(testFolder);
}
}
}
catch(Exception e){
Log(e.ToString());
}
My console write works,so I know I am connecting to the site correctly.
My log file outputs:
System.ArgumentException: Value does not fall within the expected range.
at Microsoft.SharePoint.SPListCollection.GetListByName(String strListName, Boolean bThrowException)
at Microsoft.SharePoint.SPListCollection.get_Item(String strListName)
I also attempted to print out the following:
using(SPWeb web = site.OpenWeb()){
Console.Write("Connected to site");
Console.Write(web.lists);
SPFolder testFolder = web.Folder["testFolder"];
//example method downloading folder
downloadFolder(testFolder);
}
Which outputs the following to console:
Connected to site
Microsoft.SharePoint.SPListCollection
But I'm not certain how to navigate through SPListCollection to retrieve my folder "testFolder"
Any help would be appreciated. Thanks!
When you connect to share point site, there are different types of libraries. Library that contains documents and folders is DocumentLibrary and not ListLibrary. Once you have the item / library by ID, cast it to correct SPDocumentLibrary to retrieve items you want.
Use https://learn.microsoft.com/en-us/dotnet/api/microsoft.sharepoint.spdocumentlibrary?view=sharepoint-server to get different methods and properties of DocumentLibrary to retrieve the testFolder.
Example of accessing document library item from :https://social.msdn.microsoft.com/Forums/en-US/5ee7fb55-5d90-4d28-8990-bf00479f891f/how-to-get-spdocumentlibrary?forum=sharepointdevelopmentprevious
SPSite siteCollection = this.Site;
SPWeb site = this.Web;
// obtain query string values
string ListId = Request.QueryString["ListId"];
string ItemId = Request.QueryString["ItemId"];
// create list object and list item object
SPList list = site.Lists[new Guid(ListId)];
SPListItem item = list.Items.GetItemById(Convert.ToInt32(ItemId));
// query for information about list and list item
string ListTitle = list.Title;
string ItemTitle = item.Title;
if (list is SPDocumentLibrary) {
SPDocumentLibrary documentLibrary = (SPDocumentLibrary)list;
string DocumentTemplateUrl = documentLibrary.DocumentTemplateUrl;
SPFile file = item.File;
string FileAuthor = file.Author.Name;
string FileSize = file.TotalLength.ToString("0,###") + " bits";
}

Accessing Shared Contacts with EWS Managed API (Exchange 2010)

I'm currently working on a project where I need to get Information from shared contacts (name, mailadress, etc) to compare multiple shared folders and find duplicate entries.
I'm coding in Visual Studio 2015. The program is just a console Application that creates an excel sheet, where the duplicate contacts are marked.
The Exchange Server is 2010 SP1.
The contacts are shared via E-Mail.
I have no problem to get acces to my own contacts. But I can't get to the folders that are shared to me.
I tried to follow this Guide.
But unfortunately this line gives me a nullpointer exception.
NameResolutionCollection ncCol = service.ResolveName(lnLegDN, ResolveNameSearchLocation.DirectoryOnly, true);
if (ncCol.Count > 0)
And further on I don't really understand what this part is supposed to to anyways, so I can't really fix it. It's my first time working with the EWS Managed API.
After changing the code I am able to get acces to the contacts folder from another mailbox. But that is not the folder that is shared to me.
So my question is, how can I get a contactsfolder that is named "CheckForDuplicates" for example. Is there a way?
Here is the code I changed in the above example. I'm getting the name of the mail box owner and than look for their contacts. After that I call a routine that gets the needed information from all contacts within that folder.
foreach (Item itItem in fiResults.Items)
{
object WlinkStoreEntryId = null;
if (itItem.TryGetProperty(PidTagWlinkStoreEntryId, out WlinkStoreEntryId))
{
string lookup = itItem.Subject;
string[] lookupArr = lookup.Trim().Split(new Char[] {'-'});
NameResolutionCollection ncCol = service.ResolveName(lookupArr[0], ResolveNameSearchLocation.DirectoryOnly, true);
if (ncCol.Count > 0)
{
try
{
Console.WriteLine(itItem.Subject);
FolderId SharedContactsId = new FolderId(WellKnownFolderName.Contacts, ncCol[0].Mailbox.Address);
Folder SharedContactFolder = Folder.Bind(service, SharedContactsId);
rtList.Add(ncCol[0].Mailbox.Address, SharedContactFolder);
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
}
}
I found the solution.
And it's way easier than expected.
I realized that I should look for Folders in the WellKnownFolderName.Root and not in WellKnownFolderName.Contacts.
Because the WellKnownFolderName.Contacts is reserved for the Contacts-Folder. And not like I thought for all contactfolders.
FolderId sharedRootFolderid = new FolderId(WellKnownFolderName.Root, ncCol[0].Mailbox.Address);
FolderView sharedFolderView = new FolderView(1000);
sharedFolderView .PropertySet = new PropertySet(BasePropertySet.IdOnly);
sharedFolderView .PropertySet.Add(FolderSchema.DisplayName);
sharedFolderView .Traversal = FolderTraversal.Deep;
SearchFilter testSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "CheckForDuplicates");
FindFoldersResults sharedContacts = service.FindFolders(sharedRootFolderid , testSearchFilter, sharedFolderView);
And that's already it.

List all users assigned to a calendar using EWS C#/Powershell

I have an exchange server that list 27 calendars. I need to communicate with this server to figure out what users are assigned to what calendar. I'm not good with PowerShell and i know this can be used to retreive the information i may need. I'd preffer to use Microsoft.Exchange.Webservice.Data but i dont beleive there is a way to retreive this information using this. The code below is what im using to connect with EWS and thus far is not a problem Im just looking for the best way to query what users have access to a calendar.
static void Main(string[] args)
{
ExchangeService service = new ExchangeService (ExchangeVersion.Exchange2010_SP2);
//***********New**********************
ExchangeService mailbox = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
string mailboxEmail = "JNichols#example.org";
WebCredentials wbcred = new WebCredentials("exampleUsername", "examplePassword");
mailbox.Credentials = wbcred;
// mailbox.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailboxEmail);
mailbox.AutodiscoverUrl(mailboxEmail, RedirectionUrlValidationCallback);
mailbox.HttpHeaders.Add("X-AnchorMailBox", mailboxEmail);
FolderId mb1Inbox = new FolderId(WellKnownFolderName.Inbox, mailboxEmail);
//SetStreamingNotification(mailbox, mb1Inbox);
mailbox.Url = new Uri("https://webmail.example.org/EWS/Exchange.asmx");
Dictionary<string, Folder> x = GetSharedCalendarFolders(mailbox, mailboxEmail);
}
internal static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
//The default for the validation callback is to reject the URL
bool result=false;
Uri redirectionUri=new Uri(redirectionUrl);
if(redirectionUri.Scheme=="https")
{
result=true;
}
return result;
}
In the Exchange Management Shell, you can do:
$CalendarPermissions = Get-MailboxFolderPermission -Identity jnichols#example.org:\Calendar
Which will return all permissions set on the mailbox calendar - each entry has a User property - the user or group that the permission/access right has been granted to:
$CalendarPermissions | Select User,AccessRights

Eml to pst Redemption C# -> Null Exception RDOMail

i'm trying to create a program that conver eml file into a single pst.
i have write that command:
RDOSession session = new RDOSession();
RDOPstStore store = session.LogonPstStore(newpstpath);
RDOFolder folder = store.IPMRootFolder.Folders.Item(directoryEmlFile);
RDOMail mail = folder.Items.Add("IPM.Note");
but at the command "RDOMail mail = folder.Items.Add("IPM.Note")" the system give me the null exception. can anyone help me?
You need to differ Outlook and Redemption objects.
It looks like you need to use the GetRDOObjectFromOutlookObject method of the Session class (Redemption).
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set redItem= Session.GetRDOObjectFromOutlookObject(mail)
The Add method of the Items class creates and returns a new Outlook item in the Items collection for the folder.
Most likely the folder variable is null - if the folder does not exist, retrieving it by name (RDOFolder.Folders.Item("foldername")) will return null:
RDOSession session = new RDOSession();
RDOPstStore store = session.LogonPstStore(newpstpath);
RDOFolder folder = store.IPMRootFolder.Folders.Item(directoryEmlFile);
if (folder == null) folder = store.IPMRootFolder.Folders.Add(directoryEmlFile);
RDOMail mail = folder.Items.Add("IPM.Note");

Categories

Resources