I am creating a list with a deployed list template. with the following code:
SPSite site = new SPSite("http://servername");
SPWeb web = site.OpenWeb();
web.Lists.Add(listName, listName, listTemplate);
web.Update();
SPList List = Web.Lists[listName];
I am able to access the list with the web object which is used to create it. But, SPContext.Current.Web is not updated. So, the following throws error:
SPContext.Current.Web.Lists[listName]
Is it possible to update the SPContext.Current object with latest information so that the list accessible after it is created?
Thanks in advance!
Update: Code updated.
Your code doesn't show this, so I'm going to ask for the obvious: did you try calling web.Update() right after adding the new list?
I added the below line after web.Update() and it started working.
SPContext myContext = SPContext.GetContext(Web);
Related
I'm trying to make a site map for a Sharepoint 2010 that will list every site and that site's current nav items. Navigation between sites is done via the top nav. However, I'm having problems getting the current nav items for each site. It appears that each time I get the PortalSiteMapProvider for the web, it returns the provider for the whole site collection. How do I get the items for just that site? I run this code for each site I want to get the items for:
var provider = new PortalSiteMapProvider();
provider.NavigationType = PortalNavigationType.Current;
provider.CurrentWeb = web;
var rootNode = provider.RootNode;
Anyone have any idea where to go from here?
EDIT:
So it isn't possible to just access each site collection and run this code. The PortalSiteMapProvider doesn't allow it. It is, however, possible to run this code in a ashx that's located in the layouts folder. I just need to access that ashx file from the site collection I want to enumerate, and it will work just fine :)
private void DrawWeb(SPWeb web, TreeNode node)
{
SPWebCollection webCol = web.Webs;
foreach (SPWeb w in webCol)
{
var n = new TreeNode(w.Title);
node.ChildNodes.Add(n);
DrawWeb(w, n);
w.Dispose();
}
}
Try calling this method like:
TreeNode webNode = new TreeNode(rootNode.Title);
DrawWeb(provider.CurrentWeb, webNode);
Hope this will be helpful.
So it isn't possible to just access each site collection and run this code. The PortalSiteMapProvider doesn't allow it. It is, however, possible to run this code in a ashx that's located in the layouts folder. I just need to access that ashx file from the site collection I want to enumerate, and it will work just fine :)
I have a site in SharePoint and I want to custom delete from a list. So, I'm creating the
public class ListItemEventReceiver : SPItemEventReceiver
{
public override void ItemDeleting(SPItemEventProperties properties)
{
if (properties.ListTitle.Equals("Projects List"))
{
Projects pr = new Projects();
string projectName = properties.ListItem["Project Name"].ToString();
pr.DeleteProject(projectName);
}
}
}
Where 'Projects' class has 'DeleteProject' method who deletes the item.
But it's doing nothing :(
I mention that everything it's ok in Feature.xml
Where am I wrong?
Edit (from 'answer'):
Yes, I've tried this:
properties.ErrorMessage = "projectName :" + projectName;
properties.Cancel = true;
in if clause and the event it's firing and displays the project name corectly.
I'm the farm administrator, and site administrator with full control over this site.
DeleteProject method it's right, because I've tried it in some other application (c#) and it's works fine.
A couple of things to check:
Is your list item reciever connected to the list, so that it fires?
Does the user that causes the trigger to fire have the the right to delete items?
Is there any programming error in DeleteProject?
Try putting in some logging to see how far it is running.
Edit
Could the problem be here:
string projectName = properties.ListItem["Project Name"].ToString();
Is the list item called "Project Name" with a space in the name?
Edit 2
From your comments, the combination of authentication and connection string means that it is the security context of the logged on user that is being used against the database. Check the rights of your user.
If event is firing and the only method pr.DeleteProject(projectName); is not working properly then it is difficult to guess what is wrong. If it is not confidential, please post your code and then I shall be in better position to identify what is wrong.
By the way, are you calling .Update() Method on list?
Please check out this link http://msdn.microsoft.com/en-us/library/ms431920.aspx
One more thing to care about is Itemed and Iteming events. It is better to use Before or After properties as appropriate in case of Item*ing events.
Regards,
Azher Iqbal
What is the best way to obtain the current site/web/list ?
Option 1 - Reusing existing objects
SPSite site = SPContext.Current.Site;
SPweb web = SPContext.Current.Web;
SPList list = SPContext.Current.List;
Option 2 - Creating new objects
SPSite site = new SPSite(SPContext.Current.Site.ID); // dispose me
SPweb web = site.OpenWeb(SPContext.Current.Web.ID); // dispose me
SPList list = web.Lists[SPContext.Current.List.ID];
I experienced problems when using option 1 in some situations. Since then I chose the 2nd option and it worked fine so far.
What is your opinion on this? I is generally better to go with option 2? Other suggestions?
Do use Option one, because it's more resource-efficient as you don't need to create new object (For example OpenWeb method involves querying database to do it's job). But you are not allowed to dispose objects from SPContext, that will definitely cause you problems.
You must use Option Two if your code is not run in context of application pages (like SharePoint timer or Workflow), because SPContext.Current object will be null.
Link
And yes, if you open SPWeb or SPSite object, you MUST dispose it.
I normally go with option 2 (which I believe si the approach recommended by Microsoft), but I tend to wrap things using using to ensure they are disposed of properly. Example:
using (SPSite site = new SPSite("MY SITE URL"))
{
using (SPWeb web= site.OpenWeb())
{
// Do stuff
}
}
This approach allows you to be explicit about when objects are created and destroyed.
I have an aspx page with inline code in which I am trying to update the view programmatically by setting view's Query property to my CAML query. When I run with administrator user everything works perfect view get updated successfully but when I logged in with a user who belongs to visitor group and having read only access then I get an error on view.Update() line saying that:
"Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack"
I have already try to run this code block with ElevatedPrivileges but not get any luck...(
following is my code which make you more clear:
SPUserToken token = CurrentSite.SystemAccount.UserToken;
using (SPSite st=new SPSite(SPContext.Current.Web.Url,token))
{
st.AllowUnsafeUpdates = true;
using (SPWeb wb=st.OpenWeb())
{
wb.AllowUnsafeUpdates = true;
vwSearchResult.Query = Query;
vwSearchResult.Update();
}
}
What you are doing here, is modifying the definition of the view for ALL users of the website, not only the current rendering instance of the page. This is why simple visitors cannot change it (they do not have such permission in the web)
If you want to do something, using the "SystemAccount" token, you have not only to do the "using SPSite, using SPWeb", but also find the list and the view using the "strong" SPWeb objects
Instead of modifying a view definition at runtime, you might want to consider using ListViewByQuery class http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.listviewbyquery.aspx
When I add a new item in a default Announcement list using the GUI the new item looks just as I would expect, showing the title of the item in the breadcrumb. However when adding the new item through the object model:
SPList theList = web.Lists["announcement"];
SPListItem theitem = theList.Add();
theitem["Title"] = "this is the title";
theitem.Update();
then the breadcrumb will display something like
WebTitle.ListTitle.34_.000, which I believe to be the itemID and versionnumber of the item.
A search give this but I would like to know the root cause and possible how to avoid the issue.
The issue has been resolved. Actually the list in question was a discussion list, not a announcement list ( why it was then named "announcement" is a big mystery),
Since a discussion is actually a thread container and the threads within the container, I had to call SPUtility.CreateNewDiscussion rather then list.Add.