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>
Related
Scenario : I need Refresh/Filter the Items/records displayed in List View Web Part on the same page based on selected filters. So I created Visual Web Part and tried to modify the View of List View Web Part Programmatically. So far i have reached till here :
string spListName = "Job";
protected void BtnSearchClick(object sender, EventArgs e)
{
try
{
SPWeb oWebsite = SPContext.Current.Web;
SPList oList = oWebsite.Lists[spListName];
XsltListViewWebPart xsltWP = null;
SPWebPartManager wpManager = WebPartManager.GetCurrentWebPartManager(Page) as SPWebPartManager;
//Code to Find List View Web Part on Page
foreach (System.Web.UI.WebControls.WebParts.WebPart wp in wpManager.WebParts)
{
if (wp.GetType().Name == "XsltListViewWebPart")
xsltWP = wp as XsltListViewWebPart;
}
oWebsite.AllowUnsafeUpdates = true;
StringBuilder strbPreQuery = new StringBuilder("<Where><Eq>");
StringBuilder strbPostQuery = new StringBuilder("</Value></Eq></Where>");
string strQueryKeyword = "<FieldRef Name='Customer' /><Value Type='Lookup'>";
SPQuery oQuery = new SPQuery();
oQuery.Query = strbPreQuery.ToString() + strQueryKeyword + txtCustomer.Text + strbPostQuery.ToString();
SPListItemCollection itemCol = oWebsite.Lists[spListName].GetItems(oQuery);
PropertyInfo pi = xsltWP.GetType().GetProperty("ContextView", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
SPView view = (SPView)(pi.GetValue(xsltWP, null));
view.Query = oQuery.Query;
view.Update();
wpManager.SaveChanges(xsltWP);
xsltWP.DataBind();
oWebsite.AllowUnsafeUpdates = false;
}
catch (Exception ex)
{
Response.Write(ex);
}
}
The Above code works but now I am facing following problems :
The results updation requires page refresh so If I add following code, results are updated but filter values in visual web part is lost.
this.Context.Response.Redirect(this.Context.Request.Url.ToString());
Filtered applied by one user is also reflected to another user.
Can some please help in to address these two problems I have ? that is I want
To preserve the filter values and results to be modified at the same time
The filtering should be only for one user and not for all.
Any help in this regards will be appreciated.
Create a SPQuery that will hold the default value of the view.
then after passing the value,
Use this to revert back the default query of the view.
SPView _view;
protected void Page_Unload(object sender, EventArgs e)
{
//your code
SPView view = (SPView)(pi.GetValue(xsltWP, null));
view.Query = _view.Query;
view.Update();
}
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
EDIT: I've realized that my approach in the second code block was unnecessary. I could accomplish the same thing by doing the following in ItemUpdated:
SPListItem thisItem = properties.ListItem;
thisItem.File.CheckOut();
thisItem["Facility Number"] = "12345";
thisItem.Update();
thisItem.File.CheckIn("force check in");
Unfortunately, I'm still getting the same error message when "thisItem.Update();" is executed: he sandboxed code execution request was refused because the Sandboxed Code Host Service was too busy to handle the request
I actually was receiving the error above when deploying my sandbox solution originally and used this link (http://blogs.msdn.com/b/sharepointdev/archive/2011/02/08/error-the-sandboxed-code-execution-request-was-refused-because-the-sandboxed-code-host-service-was-too-busy-to-handle-the-request.aspx) to fix it.
I am trying to write a C# event receiver that changes the value of a field when a document is added/changed in a library. I have tried using the following code:
public override void ItemUpdating(SPItemEventProperties properties)
{
base.ItemUpdating(properties);
string fieldInternalName = properties.List.Fields["Facility Number"].InternalName;
properties.AfterProperties[fieldInternalName] = "12345";
}
Unfortunately, this is only working for certain fields. For example, if I replaced "Facility Number" with "Source", the code will execute properly. This may be the fact that we are using a third party software (called KnowledgeLake) that replaces the default edit form in SharePoint with a Silverlight form. Anyway, because I was having challenges with the code above (again, because I think the Silverlight form may be overriding the field after the ItemUpdating event fires), I have tried the following code:
public override void ItemUpdated(SPItemEventProperties properties)
{
base.ItemUpdated(properties);
//get the current item
SPListItem thisItem = properties.ListItem;
string fieldName = "Facility Number";
string fieldInternalName = properties.List.Fields[fieldName].InternalName;
string fieldValue = (string)thisItem["Facility Number"];
if (!String.IsNullOrEmpty(fieldValue))
{
//properties.AfterProperties[fieldInternalName] = "123456789";
SPWeb oWebsite = properties.Web as SPWeb;
SPListItemCollection oList = oWebsite.Lists[properties.ListTitle].Items;
SPListItem newItem = oList.GetItemById(thisItem.ID);
newItem.File.CheckOut();
thisItem[fieldInternalName] = "12345";
thisItem.Update();
newItem.File.CheckIn("force");
}
}
First off, the above seems a little klunky to me as I would love to just use the AfterProperties method. Additionally, I am getting the following error when "newItem.Update()" is executed: he sandboxed code execution request was refused because the Sandboxed Code Host Service was too busy to handle the request
Am I missing something here? I would love to utilize the first code block. Any help would be appreciated.
Josh was able to answer his own question, which helped me fix my problem as well. Here is a working code snippit.
public override void ItemUpdated(SPItemEventProperties properties)
{
string internalName = properties.ListItem.Fields[columnToUpdate].InternalName;
//Turn off event firing during item update
base.EventFiringEnabled = false;
SPListItem item = properties.ListItem;
item[internalName] = newVal;
item.Update();
//Turn back on event firing
base.EventFiringEnabled = true;
base.ItemUpdated(properties);
}
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;
Can anyone see why this should not work:
SPSite topNavigationSite = new SPSite("http://moss");
SPWeb topNavigationWeb = topNavigationSite.OpenWeb();
SPNavigationNodeCollection topNavigationBarNodes = topNavigationWeb.Navigation.TopNavigationBar;
SPNavigationNode updateNode = topNavigationBarNodes.Navigation.GetNodeByUrl("/about");
updateNode.Url = "";
topNavigationWeb.Update();
I can see debugging that the url get's set to "" but when the page renders, the navigation still shows the url as /about/default.aspx
I'm running this in page_load and expected it to update the moss database with the new url value.
I know this is 3years old! but as there is no where online about updating a current url!
I had to do some debugging and this is what iv come up with! By the way I got the hint from
topNavigationWeb.Update();
indicating that its updating a list! hint hint!
a bit of background! I wanted to update the quick links from a list when they add, update and delete an item from the list! On my list I have two columns Title and URL!
I then created a project in VS 2010, its an event receiver that is connected only to that list (done in the elements.xml file)
within the .cs file I added item added, item deleting(not deleted ;) ) and item updated
public override void ItemAdded(SPItemEventProperties properties)
public override void ItemUpdated(SPItemEventProperties properties)
public override void ItemDeleting(SPItemEventProperties properties)
now within each method you can simply call this method!
add/update
public static void AddQuickLaunchItem(string header, string url, SPWeb web)
{
SPNavigationNodeCollection quickLaunch = web.Navigation.QuickLaunch;
// try to get quick launch header
SPNavigationNode nodeHeader =
quickLaunch.Cast<SPNavigationNode>().Where(n => n.Title == header).FirstOrDefault();
//if header not found create it
if (nodeHeader == null)
{
nodeHeader = quickLaunch.AddAsFirst(new SPNavigationNode(header, url,true));
}
else
{
web.AllowUnsafeUpdates = true;
nodeHeader = quickLaunch.Cast<SPNavigationNode>().Where(n => n.Title == header).First() ;
nodeHeader.Url = url;
web.AllowUnsafeUpdates = false;
}
nodeHeader.Update();
web.Update();
}
the first part is checking if the node exists using the title (header)! I'm comparing between what headers there are and from the list item:
SPNavigationNode nodeHeader =
quickLaunch.Cast<SPNavigationNode>().Where(n => n.Title == header).FirstOrDefault();
this part is the comparison:
n.Title == header
I'm getting these values (header and url / spweb) like so:
public static void AddQuickLaunchItem(string header, string url, SPWeb web)
the method that is calling the above would look like this:
private void addloopweblinks(SPSite siteCollection, SPItemEventProperties properties)
{
// Enumerate through each site and apply branding.
foreach (SPWeb web in siteCollection.AllWebs)
{
AddQuickLaunchItem(properties.ListItem["Title"].ToString(), properties.ListItem["URL"].ToString(), web);
}
}
and the above method is called within the itemadded and itemupdated ;) passing the values like so:
public override void ItemAdded(SPItemEventProperties properties)
{
using (SPSite siteCollection = new SPSite(properties.WebUrl))
{
if (siteCollection != null)
{
addloopweblinks(siteCollection, properties);
}
}
}
similar things can be done for the delete ;)
SPNavigationNode nodeHeader =
quickLaunch.Cast().Where(n => n.Title == header).FirstOrDefault();
that will get the node!
nodeHeader.delete();
nodeHeader.update();
that will delete the item!
so in your case what you need, I don't know if you noticed it was this part:
web.AllowUnsafeUpdates = true;
nodeHeader = quickLaunch.Cast<SPNavigationNode>().Where(n => n.Title == header).First() ;
nodeHeader.Url = url;
web.AllowUnsafeUpdates = false;
nodeHeader.Update();
web.Update();
as you can see what i mean by the hint! nodeHeader.Update(); didnt update the url, when debugging it does change but when i go to the update part it doesnt work :( and it clicked in i need web.AllowUnsafeUpdates = true; loool only becuse I experienced a similar situation before!
for you it would be:
using(SPSite topNavigationSite = new SPSite("http://moss"))
{
using(SPWeb topNavigationWeb = topNavigationSite.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPNavigationNodeCollection topNavigationBarNodes =topNavigationWeb.Navigation.TopNavigationBar;
SPNavigationNode updateNode = topNavigationBarNodes.Navigation.GetNodeByUrl("/about");
updateNode.Url = "";
updateNode.Update();
web.Update();
web.AllowUnsafeUpdates = false;
}
}
If the user doesnt have the sufficent rights than you need to encapsulate the above with runwithelevatedprivalages :) hope this helps :)
Have you tried:
updateNode.Update();
topNavigationWeb.Update();
It doesn't look like you are updating the SPNavigationNode object. (Note: you may not need the second Update call.)