|
|
|
|
|
Overview Web services offers you the best level of integration between Charting Web Parts and your databases or back-end systems. A powerful Web service mapping editor allows you to integrate any service that exposes its WSDL schema as a data source for a Chart Web Part. Contextual information extracted from SharePoint can be passed as input parameters to the Web service. Data are then retrieved asynchronously to maximize user experience, consumed by Chart Web Parts and exposed through visually-exciting charts.
Implementing a sample Web service
The simple chart below is generated from an external database, if you want to customize your charts, you can develop your own Web Service as explained in this post.
 Chart Web Parts data series are based on the XML schema below. Compliant Web services have to output their results according to the following specifications.
<? xml version="1.0" encoding="utf-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Segments"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="Segment"> <xs:complexType> <xs:attribute name="Title" type="xs:string" use="required" /> <xs:attribute name="Value" type="xs:unsignedByte" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
The XML content below exposes a data series containing three segments A, B and C with respective values of 10, 15 and 25.
<? xml version="1.0" encoding="utf-8"?> <Segments> <Segment Title="A" Value="10" /> <Segment Title="B" Value="15" /> <Segment Title="C" Value="25" /> </Segments>
The following source code is a C# class that returns our sample data series and exposes it through an ASP.net Web service
File SampleSeriesService.cs using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.Web.Services;
namespace ChartingForSharePoint
{
public struct Segment
{
[XmlAttribute]
public string Title;
[XmlAttribute]
public int Value;
public Segment(string title, int value)
{
Title = title;
Value = value;
}
}
[WebService(Namespace = http://api.acme.com/services)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SampleSeriesService : WebService
{
[WebMethod]
[return: XmlRoot("Segments")]
public List<Segment> GetSampleSeries(string inParam)
{
List<Segment> segments = new List<Segment>();
segments.Add(new Segment("A", 10));
segments.Add(new Segment("B", 15));
segments.Add(new Segment("C", 25));
return segments;
}
}
}
File SampleSeriesService.asmx
<%@ WebService Language="C#" Class="ChartingForSharePoint.SampleSeriesService,ChartingForSharePoint, Version=1.0.0.0, Culture=neutral,PublicKeyToken=f71dfbc876472393" %>
Registering the service
The C# class has to be compiled into a signed assembly. This assembly has to be registered into the GAC of your server, or copied into the bin directory of your Web application (in this case, make sure CAS policies are correctly configured for your assembly).
The ASMX file has to be copied at root level or into a subdirectory of folder C:\Program Files\Common file\Microsoft Shared\web server extensions\12\ISAPI on your Web front-end server.
The Web service is ready to run, but you must register it via an STSADM command in order to make SharePoint exposing its WSDL schema correctly. If you omit this step, no WSDL schema will be exposed when trying to access the service description via the special WSDL query string token.
Use the registerwebservice STSADM operation with syntax below to register the Web service to SharePoint. This custom STSADM command is automatically deployed when setting-up Charting for SharePoint on your system.
You can use the syntax below from a command prompt to obtain the list of parameters supported by the operation
C:\...\12\BIN>stsadm.exe -help registerwebservice
The table below gives details about each parameter
|
Parameter |
Details |
Comments |
|
url |
Absolute URL of the Web service |
|
|
username |
Login of the account used to access the service |
This parameter is optional. You only need to specify credentials if the Web application uses basic authentication. Login can be composed of a username only, or it can contain a domain and a username separated by a backslash character (e.g. DOMAIN1\userA) |
| password
|
Password of the account used to access the service |
Warning: the password will be sent in clear when calling the service |
Below is a screenshot of how to register our sample service on the localhost Web application. If you receive the message Operation completed successfully, the Web service definition file is available to SharePoint.

You can ensure that the WSDL definition file is available by accessing the service URL from a Web browser and then click the Service description link, or by appending ?WSDL at the end of the service URL (see sample below)
http://localhost/_vti_bin/SampleSeriesService.asmx ?WSDL
Authentication methods
Charting Web Parts are relying on Web browser credentials cache to access Web services. Thus, we advise you to connect to Web services located on the same Web application as Web Part pages. This way, Charting Web Parts are compliant with native SharePoint authentication methods:
Using a Web service as a data source
1. From any Web Part page on your site collection, add a new Chart Web Part.

Note: make sure Charting for SharePoint is correctly deployed on your site collection. Refers to § Deploy features on a site collection for more details about setup procedure.
2. From the new Web Part, open the tool pane by clicking on the message displayed into the Web Part.

3. From the Data mapping section of the tool pane, click on Edit mappings.

4. Select Web service as a data service type from the header of the popup window
 5. Enter the absolute or relative service description URL into Address of the service description file. Then press Enter or click on the magnifier button
 6. Choose a prefix and specify the service relative URL if you want to use relative path, or leave the default URL if you prefer an absolute URL.
Note: We advise you to work with relatives URLs for both service description and service address. You can then streamline support of extended Web applications.
7. Select a Web method from available operations. When a new operation is selected from the list, the corresponding input parameters are populated in the Input parameters mapping grid. The first parameter is ready for binding.

8. For each input parameter, click on parameter name, map it to its contextual value by selecting a macro from the list of predefined values, and then click on the Save link. Repeat this operation for all input parameters.

9. If no macro is convenient for your input parameter, you can hard code its value or use an expression builder registered for the Web application.
Note: if you want to improve the list of available macros with custom macros, you can register some ExpressionBuilder expressions, and add your custom macros into the following file
C:\...\12\TEMPLATE\XML\Prexens\SharePoint\ApplicationPages\Services\Mapping\ParameterMappingMacros.xml
10. When all settings are OK, click on the Save button. Settings are saved and the corresponding chart is displayed.

11. You can adjust the look & feel of the chart by editing chart’s settings from the tool pane. Different categories of settings are available:
Possible errors and resolutions
The table below is a non-exhaustive list of possible errors that can occurs when using mapping editor.
|
Error message |
Resolution |
| Unable to cast object of type 'System.Web.Services.Description.HttpAddressBinding' to type 'System.Web.Services.Description.SoapAddressBinding' |
Try to register the Web service on the same Web application as the Web Part page. Refers to § “Registering the service” for more details about how to register a Web service. |
|
There is an error in XML document (3, 2) |
WSDL description address is invalid. Make sure that you’ve appended the WSDL query string token to the URL of service description file. If yes, try to access the URL you’ve specified from a Web browser to ensure that it returns the WSDL schema of the service. |
|
Exception: Protocol error |
URL of the service description file is not well formed. Open a Web browser and make sure you can access the service with URL you’ve specified. |
|
404 not found |
The URL you’ve specified as the service description file address does not exist. Open a Web browser and make sure you can access the service with URL you’ve specified. |
| |
| |
Goal of this post
The goal of this post is to guide you through the different steps for replacing the ‘Submit for Approval’ quick access button in a WCM environment.
Problematic overview
‘Submit for Approval’ is a native button which aims at firing a ‘Parallel Approval’ workflow when Publishing features are activated in a WCM web site:

When deploying a custom approval workflow, you’ll probably need to overwrite the logic of this button to start your custom workflow correctly. You would also be able to customize the icon and the text of your custom button to achieve something like this:

Write a custom class CustomSubmitForApproval
1. Set pre-requisites:
-
First, add those tworeferences : Microsoft.SharePoint, Microsoft.SharePoint.Publishing
-
Create a public sealed class that inherits from: Microsoft.SharePoint.Publishing.WebControls.EditingMenuActions.ConsoleAction
-
Add a constant used as argument of post back events: private const string PostBackEventArg = "submitForApproval";
2. Add a constructor and customize your custom quick access button: public CustomSubmitForApprovalButton()
: base()
{
this.DisplayText = "Custom Submit for Approval";
this.ImageUrl = "/_layouts/images/workflows.gif";
}
3. Override NavigateUrl property and fire post back events:public override string NavigateUrl
{
get
{
return String.Format("javascript:{0}", Page.ClientScript.GetPostBackEventReference(
this, CustomSubmitForApprovalButton.PostBackEventArg));
}
}
4. Override RaisePostBackEvent method, and implement your redirection logic
In our case, we force the page check in and we redirect toward check-in page:
public override void RaisePostBackEvent(string eventArgument)
{
try
{
if (eventArgument == CustomSubmitForApprovalButton.PostBackEventArg)
{
SPFile myFile = SPContext.Current.File;
// Auto checkin page before redirecting to 'Publish Major Version'
if (myFile.CheckOutStatus != SPFile.SPCheckOutStatus.None)
{
myFile.CheckIn("Default comment", SPCheckinType.MinorCheckIn);
}
string redirectUrl = String.Format(
"{0}_layouts/Checkin.aspx?FileName={1}&Publish=true&List={2}&Source={3}",
SPContext.Current.Web.ServerRelativeUrl,
SPContext.Current.ListItemServerRelativeUrl,
Convert.ToString(SPContext.Current.List.ID),
Page.Request.Url.OriginalString);
SPUtility.Redirect(redirectUrl, SPRedirectFlags.Default, HttpContext.Current);
}
}
catch (Exception ex)
{
ShowError(ex, new ConsoleError(ex.Message));
}
}
You can override some properties to control what is the minimum level of permission required to access the feature, and what are the states causing your button to appear in the page editing toolbar. In samples below, users have to be granted the permission of adding items and page has to be a publishing page waiting for approval.
5. Override SPBasePermissions UserRights property public override SPBasePermissions UserRights
{
get { return SPBasePermissions.AddListItems; }
}
6. Override AuthoringStates RequiredStates property public override AuthoringStates RequiredStates
{
get
{
return AuthoringStates.IsPublishingPageTrue |
AuthoringStates.SaveConflictExistsFalse |
AuthoringStates.IsMajorVersionFalse |
AuthoringStates.IsApprovalWorkflowConfiguredTrue |
AuthoringStates.InEditModeFalse |
AuthoringStates.IsApprovalWorkflowRunningFalse;
}
}
Overwrite CustomQuickAccess.xml file in master pages gallery
When your custom class is compiled and deployed on your SharePoint server, you will have to overwrite CustomQuickAccess.xml located into MOSS master pages gallery.
In a live scenario, we recommend to deploy this file through activation event of a custom feature. Simply make sure not to override an already existing file. In our sample scenario, we are going to edit this file directly from SharePoint Designer :
1. Open CustomQuickAccess.xml from /_catalogs/masterpage/Editing Menu
2. Add a reference to our custom class (mind to adjust assembly reference with your own assembly qualified name): <references>
<reference TagPrefix="Prexens"
assembly="Prexens.SharePoint.CustomQuickAccessButton, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5"
namespace="Prexens.SharePoint.CustomQuickAccessButton" />
</references>
3. Add a ConsoleNode that override native qaPublish Node ID:
<structure>
<ConsoleNode
Sequence="65"
ConfigMenu="Replace"
Action="Prexens:CustomSubmitForApprovalButton"
ID="CustomQuickAccessButton_SubmitForApproval"
ChangedNodeID="qaPublish" />
</structure>
4. Add two ConsoleNode that remove native Approve and Decline buttons (those two feature should probably be inconsistent with your custom publishing workflow):
<ConsoleNode ConfigMenu="Delete" ChangedNodeID="qaWorkflowDecline" />
<ConsoleNode ConfigMenu="Delete" ChangedNodeID="qaWorkflowApprove" />
5. Save, publish, and approve this file in master pages gallery | |
| | Goal of this post
By enabling audience targeting option on a list or library, you can display content only to people who are members of a particular group or audience.
You can then specify audience members through Audience Targeting field.
But how to retrieve all members from this audience field programmatically? For instance, how to get their email addresses?
What an audience is composed of?
Target audience field can only contain 3 types of objects (see screenshot below):
- Global audiences (can be defined in the Shared Services Administration of the SharePoint central administration, Audiences section).
- Distribution/Security Groups (groups of your Active Directory).
- SharePoint Groups.

Let's code
1. Audience property
Once you filled-in target audience field , data are stored in "Audience" property of the underlying element (e.g. item, document, navigation node). string audiencePropertyString = Convert.ToString(item.Properties["Audience"]); Note that we use Convert.ToString() instead of .ToString() to avoid any null exception if the property does not exist. 2. Get audience IDs from audience propertyAudienceManager class provides a very handy method GetAudienceIDsFromText that retrieves member's identifiers. string[] globalAudienceIds;
string[] dlDistinguishedNames;
string[] sharePointGroupNames;
int result = AudienceManager.GetAudienceIDsFromText(
audiencePropertyString,
out globalAudienceIds,
out dlDistinguishedNames,
out sharePointGroupNames);
We now have three arrays fulfilled with audiences IDs.
3. Get users from global audiences
Once compiled, a global audience is just a list of users. Thus it's quite straightforward to enumerate them. foreach (string globalAudienceId in globalAudienceIds)
{
AudienceManager am = new AudienceManager(ServerContext.GetContext(SPContext.Current.Site));
foreach (UserInfo member in am.GetAudience(new Guid(globalAudienceId)).GetMembership())
{
string email = member.Email;
// TODO: what you need with this email ...
}
}
4. Get emails of security groups members
In this example, we won't try to get users that are in groups of groups.
First this simple method helps us to get members of an Active Directory group:
/// <summary>
/// Get members of a specified AD group
/// </summary>
/// <param name="groupName">AD group name</param>
/// <returns>Members</returns>
private static List<DirectoryEntry> GetWindowsGroupMembers(string groupName)
{
// Variables
List<DirectoryEntry> members;
DirectorySearcher ds;
ResultPropertyCollection results;
DirectoryEntry member;
// Init
members = new List<DirectoryEntry>();
ds = new DirectorySearcher();
// Init directory searcher filter
if (groupName.StartsWith("cn=", StringComparison.InvariantCultureIgnoreCase))
{
ds.Filter = String.Format("({0})", groupName);
}
else
{
ds.Filter = String.Format("(cn={0})", groupName);
}
// Execute search
results = ds.FindOne().Properties;
// Get group members foreach (Object memberColl in results["member"])
{
member = new DirectoryEntry(String.Format("LDAP://{0}", memberColl));
if (member != null)
{
members.Add(member);
}
}
// Return members list
return members;
}
Then this method helps to get a property value of an active directory entry:
/// <summary>
/// Get property value from AD entry
/// </summary>
/// <param name="entry">Directory entry to request</param>
/// <param name="propertyName">Property name</param>
/// <returns>Property value</returns>
private static object GetWindowsUserPropertyValue(DirectoryEntry entry, string propertyName)
{
// Variables
object propertyValue = null;
System.DirectoryServices.PropertyCollection userProps = null;
// Get AD entry properties
userProps = entry.Properties;
// Get specified property values
propertyValue = userProps[propertyName].Value;
// Return property value
return propertyValue;
}
Finally we get email adresses from security groups members:
foreach (string dlDistinguishedName in dlDistinguishedNames)
{
// Connect to AD group
DirectoryEntry group = new DirectoryEntry(String.Format("LDAP://{0}", dlDistinguishedName));
// Init directory searcher
DirectorySearcher ds = new DirectorySearcher(group);
// Get AD group name
string groupName = ds.FindOne().GetDirectoryEntry().Name;
if (groupName.Contains(@"\"))
{
groupName = groupName.Substring(groupName.LastIndexOf(@"\") + 1);
}
// Get users infos
foreach (DirectoryEntry member in GetWindowsGroupMembers(groupName))
{
string email = Convert.ToString(GetWindowsUserPropertyValue(member, "mail"));
// TODO: what you need with this email ...
}
}
5. Get users from SharePoint groups
A SharePoint group is composed of SharePoint users, but a SharePoint user can also be a security group!
foreach (string sharePointGroupName in sharePointGroupNames)
{
// Get users from group
foreach (SPUser user in SPContext.Current.Web.SiteGroups[sharePointGroupName].Users)
{
// Add simples users emails to list
if (!user.IsDomainGroup)
{
string email = user.Email;
// TODO: what you need with this email ...
}
// The user is an AD group reference
else
{
// Get AD group names
string groupName = null;
if (user.LoginName.Contains(@"\"))
{
groupName = user.LoginName.Substring(user.LoginName.LastIndexOf(@"\") + 1);
}
else
{
groupName = user.LoginName;
}
// Get users infos and add email to list
foreach (DirectoryEntry member in GetWindowsGroupMembers(groupName))
{
string email = Convert.ToString(GetWindowsUserPropertyValue(member, "mail"));
// TODO: what you need with this email ...
}
}
}
}
Important note
To be able to browse your Active Directory, the application pool identity must be a domain account. But this should be the case... | |
| |
Goal of this post
I've been working on the past few days on a way to improve the logging infrastructure of our data visualization tool Charting for SharePoint.
I thought adding a new category to SharePoint Central Admin diagnostic logging screen would be straightforward. Damned! I'm still wondering why this part of the framework is so skeletal. I found so few documentation on IDiagnosticsManager and IDiagnosticsLevel - and the way to implement this stuff correctly - that I've decided to create a proxy class to make this finally easy.
Only very few lines of code are required to achieve that:
Play with the sample attached
The file attached to this post contains a sample implentation of my base class (see Samples folder from the Visual Studio solution)
You can try it by deploying Prexens.SharePoint.Diagnostics.wsp (see bin\Solution folder from the Visual Studio solution). This solution basically registers the DLL, provisions a farm level feature containing a receiver which registers the diagnostics manager when activated. The diagnostics manager is deleted when the feature is deactivated.
Implement your own diagnostics manager
Here are the steps to implement your own diagnostics manager based on my abstract class.
- Create a class library assembly and sign it. Add a new class and make it inherit from Prexens.SharePoint.Diagnostics.Samples.BaseDiagnosticsManager (see files attached to this post to get this class).
- Implement a parameterless constructor which passes a literal identifier for your diagnostics manager as a parameter of the base class contructor. Call RegisterCategory for any new entry you want to make visible from the list of SharePoint logging categories.
public SandboxDiagnosticsManager()
: base("My diagnostics manager")
{
RegisterCategory("My first custom logging category");
RegisterCategory("My second custom logging category");
}
- Override the method GetCurrentOnFarm(SPFarm farm) and paste the code below. Simply replace SandboxDiagnosticsManager with the name of your own class.
protected override BaseDiagnosticsManager GetCurrentOnFarm(SPFarm farm)
{
return farm.Services.GetValue<SandboxDiagnosticsManager>("My diagnostics manager");
}
That's it, you diagnostics manager is ready to go. Event and trace severity levels will be automatically persisted to SharePoint config DB when farm admins tweak the event throttling of your custom categories. The SharePoint OO will give you a hook to a cached copy of these settings anywhere, anytime.
Next step is to register your diagnostics manager as a SharePoint service.
Register your custom diagnostics manager
Run the following code in a console app. Again, replace SandboxDiagnosticsManager with the name of your own class SandboxDiagnosticsManager manager = new SandboxDiagnosticsManager();
SPFarm.Local.Services.Add(manager);
A cleaner way would be to create a farm feature registering your diagnostics manager on activation, and deleting it on deactivation (see attached file for a running sample of this approach).
Use your custom diagnostics manager
Event and trace severity levels associated with your custom categories can be retrevied this way: SandboxDiagnosticsManager manager =
SPFarm.Local.Services.GetValue<SandboxDiagnosticsManager>("My diagnostics manager");
IDiagnosticsLevel customLoggingCategory = manager.GetItem("My first custom logging category");
EventSeverity eventSeverity = customLoggingCategory.EventSeverity;
TraceSeverity traceSeverity = customLoggingCategory.TraceSeverity;
In my case, my custom categories are used in relevant part of the code of Charting for SharePoint to determine if a trace has to be outputted to ULS files according to trace and event severity levels configured through central admin.
Updates from my last post on March 6
I've updated my source code to make it Web farm compliant. Update method is indeed different when running code on several WFE. | |
| |
Quick description of the tool (abstract from Microsoft SharePoint Team Blog)
This tool is not supported by Microsoft and is recommended to be used on Developer workstations and not on production SharePoint Server installations. For additional information, please head over to Paul Andrew's blog post.
How to use it
- Install SPDisposeCheck.msi on your development server.
- Open a command window.
- Type following command:
"c:\Program Files\Microsoft\SharePoint Dispose Check\SPDisposeCheck.exe" <path to assemblies> -debug | |
| |
Goal of this post
This post is a good example of how to programmatically associate a Workflow to a list. The workflow can be standard or designed with SharePoint Designer or Visual Studio. As a workflow is using a standard tasks list and a specific workflow history list to run properly, the code will check and use or create them if necessary. It will also take care of associating the workflow with a list.
Code example
We assume that the variable web is a SPWeb object containing the list we want to associate the workflow with.
1. Declare objects we are going to use SPList myList = null; // List to associate workflow to
string myListName = null; // My list name
SPList historyList = null; // Workflow history list
SPList taskList = null; // Workflow tasks list
string workflowTemplateGuid = null; // Workflow template Guid
SPWorkflowTemplate workflowTemplate = null; // Workflow template
SPWorkflowAssociation workflowAssociation = null; // Workflow association
string workflowAssocName = null; // Workflow association name
2. Init Be sure to use the internal name of the list. And set the workflow association name, this will appair as workflow name in SharePoint list settings. myListName = "My list name";
workflowAssocName = "My Workflow";
3. Get Workflow template If you want to use a custom workflow and know its template GUID, use the GUID string. workflowTemplateGuid = "BAD855B1-32CE-4bf1-A29E-463678304E1A"; workflowTemplate = web.WorkflowTemplates[new Guid(workflowTemplateGuid)]; Instead you can get the workflow template GUID by using the GetTemplateByName method. workflowTemplate = web.WorkflowTemplates.GetTemplateByName( "Template name", System.Globalization.CultureInfo.CurrentCulture);
4. Get or create workflow history and tasks lists. The history list is dedicated to workflows and it's based on the WorkflowHistory list template. Most of times you'll have to create it. // Try to get workflow history list
try
{
historyList = web.Lists["Workflow History"];
}
catch (ArgumentException exc)
{
// Create workflow history list
Guid listGuid = web.Lists.Add("Workflow History", "", SPListTemplateType.WorkflowHistory);
historyList = web.Lists[listGuid];
historyList.Hidden = true;
historyList.Update();
}The tasks list is a common tasks list based on Tasks list template. If you want to create a specific tasks list for the workflow, don't use "Tasks" title for it. In the example we want to use a dedicated tasks list and will name it "Workflow Tasks". // Try to get workflow tasks list
try
{
taskList = web.Lists["Workflow Tasks"];
}
catch (ArgumentException exc)
{
// Create workflow tasks list
Guid listGuid = web.Lists.Add("Workflow Tasks", "", SPListTemplateType.Tasks);
taskList = web.Lists[listGuid];
taskList.Hidden = true;
taskList.Update();
}
5. Create workflow association, configure it and associate it to the list. // Allow unsafe updates on web
web.AllowUnsafeUpdates = true;
try
{
// Create workflow association
workflowAssociation = SPWorkflowAssociation.CreateListAssociation( workflowTemplate, workflowAssocName, taskList, historyList);
// Set workflow parameters
workflowAssociation.AllowManual = false;
workflowAssociation.AutoStartCreate = true;
workflowAssociation.AutoStartChange = false;
// Add workflow association to my list
myList.AddWorkflowAssociation(workflowAssociation);
// Enable workflow
workflowAssociation.Enabled = true;
}
finally
{
web.AllowUnsafeUpdates = false;
} | |
| |
Goal of this post This post sums up all the different methods to get handy information when you need to debug a SharePoint piece of code.
Problematic overview As a reminder, when an error occurs in a SharePoint page, the inexplicit error message appears:

Fortunately, you are able to display debug information, stack traces, detailed error messages, and more…
Solution, and many more
1. Set CustomError mode to Off and CallStack to true
When the message above occurs, the first step to execute is to configure the CustomError mode and the CallStack parameters in your web.config file:
System.Web.Compilation.AssemblyBuilder.Compile() at System.Web.Compilation.BuildProvidersCompiler.PerformBuild() at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)
You are now able to determine which instruction had caused the error and what is the real error message.
2. Display trace
When developing SharePoint applications or pages, even if the page builds successfully, you may need more information on the server variables, the headers, the forms post values, the cookies, the page web controls, the request trace, etc…
This feature natively exists in ASP.NET; you just have to enable it into your web application configuration and activate it on a specific page, or into the web.config file of your Web application:
Allow trace on a specific page:
Allow trace on the entire web site:
3. Using Visual Studio debugger
SharePoint developments can be debugged like console applications or windows applications by configuring the Visual Studio debugger.
Tip: you can attach your debugger to all the w3wp.exe processes, or determine which process is used by your current portal web application by opening a command prompt, and executing the following command: %systemroot%\System32\cscript.exe %systemroot%\System32\iisapp.vbs
Once you have found the Application ID, you just have to attach your project to the right w3wp.exe process (the one that executes your current portal web application):

If you want to have more details about debugging tips within Visual Studio, you can find more documentation on MSDN:
Tip: when debugging a custom workflow, remember to select Workflow as code type when attaching the process. Otherwise, Visual Studio may crash without explicit error message.
4. Looking for LOG files
Depending on your diagnostic logging configuration (see Central Administration > Operations > Diagnostic logging), SharePoint can log events on text files located by default in: "C:\Program Files\Common files\Microsoft Shared\web server extensions\12\LOGS"
For instance, if you have to debug a custom Workflow developed with Visual Studio, open the last log file (by sorting them by date), place your cursor at the end of the file, and search for workflow infrastructure (direction: top). You'll see the detailed error that occurred while executing your workflow.
5. Write your own custom trace in SharePoint log files
Source code and usage sample can be found at the following MSDN url:
http://msdn.microsoft.com/hi-in/library/aa979522(en-us).aspx | |
| | Goal of this post
This post aims at providing a step by step solution to an uncommon error which could happen when you try to import an Excel file to a SharePoint 2007 custom list.
Problematic overview
The "Import to a SharePoint List" feature is usually used to create and fill a custom list from an Excel source file.
For an unknown reason, this feature may not work properly on some client workstations whatever the version of SharePoint and Office Excel used. During the import step, the site designer receives the following error message box:

Solution
First we have to point out that this error isn't caused by SharePoint but by Ms Excel, and that the fix will have to be executed on each client workstation - at least site designers workstations - because standard users are not impacted by this error.
The issue will be fixed in two steps: first we need to edit the EXPTOOWS.XLA excel file, and then we have to restore the SharePoint sites collection(s).
Modify EXPTOOWS.XLA
- Open the Excel add-in "EXPTOOWS.XLA" located by default in "c:\Program Files\Microsoft Office\Office12\<LCID>", where <LCID> is your language identifier (for example, 1033 for a standard English installation, 1036 for a French one).
- Press ALT+F11 to open the Visual Basic source code editor
- Comment out the following line : "lVer = Application.SharePointVersion(URL)" by adding a simple quote at the beginning of the line
- Below the commented line, add the following instruction : IVer = 2
- Save your changes, and restart the client machine.
Backup and restore site the sites collection
The Excel install is now fixed, and you will be able to import Excel files in custom SharePoint list on the new SharePoint site collections. But in order to make this solution work on the actual site collection, you will have to backup and restore it by using STSADM command line tool which is provided with SharePoint (more information on STSADM command line tool are available by following this link : http://technet.microsoft.com/en-us/library/cc261956.aspx)
Execute the following commands :
stsadm -o backup -url http://PORTAL-URL -filename c:\Backups\BACKUP-FILE.dat
stsadm -o restore -url http://PORTAL-URL -filename c:\Backups\BACKUP-FILE.dat -overwrite
You can now start again the custom list importation from an Excel file, it should now work properly.
| |
| |
Goal of this post
This post guides you through the steps for inserting the famous DVWP, which is an exclusive part of SharePoint Designer, in a publishing page of a WCM site.
Problematic overview
As a reminder, when trying to open a publishing page with SharePoint Designer, the following message box appears:

Because we can't open the page in SharePoint Designer, we cannot configure and add the DVWP…
Solution
SharePoint Designer contains a very handy feature for WCM scenarios: " Detach from Page Layout ". This will break the inheritance between the publishing content page and its page layout.
First, start by duplicating the publishing page:

Right click on the copied page and select " Detach from Page Layout ": this will embed the layout in the content page. We can now open the content page as a standard " collaborative " page, configure and insert our Data View Web Part:

Once you've configured the Web Part, you can export it from the browser interface…

… then re-import it in the SharePoint Web Part Gallery:

You can now open the target content page again, and insert your custom DVWP directly in a Web Part zone.
Tip: we recommend you to keep the duplicated page in the library for further modifications!
| |
| |
When developing custom STSADM commands, it could be handy to debug our code in the real execution context of STSADM. To do so, you only have to deal with your Visual Studio project configuration.
1. Right click your VS project and go to properties
2. From Build Events tab, paste the following commands into the Post-buid event command line box
"%programfiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" /uf $(TargetName) "%programfiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" /if "$(TargetPath)"
3. From Debug tab, choose Start external program as a Start Action and browse for file C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\STSADM.EXE
4. In the Command line arguments text box, specify -o <name of your command> and the rest of your input parameters
5. You can now add break points to your code, run your project and debug your code in real conditions | |
|
1
- 10  |
|
|
|
|
|
|