I´m trying to write an application to set Alerts on a list for all people that are already having minimum one alert in the sitecollection. I know how to get the user objects for all this users, but when I try to set the alert for each user there appears the problem. For some users there comes an SPException that says that the list is not existing. I looked in the user.Alerts propertie and there is a field Web, where the sitecollection name is at the users that dont work. It works only for the users that have the right web in there to access the list and set the alert. Does anyone know a workaround so that i can set alert for all the users that i want?
Here is the code I´m using to set the alerts:
SPAlert alert = user.Alerts.Add();
alert.AlertType = SPAlertType.List;
alert.EventType = SPEventType.Add;
Console.WriteLine(alertWeb.Url+" "+ alertingListName);
alert.List = alertWeb.Lists.TryGetList(alertingListName);
alert.AlertFrequency = SPAlertFrequency.Immediate;
alert.AlwaysNotify = false;
alert.Update(false);
Thanks in advance for helping me
I have solved the problem on myself now. I post the solution here so people who have the same problem can find it.
The problem was that in the User Object propertie user.alerts.web was the wrong web. I solved this problem by getting the user object not from the web.alerts collection but from the web.allusers collection, so that the right web stands in the propertie.
Related
I am writing an application that creates an overview of peoples Outlook calendars, i.e it will show the amount of unplanned time per week for the coming [n] weeks.
The basics are working, but there's one thing that I am having trouble with. Some users have shared their Outlook calendar in a way so that other users can only see availability information (the time and description of the appointments), but not any details.
I verified this by opening Outlook manually and opening a shared calendar; hovering the mouse over an appointment will show a popup with begin and end time, description and location, but double clicking it gives an error: "You are not authorized to display the calendar, do you want to ask [person] to share it?".
The relevant lines from my code are:
var outlook = new Application();
var mapiNamespace = outlook.GetNamespace("MAPI");
var recipient = mapiNamespace.CreateRecipient("Scott");
recipient.Resolve();
var calendarFolder = mapiNamespace.GetSharedDefaultFolder(recipient, OlDefaultFolders.olFolderCalendar);
var calendarItems = calendarFolder.Items;
Everything I now try to do with calendarItems will raise an exception. For instance, getting Count will raise a TargetInvocationException (The client process failed, but I'm not quite sure about the exact English translation). Calling Sort("[Start]") will raise a COMException with message Unknown property: Start. Both do work for fully shared calendars.
Now, for the overview, all I need is begin and end times, so I don't really want to ask everyone to change their sharing settings, especially when that shouldn't be necessary.
My questions are:
Most important: Is there another way to get availability info that I'm overlooking?
And related: Is Interop still the way to go these days, or are there alternatives? Maybe an Office365 webservice?
Instead of using GetSharedDefaultFolder and accessing the items in that folder, you can use Recipient.FreeBusy method.
If you view a SharePoint calendar in MS Outlook and change the color of that item in Outlook, the SharePoint ows_MetaInfo gets changed from this:
2362;#
to This:
2362;#vti_encoding:SR|utf8-nl
FollowUp:SW|
vti_serverversion:SW|2
vti_versionhistory:SW|473e1c0c47cf034d9969c8513def1903:4
vti_clientversion:SW|4
BusyStatus:SW|2
Categories:SW|Red Category
Priority:SW|
IntendedBusyStatus:SW|
vti_externalversion:IW|3
I have a C# program that creates the SP calendar entry but I would like to be able to modify this ows_MetaInfo Categories property so that I can color code these items so that users that view this in Outlook will see these color codes.
I have searched on everything that I can thing of. I have seen people reading this ows_MetaInfo data but nothing that says how it can be changed. As stated earlier, I'm doing this in C# and I would like to change the ows_MetInfo Categories property so that Outlook users will see color coded calendar entries.
Any help would be Greatly Appreciated!
I've been searching around for quite some time to figure this out and I overlooked the most obvious answer... :) All I had to do was ask for help for me to finally figure it out! LOL :D
MetaInfo is just another String field. When you make a color change in Outlook to a SharePoint attached calendar item it, just adds text to that field that specifies the color along with some other default items. To change the color you can just specify it with something like cListItem["MetaInfo"] = "Categories:SW|Red Category\r\n"; and it will just change the Categories field leaving the others alone.
For completeness, I'm going to post my entire test example. (Because I hate it when I find the answer to a problem but only part of the answer is posted leaving me to guess at what else was in the code that made the example actually work :) )
This is done is VS2013 using a Console App
using Microsoft.SharePoint.Client;
using SP = Microsoft.SharePoint.Client;
using System.Net;
namespace SharePointSetMetaInfo
{
class Program
{
static void Main(string[] args)
{
using (ClientContext context = new ClientContext("https://mySharePointServer/sites/MySite/"))
{
context.Credentials = new NetworkCredential("myUserName", "myPassword", "MYDOMAIN");
SP.List calendarList = context.Web.Lists.GetByTitle("Calendar");
ListItem cListItem = calendarList.GetItemById(2301);//This is one way to retrieve an item for update. You can also use a Caml Query
context.Load(cListItem);
cListItem["MetaInfo"] = "Categories:SW|Red Category\r\n";
cListItem.Update();
context.ExecuteQuery();
}
}
}
}
Hopefully this helps someone else who is trying to programmatically change the colors on SharePoint calendar items as they show up in Outlook. This is not applicable to how SharePoint calendar items appear in SharePoint, only Outlook.
I only want the room's email to receive an invitation, not the other requiredAttendees. However, the "Save()" method appears to only have a send to all or none type of setup. Does anyone have a solution?
appointment.Subject = myAppointmentInfo.ClassName;
appointment.Body = "";
appointment.Start = myAppointmentInfo.StartDateTime;
appointment.End = myAppointmentInfo.EndDateTime;
appointment.Location = myAppointmentInfo.Location;
appointment.ReminderMinutesBeforeStart = 5;
appointment.RequiredAttendees.Add(employeeEmail1);
appointment.RequiredAttendees.Add(employeeEmail2);
appointment.RequiredAttendees.Add(roomEmail);
appointment.Save(SendInvitationsMode.SendToNone);
I have a partial solution to this now. What I ended up doing was this:
var calendar = Folder.Bind(service, new FolderId(WellKnownFolderName.Calendar, roomEmail));
appointment.Save(calendar.Id, SendInvitationsMode.SendToNone);
It allowed me to send to only the roomEmail, but still have the other required attendees show up on the list of Required Attendees.
This solved my initial problem, but now I need to learn how to do something similar for my appointment updates and deletes (which is proving to be more difficult). If you know how to do these things please let me know! Thanks
UPDATE: I found my issue with this problem as well. To do updates and deletes without sending notifications to the attendees, use:
appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);
for updates, and:
appointment.Delete(DeleteMode.SoftDelete, SendCancellationsMode.SendToNone);
my biggest issue before was that I was setting the DeleteMode type to "MoveToDeletedItems" instead of "SoftDelete".
I'am running across this issue when I'm debugging or running my coded UI automation project, where i get the exception labeled "{"COM object that has been separated from its underlying RCW cannot be used." System.Exception {System.Runtime.InteropServices.InvalidComObjectException}" everytime i come from a browser window that contains a pdf reader embedded in it. This happens every time I retrieve the window and try to click back. It barfs when i perform the back method on it. I've tried different things but none has worked including the playback wait.
var hereIsmypdf = ReturnPDFDoc();
public BrowserWindow ReturnPDFDoc()
{
Playback.Wait(1000);
var myPdFdoc = GlobalVariables.Browser;
return myPdFdoc;
}
hereIsmypdf.Back();
The only way i was able to get around this issue was not to use the BrowserWindow class. I ended up using the WinWindow class and just getting the tab of the window from it. The BrowserWindow class seemed to trigger the exception "COM object that has been separated from its underlying RCW cannot be used." System.Exception {System.Runtime.InteropServices.InvalidComObjectException}" everytime i tried to retrieve it. I hope this helps someone one or maybe someone has a better way to handle this issue.
For the people that voted my question down, i really did try to figure it out. Sorry i wasnt clear about what i was asking the community or couldn't properly articulate what this pain was. I'm sure someone probably is going through the same pain i did and having a hard time articulating whats going on.
Here is my code on what i ended up doing
public WinTabPage ReturnPDFDoc()
{
WinWindow Wnd = new WinWindow();
Wnd.SearchProperties[BrowserWindow.PropertyNames.ClassName] = "IEFrame";
WinTabList tabRoWlist = new WinTabList(Wnd);
tabRoWlist.SearchProperties[WinTabPage.PropertyNames.Name] = "Tab Row";
WinTabPage myTab = new WinTabPage(tabRoWlist);
myTab.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
myTab.SearchProperties[WinTabPage.PropertyNames.Name] = "something";
//UITestControlCollection windows = newWin.FindMatchingControls();
return myTab;
}
I need to get the direct reports from a logged in user (MVC 4)
I don't need the names of the direct reports but I do need their email addresses including their proxy addresses.
So for this reason I need to search through Exchange. I personally have never attempted to search Exchange in the past and everything I find out there tells me how to get from step 8 to the finish line but says nothing about how to go from step 1 to 8.
I can get the current users user name by simply
User.Identity.Name.Replace(#"yourdomain\", "")
and I have found this example which so far is probably the best example I have found
http://msdn.microsoft.com/en-us/library/office/ff184617(v=office.15).aspx
but even with that example the line
Outlook.AddressEntry currentUser =
Application.Session.CurrentUser.AddressEntry;
is not actually getting the current user logged into the site.
I really hope someone out there is familiar with this and can get me past this point.
I reworked the sample from the URL as the following LINQPad 4 query. I've found that LINQPad is a great way to experiment because it is very scripty, allowing quick experimentation, and you can easily view data by using the Dump() extension method. Purchasing intellisense support is totally worthwhile.
Also, I noticed there is a lot of fine print like:
The logged-on user must be online for this method to return an AddressEntries collection; otherwise, GetDirectReports returns a null reference. For production code, you must test for the user being offline by using the _NameSpace.ExchangeConnectionMode property, or the _Account.ExchangeConnectionMode property for multiple Exchange scenarios.
and
If the current user has a manager, GetDirectReports() is called to return an AddressEntries collection that represents the address entries for all the direct reports of user’s manager. If the manager has no direct reports, GetDirectReports returns an AddressEntries collection that has a count of zero.
So there are a lot of assumptions like Exchange is configured properly with Direct Report relationships, and the current user is online...which I believe brings Lync into the equation. Hopefully this LINQPad query will be useful to you. Just copy and paste it into a text editor and name it with the .linq file extension. You'll then be able to open it in LINQPad 4. BTW: You're question caught my attention because there was talk recently at my work of pulling direct reports from Active Directory. I wish I could be more helpful...good luck.
<Query Kind="Program">
<Reference><ProgramFilesX86>\Microsoft Visual Studio 12.0\Visual Studio Tools for Office\PIA\Office15\Microsoft.Office.Interop.Outlook.dll</Reference>
<Reference><ProgramFilesX86>\Microsoft Visual Studio 12.0\Visual Studio Tools for Office\PIA\Office15\Microsoft.Office.Interop.OutlookViewCtl.dll</Reference>
<Namespace>Microsoft.Office.Interop.Outlook</Namespace>
</Query>
void Main()
{
GetManagerDirectReports();
}
// Define other methods and classes here
private void GetManagerDirectReports()
{
var app = new Microsoft.Office.Interop.Outlook.Application();
AddressEntry currentUser = app.Session.CurrentUser.AddressEntry;
if (currentUser.Type == "EX")
{
ExchangeUser manager = currentUser.GetExchangeUser().GetExchangeUserManager();
manager.Dump();
if (manager != null)
{
AddressEntries addrEntries = manager.GetDirectReports();
if (addrEntries != null)
{
foreach (AddressEntry addrEntry in addrEntries)
{
ExchangeUser exchUser = addrEntry.GetExchangeUser();
StringBuilder sb = new StringBuilder();
sb.AppendLine("Name: " + exchUser.Name);
sb.AppendLine("Title: " + exchUser.JobTitle);
sb.AppendLine("Department: " + exchUser.Department);
sb.AppendLine("Location: " + exchUser.OfficeLocation);
sb.Dump();
}
}
}
}
}
I would suggest using EWS Managed API in conjunction with your code to get the direct reports for a user. As Jeremy mentioned in his response that you need to have your direct report relationships already set up. To help you get started, here some steps to get EWS Managed API up and running:
Download the latest version of EWS Managed API
Get started with EWS Managed API client applications to learn about how to reference the assembly, set the service URL, and communicate with EWS.
Start working with your code. If you need some functioning code to get you going, check out the Exchange 2013 101 Code Samples that has some authentication code already written and a bunch of examples you can modify to make your own.
If you have the email address or user name of the current user you can use the ResolveName() method to get to their mailbox to retrieve additional information. Here is an article to help with that method: How to: Resolve ambiguous names by using EWS in Exchange 2013
Essentially you want to get to the point where you can run a command similar to this:
NameResolutionCollection coll = service.ResolveName(NameToResolve, ResolveNameSearchLocation.DirectoryOnly, true, new PropertySet(BasePropertySet.FirstClassProperties));
If you give a unique enough value in the NameToResolve parameter you should only get back one item in the collection. With that, you can look at the direct reports collection within that one item and see not only the names of their direct reports, but their email addresses as well.
I hope this information helps. If this does resolve your problem, please mark the post as answered.
Thanks,
--- Bob ---