SiteMapNodes not showing after upgrade from Unity to autofac - owin

We had a development house upgrade our site to use Autofac instead of Unity and now our sitemap is empty - we no longer have our menu items nor do we have our breadcrumb trail. From debugging all I can say with certainty is that our sitemapNodes are empty (Only the root shows up) - running the old and new side by side everything happens in extenral code so I have no idea where it's going wrong. We use a custom implementation of the SiteMapNode to identify our menu items like below
[AuthorizeRights(SystemRights.MyRights)]
[MyCustomMvcSiteMapNode(LocalizedTitleKey = "MyObject_IndexTitle", ParentKey = "MyObject", Key = "MyObjectIndex", ShowInBreadCrumbOnly = true)]
public ActionResult Index()
{
var list = _myObjectLogic.GetMyObjects();
var viewModel = new MyObjectsViewModel(list);
return View(viewModel);
}
In the old version the code just finds the pages and lines them up in the menu, but in the new code nothing.
I've searched ad nauseum and found countless pages that tell me things like "You need to install these Nuget Packages" or "If you're using OWIN you need this code at startup" but none of it worked.
Can anyone tell me what we are missing?

Related

faces-redirect=true not working while creating and rendering view

I am currently working on a JSF 2.2 application. As per requirements, I have created custom view handler (using ViewHandlerWrapper) for my application. All the methods are just passing to default view handler except renderView which I am overriding as follows -
private viewHandler viewHandlerWrapped = null;
renderView(FacesContext facesContext, UIViewRoot viewToRender) {
String viewId = viewToRender.getViewId();
if (viewId == some condition) {
/* Do calculation to derive viewId */
}
UIViewRoot viewRoot = viewHandlerWrapped.createView(facesContext,viewId+"?faces-redirect=true");
facesContext.setViewRoot(viewRoot);
//now let system render the view
viewHandlerWrapped.renderView(facesContext,viewRoot);
}
The above is working fine and rendering & navigation is happening as expected. The only issue is faces-redirect=true is not working. The URL seems to be always one behind.
I have gone through many answers given in stackoverflow or internet. But nowhere I am able to find how to solve this.
I think I am doing something wrong e.g. ?faces-redirect=true might not be the correct way while creating view. But I am not sure what can be done to correct this.
Can someone please help me out with this?
After struggling with this for more than 4 weeks, I finally found a way to get the correct URL (instead of previous one). I am updating my answer here in case any one else falls into same problem -
"It looks like we can not use the faces-redirect=true the way I was using while creating and rendering the pages. It should be suffixed with form action. So I have changed my code as follows -
1) actions are returned on click of a button e.g.
public string doAction {
----
return "action?faces-redirect=true";
}
2) Code is updated to use implicit navigation wherever possible. With this, I didn't need to build my custom viewhandler as navigation is happening implicitly. So, I have scrapped the viewhandler.
With above two simple steps, the correct URL is being displayed on the browser now.

Determining which Visual Studio context menu was selected?

