I'm trying to retrieve a name of the persdon who completed a task. In my Tasks list i can see 'Modified By' which is Editor.
In Sharepoint Manager I can see the persons name in the Editor column.
How can I get this value in the code
I create a task and after the ontaskchanged I have a code block. I've tried many permutations but cannot retrieve this data.
private void UpdateCreatedByAndModifiedByFieldData(string strSiteUrl, string strListName, string strUserFieldName)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(strSiteUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists[strListName];
foreach (SPListItem listItem in list.Items)
{
//Read user id from a list column of user type and create SPUser object
SPUser user = web.EnsureUser(listItem[strUserFieldName].ToString().Trim());
if (user != null)
{
string userValue = user.ID + ";#" + user.Name;
//Assign the above user to the "Created By" column
listItem["Author"] = userValue;
//Assign the above user to the "Modified By" column
listItem["Editor"] = userValue;
//Call the update method to apply the above changes
listItem.Update();
web.Update();
}
}
}
}
});
}
catch (Exception ex)
{
throw ex;
}
}
Check this also
How to get SharePoint file creator name using AllDocs table?
Related
I created an event receiver that should trigger a SharePoint designer workflow, however this never happens. This part of the code never evaluates to true for the guid and workflow association: if (association.BaseId == workflowGuid). I am a bit stumped and not quite sure why it's not working. Any insight would be appreciated...and my code is below. Basically when an item is added to my list, it should trigger my Sharepoint designer workflow but this never happens and I can manually start the workflow fine.
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
startWF(properties);
}
private void startWF(SPItemEventProperties properties)
{
try
{
//bool startWF = false;
string strWorkflowID = "{c66ff94f-ba7c-4495-82fe-e73cdd18bad9}";
//string statusVal = properties.AfterProperties["eRequest Division"].ToString();
SPListItem li = properties.ListItem;
//using (SPWeb web = li.Web)
using (SPWeb web = properties.OpenWeb())
{
using (SPSite site = web.Site)
{
SPWorkflowManager mgr = site.WorkflowManager;
SPList parentList = li.ParentList;
//SPList list = web.Lists["Charitable and Political"];
SPWorkflowAssociationCollection associationCollection = parentList.WorkflowAssociations;
LookUpAndStart(li, mgr, associationCollection, "{c66ff94f-ba7c-4495-82fe-e73cdd18bad9}");
}
}
}
catch (Exception ex)
{
}
}
private static void LookUpAndStart(SPListItem listItem, SPWorkflowManager mgr, SPWorkflowAssociationCollection associationCollection, string workflowID)
{
foreach (SPWorkflowAssociation association in associationCollection)
{
Guid workflowGuid = new Guid(workflowID);
//if (association.Name.ToLower().Equals(workflowGuid))
//if (association.BaseId == workflowGuid)
//if (association.BaseId.ToString("B").Equals(workflowGuid))
if (association.BaseId == workflowGuid)
{
string data = association.AssociationData;
SPWorkflow wf = mgr.StartWorkflow(listItem, association, data, true);
break;
}
}
}
}
}
In my case the following was the problem.
Declarative workflows will not start automatically if the following conditions are true:
The Windows SharePoint Services Web application runs under a user's domain account.
The user logs in by using this domain account.
The site displays the user name as System Account.
I want to track if the users have read sharepoint 2010 document center's documents, currently user infos are not stored in audit logs, is there any way to do it?
It gets stored in audit logs.
Enable auditing for that particular document library and then get the details using the following code:
SPSite oSPsite = new SPSite
SPList doclib= oSPWeb.Lists["doclib"];
SPWeb oSPWeb = oSPsite.OpenWeb()
SPListItemCollection doclibitems= doclib.Items;
foreach (SPListItem odoclibItem in doclibitems)
{
odoclibItem .Audit.AuditFlags = SPAuditMaskType.View;
// odoclibItem .Audit.AuditFlags = SPAuditMaskType
SPAuditQuery oquery = new SPAuditQuery(oSPsite);
oquery.RestrictToListItem(odoclibItem );
odoclibItem .Audit.Update();
SPAuditEntryCollection oAuditEntryCollection =SPsite.Audit.GetEntries(oquery);
foreach (SPAuditEntry entry in oAuditEntryCollection)
{
if (entry.Event == SPAuditEventType.View)
{
id = Convert.ToString(entry.UserId);
// get the user name and other details here
}
}
}
I found the solution. Here is the steps.
1- Create a class library.
2- Right click the library and add new item.
3- Select ASP.NET Module under Web node.
4- Add PreRequestHandlerExecute event handler inside Init.Here is my code.
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += context_PreRequestHandlerExecute;
}
5- Methods
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
var app = sender as HttpApplication;
if (app != null)
{
string requesturl = app.Request.Url.ToString();
string file = string.Empty;
// if document opens in browser
if (app.Request.QueryString["Source"] != null && app.Request.QueryString["id"] != null && app.Request.QueryString["Source"].StartsWith(documentSiteUrl))
{
file = app.Request.QueryString["id"].Remove(0, app.Request.QueryString["id"].LastIndexOf('/'));
Worker(file);
}
// if document opened installed office apps or downloaded the document
if (requesturl.StartsWith(SiteUrl))
{
requesturl = requesturl.Remove(0, requesturl.LastIndexOf('/') + 1);
Worker(requesturl);
}
}
});
}
private void Worker(string requesturl)
{
#region ext control
List<string> extList = new List<string>(Exts.Split(';'));
bool result = false;
foreach (string item in extList)
{
if (requesturl.EndsWith(item))
{
result = true;
break;
}
}
#endregion
if ((!requesturl.Contains(".aspx")) && (!requesturl.EndsWith("/")) && result)
{
SPWeb web = SPContext.Current.Web;
String fileName = requesturl.Substring(requesturl.LastIndexOf("/") + 1);
// Add log
web.AllowUnsafeUpdates = true;
AddReadInfo(web.CurrentUser, fileName, web);
web.AllowUnsafeUpdates = false;
}
}
private void AddReadInfo(SPUser sPUser, string fileName, SPWeb web)
{
#region Logging
SPList logList = web.Lists.TryGetList("LogList");
if (logList != null)
{
SPListItem item = logList.Items.Add();
item["User"] = sPUser.Name;
item["Document"] = fileName;
item["Read"] = "Read";
item.Update();
}
#endregion
}
6- Don't forget signing the project.
7- Build Project.
8- Add dll to GAC and BIN folder under the C:\inetpub\wwwroot\wss\VirtualDirectories\80\ folder.
9- Open IIS Manager.
10- Find your site nod and select.
11- Open Modules.
12- Right click under modules page and select Add Managed Module option.
13- Give a name and select your module under dropdownlist.
14- IIS reset.
I have list of clients through which i have created SharePoint user groups with this code.
namespace CreateGroupCSharp.EventReceiver1
{
public class EventReceiver1 : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
using (SPSite site = new SPSite("http://abc/"))
{
SPWeb web = site.AllWebs[0];
SPList customList = web.Lists["Client"];
string strCount = properties.ListItem.Title.ToString();
string status = properties.Status.ToString();
SPGroup groupOwner = web.SiteGroups.GetByID(int.Parse(web.Properties["vti_associateownergroup"]));
string groupName = strCount;
web.SiteGroups.Add(groupName, groupOwner, null, "Custom SharePoint Group for Demo");
SPGroup wcmGroup = web.SiteGroups[groupName];
SPRoleDefinition designerRoleDefinition = web.RoleDefinitions["Contribute"];
SPRoleAssignment roleAssignment = new SPRoleAssignment(wcmGroup);
roleAssignment.RoleDefinitionBindings.Add(designerRoleDefinition);
web.RoleAssignments.Add(roleAssignment);
wcmGroup.Update();
web.Update();
}
base.ItemAdded(properties);
}
}
}
Is it possible to create users for each client in SharePoint list itself?
How can I assign these created groups to the the users in list?
I would add a Person or Group column named Users to your list. Allow multiple selections and allow people only (no groups) to be selected. You can then add the users to the group using the following code in your event receiver:
private void AddUsers(SPWeb web, SPGroup group, SPListItem item)
{
object value = item["Users"];
if (null != value)
{
SPFieldUserValueCollection userValues =
new SPFieldUserValueCollection(web, value.ToString());
foreach (SPFieldUserValue userValue in userValues)
{
SPUser user = userValue.User;
if (null == user)
{
user = web.EnsureUser(userValue.LookupValue);
}
group.AddUser(user.LoginName, user.Email, user.Name, null);
}
}
}
I got an exception when executing this snippet code
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(siteUrl.Trim()))
{
using (SPWeb web = site.OpenWeb())
{
try
{
web.AllowUnsafeUpdates = true;
SPUser spUser = web.AllUsers[userName];
if (spUser != null)
{
SPGroup spGroup = web.Groups[groupName];
if (spGroup != null)
spGroup.AddUser(spUser);
}
}
catch (Exception ex)
{
this.TraceData(LogLevel.Error, "Error at function Named [AddUserToSPGroupWidget.AddUserToGroup] . With Error Message: " + ex.ToString());
}
finally
{
web.AllowUnsafeUpdates = false;
}
}
}
});
PLease guide me. Thanks in advance.
I don’t know what your exact exception is, but you can try to do following changes:
Instead of
SPUser spUser = web.AllUsers[userName];
use (it will ensure that user exists on the web)
SPUser spUser = web.EnsureUser(userName);
Instead of
SPGroup spGroup = web.Groups[groupName];
use (Groups collection contains only groups that are defined on the current sub web)
SPGroup spGroup = web.SiteGroups[groupName];
There is no need to check (spGroup != null) because if group is not found then always exception will be thrown.
Using the following block of code, the listItem.Update fails with a NullReferenceException:
SPWeb web = null;
SPList list = null;
SPListItem listItem = null;
try
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(this.SiteUrl))
{
web = site.OpenWeb();
list = web.Lists[this.ListName];
listItem = list.Items.Add();
listItem["Background"] = "foo";
}
}
);
listItem.Update();
}
catch
{
}
finally
{
web.Dispose();
}
If I move the listItem.Update() method inside of the anonymous delegate, I get "Operation is not valid due to the current state of the object."
Yes, I've combed through SO and have tried many permutations without success.
Any ideas?
Update:
After the first comment, I tried to remove the anonymous delegate from the code to see if it fared any better:
// store the selected item to pass between methods
public T SelectedItem { get; set; }
// set the selected item and call the delegate method
public virtual void Save(T item)
{
SelectedItem = item;
try
{
SPSecurity.RunWithElevatedPrivileges(SaveSelectedItem);
}
catch
{
}
}
public virtual void SaveSelectedItem()
{
if (SelectedItem != null)
{
using (SPSite site = new SPSite(this.SiteUrl))
{
using(SPWeb web = site.OpenWeb())
{
SPList list = web.Lists[this.ListName];
SPListItem listItem = list.Items.Add();
//UpdateListItem(listItem, SelectedItem);
listItem["Background"] = "foo";
listItem.Update();
}
}
}
}
And this still fails "Operation is not valid due to the current state of the object." In both code samples, it looks like site.Impersonating is false. I am using Windows Auth, and Impersonation in the web.config. This is running from the ASP.Net Development server.
I found an example from this site (blackninjasoftware). I create a reference to the site, grab its SystemAccount token and then create another reference to the site, using the admin token. It seemed a little hackish to me at first - but hey - I have a deadline.
Final working method body now looks like:
SPListItem new_item = null;
SPSite initialSite = new SPSite(this.SiteUrl);
using (var site = new SPSite(this.SiteUrl, initialSite.SystemAccount.UserToken))
{
// This code runs under the security context of the SHAREPOINT\system
// for all objects accessed through the "site" reference. Note that it's a
// different reference than SPContext.Current.Site.
using (var elevatedWeb = site.OpenWeb())
{
elevatedWeb.AllowUnsafeUpdates = true;
SPList list = elevatedWeb.Lists[this.ListName];
new_item = list.Items.Add();
UpdateListItem(new_item, item);
if (new_item != null)
{
new_item.Update();
}
}
}
initialSite.Dispose();