Can anybody tell me why this code doesn't work?
The "adding code" itself works, but unfortunately not in an ItemAdded Event.
I need this code in the ItemAdded Event and therefor i cannot use ItemAdding.
Thanks for any help.
public override void ItemAdded(SPItemEventProperties properties)
{
SPSite site = new SPSite("http://air_sim:39167/");
SPWeb web1 = site.RootWeb;
SPList List = web1.Lists["Announcements"];
SPListItem newitem = List.Items.Add();
newitem["Title"] = "Example";
newitem.Update();
}
Did you do any steps to attach event receiver to your list?
If no, you can install a feature to manage event receivers and
verify that the event receiver is added and if not, add it manually:
http://chrissyblanco.blogspot.com/2007/08/event-receiver-management.html
Maybe exception is thrown somwere? For example, if such site or list
with such name doesn't exist, exception will be thrown. Also if you
don't initialise required fields of your item, the Update() call
will throw exception.
By the way the properties variable contains many useful properties:
SPListItem newitem = properties.List.Items.Add();
newitem["Title"] = "Example";
newitem.Update();
Do you use Sharepoint 2010 or Sharepoint2007?
Do you use VS2008 or VS2010?
If you couldn’t use debugger, use EventLog:
public override void ItemAdded(SPItemEventProperties properties)
{
EventLog.WriteEntry("DebugSharepoint", "ItemAdded fired");
try
{
SPSite site = new SPSite("http://air_sim:39167/");
SPWeb web1 = site.RootWeb;
SPList List = web1.Lists["Announcements"];
SPListItem newitem = List.Items.Add();
newitem["Title"] = "Example";
newitem.Update();
}
catch(Exception e)
{
EventLog.WriteEntry("DebugSharepoint", e.Message, EventLogEntryType.Error);
}
}
Attach a debugger.
Go to cmd and type iisapp. You would get the worker process id.
Then open your event handler project and go to the tools and attach process and set the debug point on ItemAdded as well as ItemAddding event
Try the below solutions:
Check whether the Site exists with that name.
Check whether user has the permission to insert item.
Try using AllowUnsafeUpdates:
SPSite site = new SPSite("site address");
SPWeb web1 = site.RootWeb;
SPList List = web1.Lists["Announcements"];
web1.AllowUnsafeUpdates = true;
SPListItem newitem = List.Items.Add();
newitem["Title"] = "Example";
newitem.Update();
web1.AllowUnsafeUpdates = false;
Related
I'm using event receivers to modify some of the inputs in a SharePoint 2013 site.
They are fairly straight forward, here is a simple example
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
using (SPSite site = new SPSite(properties.WebUrl))
{
using (SPWeb web = site.OpenWeb(properties.RelativeWebUrl))
{
//web.AllowUnsafeUpdates = true;
SPListItem item = properties.ListItem; // Boom!
var title = item["Title"].ToString();
item["Title"] = title.Replace(" ", "_");
//item.Update();
//item.SystemUpdate(false);
}
}
}
This renders the error
Message:
Method not found: 'Microsoft.BusinessData.Runtime.IEntityInstance Microsoft.BusinessData.Runtime.NotificationParser.GetChangedEntityInstance(Microsoft.BusinessData.MetadataModel.IEntity, Microsoft.BusinessData.MetadataModel.ILobSystemInstance)'.
Source:
Microsoft.SharePoint
StackTrace:
at Microsoft.SharePoint.SPItemEventProperties.get_ListItem()
at eventreceivers.Kundregister.PrivateCustomer.PrivateCustomer.<>c__DisplayClass2.<ItemAdded>b__0()
at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass5.<RunWithElevatedPrivileges>b__3()
at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
I have ensured that those methods are available in the class.
Any advices are highly appreciated, thanks!
I was already facing the same issue.
instead of using
SPListItem item = properties.ListItem;
use following code to get item,
SPListItem item = properties.Web.Lists.TryGetList(properties.ListTitle).GetItemById(properties.ListItemId);
All the best!
Regards,
Praveen Singh
I have a "project list" (title, lead, members, site-URL) that is supposed to refer to team sites under the site that has the project list. So I added an SPItemEventReceiverto my feature in a sandbox solution to do that.
In ItemAdding(properties), I invoke the following:
string projectName = properties.AfterProperties["Title"].ToString();
SPWeb currentWeb = properties.Web;
SPWeb subweb = currentWeb.Webs.Add(projectName, projectName,
"Project site for " + projectName, (uint) currentWeb.Locale.LCID,
Microsoft.SharePoint.SPWebTemplate.WebTemplateSTS, true, false);
But when debugging, the call to Add throws an SPException wrapping a COMException for a HResult code of FAILED with the message The sandboxed code execution request was refused because the Sandboxed Code Host Service was too busy to handle the request.
Is there something wrong with the parameters, or should I delegate the actual creation to a workflow instead?
Following try with this:
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
// Get the web where the event was raised
SPWeb spCurrentSite = properties.OpenWeb();
//Get the name of the list where the event was raised
String curListName = properties.ListTitle;
//If the list is our list named SubSites the create a new subsite directly below the current site
if (curListName == "SubSites")
{
//Get the SPListItem object that raised the event
SPListItem curItem = properties.ListItem;
//Get the Title field from this item. This will be the name of our new subsite
String curItemSiteName = properties.AfterProperties["Title"].ToString();
//Get the Description field from this item. This will be the description for our new subsite
string curItemDescription = properties.AfterProperties["Description"].ToString();
//Update the SiteUrl field of the item, this is the URL of our new subsite
properties.AfterProperties["SiteUrl"] = spCurrentSite.Url + "/" + curItemSiteName;
//Create the subsite based on the template from the Solution Gallery
SPWeb newSite = spCurrentSite.Webs.Add(curItemSiteName, curItemSiteName, curItemDescription, Convert.ToUInt16(1033), "{8FCAD92C-EF01-4127-A0B6-23008C67BA26}#1TestProject", false, false);
//Set the new subsite to inherit it's top navigation from the parent site, Usefalse if you do not want this.
newSite.Navigation.UseShared = true;
newSite.Close();
}
}
Seems to be some deadlock situation; I solved my particular case by using the post-event ItemAdded instead (changing from setting values in AfterProperties to updating the ListItem instead). There, for some reason, the call to Webs.Add() completes normally...
I'm using the following code to add an item to a list on the top level of my application but it is not adding anything, does anyone know why? Is there anything missing?
It doesn't return me any error, just doesn't add the item and the list remains empty.
The code is in the FeatureActivated method of the feature where the list instance is being deployed.
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPList icons = web.GetList(path)
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPListItem icon = icons.Items.Add();
icon[SPBuiltInFieldId.Title] = "title";
icon[new Guid("d3429cc9-adc4-439b-84a8-5679070f84cb")] = "class1";
icons.Update();
}
you have to call the Update() method of the icon object, not icons.
I found out there are 2 ways of successfully add an item to a list:
Like Andreas Scharf said:
SPListItem item = list.Items.Add();
item["Title"] = "some title";
item.Update();
Some other way using the AddItem() instead of the Add() from the items collection
SPListItem item = list.AddItem();
item["Title"] = "some title"; // Add item's field values
item.Update(); //also the item is updated, not the list
I've started programming event handlers.
At first I added some items to lists with hard coded values.
Everything worked fine, but then I switched to using properties.OpenWeb() and tried to get the URL with web.Url.ToString() - doing this the handlers won't work and do not emit any error.
Do I have to change any configuration?
Have you got a way to solve my problem?
By the way if I try to get values, they are all null.
I am using WSS 3.0 and VS 2008, please see my code below, and thanks!
public override void ItemAdded(SPItemEventProperties properties)
{
SPSite site = new SPSite("http://air_sim:1431/");
SPWeb web = site.RootWeb;
SPList List = web.Lists["Announcements"];
base.ItemAdded(properties);
SPWeb web1 = properties.OpenWeb();
SPListItem newitem = List.Items.Add();
newitem["Title"] = "test";
newitem["Body"] = web1.Url.ToString();
newitem.Update();
}
By the way i found this code on msdn.
It doesn't work. No error..nothing, and of couse the condition is true.
public override void ItemAdding(SPItemEventProperties properties)
{
using(SPWeb oWebsite = new SPSite(properties.SiteId).OpenWeb(properties.RelativeWebUrl))
{
SPListItemCollection collItems = oWebsite.Lists[properties.ListTitle].Items;
if (collItems.Count >1)
{
properties.Cancel = true;
properties.ErrorMessage = "Adding items to this list is not supported because it already contains " +
collItems.Count.ToString() + " items.";
}
}
}
please be sure of that the "Type" in "receiver" in the Elements.xml as following :
<Type>ItemAdded</Type>
your "receiver" node should be something like :
<Receiver>
<Name>ERItemAdded</Name>
<Type>ItemAdded</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>NameSpace.ClassName</Class>
<SequenceNumber>10000</SequenceNumber>
</Receiver>
After reading Stefan Gossner's post about disposing objects and this question about Cross method dispose patterns, I found that I was guilty of accidentally reopening some SPWebs. I know in Stefan Gossner's post he mentions you should dispose of an SPWeb after you are finished with any child object. However, the microsoft documentation mentions Caching the SPListItemCollection object. Is the following code correct? Would the returned SPListItemCollection reopen an SPWeb object? Is there any way to tell for sure?
// is this correct????
private SPListItemCollection GetListItems()
{
SPListItemCollection items = null;
try
{
using (SPSite site = new SPSite(GetListSiteUrl()))
{
using (SPWeb web = site.OpenWeb())
{
// retrieve the list
SPList list = web.Lists[_ListName];
// more code to create the query...
items = list.GetItems(query);
}
}
}
catch (Exception e)
{
// log error
}
return items;
}
Edit 09/09/09
I am mainly referring to this part of Stefan Grossner's post:
You should dispose a SPWeb or SPSite
object after the last access to a
child object of this object.
I believe what he is saying is that if I use the SPListItemCollection after I dispose of the SPWeb that I used to get it... the SPWeb will be reopened automatically.
I found out after asking Stefan directly that the SPListItemCollection can indeed reopen the SPWeb after you dispose of it. This means that my code posted above is INCORRECT and I would only be able to dispose of the SPWeb after I use the SPListItemCollection.
Update: It is better to convert to the SPListItemCollection to something else and return that instead.
private DataTable GetListItems()
{
DataTable table = null;
try
{
SPListItemCollection items = null;
using (SPSite site = new SPSite(GetListSiteUrl()))
{
using (SPWeb web = site.OpenWeb())
{
// retrieve the list
SPList list = web.Lists[_ListName];
// more code to create the query...
items = list.GetItems(query);
// convert to a regular DataTable
table = items.GetDataTable();
}
}
}
catch (Exception e)
{
// log error
}
return table;
}
As far as I know the answer is no, but I would have written the code something like
private void FetchItems(Action<SPListItemCollection> action)
{
using(...)
{
var items = list.GetItems(query);
action(items);
}
}
By doing this, to call this method you would need to send a method along (delegate) that the SPListItemCollection should be used for, an example:
FetchItems( items => ....) or FetchItems( DoStuffWithItems(SPListItemCollection) )
If you are talking about whether you need an SPWeb in the same scope when you get around to using the SPListItemCollection, I think the answer is no.
For example, I routinely do the following:
private IEnumerable<SPListItem> AllItems;
public void GetItems()
{
var results = SPContext.Current.Web.Lists[ListName].Items.Cast<SPListItem>();
this.AllItems = results;
}
and then I use AllItems all over the place, and it works fine.
Incase you are wondering, the cast is done so I can use Linq on the result set - much much faster than submitting a query to the list, especially if you are doing multiple subselects on the data.