I'm writing a VS2012 add-in, adding a command to Build Explorer context menu (see related question). The command gets added to 2 different context menus:
Build Explorer
Team Explorer, Builds page, My Builds section
When my one callback is called, how do I know which of these it is?
I tried get the focused control (using P/Invoke as this question suggests). However, it gets me a Tabs container for (1), and null for (2). I could try to cast the control to the tabbed container, but that sounds pretty bad...
Any better alternative?
My new/other idea - it is similar to yours:
You should try to monitor which window was activated lastly.
If you create an eventhandler for your command, then you may be able to check which window is active when your command fired. A simple evenent handler for a command:
void cmdEvents_BeforeExecute( string guid, int ID, object customIn, object customOut, ref bool cancelDefault )
{
Window2 teamExplorer = _applicationObject.Windows.Item("Team Explorer") as Window2;
if (_applicationObject.ActiveWindow.Caption == teamExplorer.Caption)
{
//You are called from Team Explorer
}
else
{
//Somewhere else
}
}
And the way you can subscribe:
static _dispCommandEvents_BeforeExecuteEventHandler _myHandler;
static CommandEvents _cmdEvents;
public void OnConnection(...)
{
Command command = ...; // Init your command
int ID = command.ID;
string GUID = command.Guid;
CommandEvents _cmdEvents = _applicationObject.Events.get_CommandEvents(GUID, ID);
_myHandler = new _dispCommandEvents_BeforeExecuteEventHandler(cmdEvents_BeforeExecute);
_cmdEvents.BeforeExecute += _myHandler;
}
You may find a better way to identify the window(s) by GUID. You should keep at least _cmdEvents as static because when it will be desroyed, your event handler could vanish (least for internal commands).
In OnDisconnection you should unsubscribe.
Reworked by the comment, and founded links:
As the menu item is shown every place it seems there is no way to distinct between them from an Add-In, you should add two command and distinct them by their context.
The way instead of converting the Add-In to a VS-Package MZ-Tools HOWTO: Controlling the state of command in a Visual Studio add-in, try MZ-Tools HOWTO: Use the IVsMonitorSelection ... you can also get it from an Add-In.
But:
Neither the AddNamedCommand nor the QueryStatus methods honor the
invisible state: the button that must be invisible ...
remains disabled rather than invisible.
I think this makes it impossible to do it from an Add-In on a suitable way, but maybe you can check the contexts.
Other way you could get further, if you try to migrate your command/menu into a VSPackage and create a custom UIContext for the menu items or find a suitable predefined one. I have no access to a Studio enhanced with Build Explorer so I can't try it.
The following discussion is about custom contexts for vs-packages:
http://davedewinter.com/2008/04/05/dynamic-menu-commands-in-visual-studio-packages-part-3/
Sadly the links are broken from the post, and I can't reach Part 1. and Part 2. which is about the discussion of the problem from the beginning.
But there is no guarantee you can create a context which suits you.
Only context ID I found for Team Explorer is the guidTeamProjectCmdUIContext.
It is placed at vsshilds.h in Visual Studio 2010 SDK, vsshell*.h are also contain several others.
MSDN: Vsct files to define command, menus, ect. from packages.
Condition attribute for items:
http://msdn.microsoft.com/en-us/library/bb491718.aspx
http://msdn.microsoft.com/en-us/library/bb166515.aspx
MSDN: VisibilityItem element for commands and toolbars.
VisibilityItem element determines the static visibility of commands and toolbars.
... After the VSPackage is loaded, Visual Studio expects command visibility to be determined by the VSPackage rather than the VisibilityItem.
And finally about predefined Context Guids:
http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.uicontextguids80.aspx
http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.uicontextguids.aspx

Best way to programmatically create/maintain SharePoint Quick Launch menu

We have a solution that deploys a number of lists and pages. We wan't to create links for them on the Quick Launch menu automatically when a feature is activated.
The structure could be something like this.
Customers
Active
Inactive
Sales
Quotes
Orders
And so on. The site collection admin might add another link between the "Active" and "Inactive" links. When the feature is deactivated I don't want to remove the items, but if the feature is activated again i don't want the navigation to be added again :)
Is there a built in API that you can use? I know about the SPWeb.Navigation.QuickLaunch and the SPNavigationNode(Collection) structure etc. But is there another way?
Hope you can help :)
What kind of other way would you be looking for?
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWeb web = (SPWeb)properties.Feature.Parent;
// Check for an existing link to the list.
SPNavigationNode listNode = web.Navigation.GetNodeByUrl(list.DefaultViewUrl);
// No link, so create one.
if (listNode == null)
{
// Create the node.
listNode = new SPNavigationNode(list.Title, list.DefaultViewUrl);
// Add it to Quick Launch.
web.Navigation.AddToQuickLaunch(listNode, SPQuickLaunchHeading.Lists);
}
}
We have used the method above for a while and it tends to work out just fine.
If you can let me know what kind of thing you are trying to accomplish that manipulating SPWeb.Navigation wont let you do, I might be able to be of some more help

Get Current Navigation items for all site collections and webs - SP2010

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 :)

SharePoint itemDeleting evert is not working

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

Resources