Showing posts with label VSeWSS. Show all posts
Showing posts with label VSeWSS. Show all posts

Monday, January 4, 2010

How to: Develop SharePoint solutions using VSeWSS, move into WSPBuilder & develop custom field type

Hi all,

The development and deploying SharePoint solutions, I always use WSPBuilder. WSPBuilder is BEST TOOL for building and deploying WSP packages. I have dealt with both the tools and I preferred WSPBuilder of following reasons:
Pros:
1) Its highly stable and have higher performance.
2) Provides default templates such as Blank feature, Feature with eceiver, Event Handler, Sequential and state based workflows, Web part features etc.
3) Mimics 12 Hive structure.

Cons:
1) List instance, List Templates, Field Controls, List Definition from content type are NOT defined although they can defined with some efforts.
2) Can not reverse engineer the objects such as lists, templates, content types etc.


VSeWSS:
Pros:
1) Ability to get intellisense within all SharePoint framework files
2) Ability for a range of code snippets when within SharePoint framework files such as list instances, list templates, field controls etc. (not available in WSPBuilder).
3)   Ability to reverse engineer objects in a SharePoint Site instance to Feature using SharePoint Solutions Generator.   (not available in WSPBuilder)

Cons:
1) Performance issue and not very stable. While developing I used to get lot of errors.
2) Does not follow 12 Hive structure.
3) While deploying solutions, we may get this error: No language-neutral solution exists in the store.
4)  VSeWSS 1.3 has issues when you deploy WSP packages.

For more information on comparisons between VSeWSS and WSPBuilder follows these links:
>> Solution package development tool comparisons
>> SharePoint Development Tools


In this post, I will move SharePoint soltions from VSeWSS 1.2 to WSPBuilder. Apparently, Migration from VSeWSS to WSPBuilder is easy but there are some little tricks, you face some bugs and other workarounds to get the solutions working.

I am going to create a VSeWSS 1.2 project which will do the following:
1) Create a new custom field control and do some kind of validations using regular expressions.
2) Create a custom content type using those field control.
3) Create a List Definition from that content type.

Its a screen cast from channel 9.

NOTE: I had really tough time using VSeWSS 1.3 extensions and there were lot of issues. I finally reverted back to 1.2.
So, Lets get started:

Download the source

PartA. Create a VSeWSS 1.2 project.
---------------------------------------------------------------------------------------------------

Step1: Open up Visual Studio >> File >> New >> Project >> From "Project Types" select "SharePoint" and from "Templates" select "Empty".













Step2:  Right click on the project >> Add >> New Item >> List Instance and name it "Videos"












>> Choose the base type. Select the "Links".








 >> Open up the instance.xml, modify the "Title", "OnQuickLaunch" and some default rows in data elements.

 <ListInstance FeatureId="00bfea71-2062-426c-90bf-714c59600103"
                Title="Videos"
                Description="links to the videos"
                OnQuickLaunch="TRUE"
                Url="Lists/Videos">
    <Data>
      <Rows>
        <Row>
          <Field Name="URL">http://www.yahoo.com</Field>
          <Field Name="Comments">Link to yahoo website</Field>
        </Row>
        <Row>
          <Field Name="URL">http://www.google.com</Field>
          <Field Name="Comments">Link to google website</Field>
        </Row>
      </Rows>
    </Data>
  </ListInstance>


>> Right click on the project >> Add >> New Item >>  Field Control












Why to do need this is because our field is going to have a specific formatting requirements i.e. some kind of validations must be applied on that field.

Step3: Open up "TimeCode.Field.cs"

We have time span field which has format: "HH:MM:SS.MMMMMMM". We can follow same formatting requirements.
----------------------------------------------------------------------
  public override string GetValidatedString(object value)
        {
            string input = value.ToString();
            if (this.Required && string.IsNullOrEmpty(input))
            {
                throw new SPFieldValidationException("This field is required!");
            }


            Regex r = new Regex(@"^\d{2}:\d{2}:\d{2}\.\d{7}$");
            if (!r.IsMatch(input))
            {
                throw new SPFieldValidationException("Time code must be in the format of HH:MM:SS.MMMMMMM");
            }
            return base.GetValidatedString(value);
        }
-------------------------------------------------------------------------------------------
Project structure will be like this:


















Step4: Create a content type.

>> Right click on project >> Add >> New Item >> Content type












>> Choose the "Item" from the "Base Content Type"








>> We can see some commented "Fields" and "FieldRef"









>> Uncomment this field. Add 2 more fields namely "URL" and "TimeCodeField"

>> i) "URL" field "ID" is already defined in 12 >> Template >> Features >> Fields >> fieldswss.xml



     ii) "TimeCode" field is defined in TimeCode.Field.cs. "ID" is the Guid.








>> Do the same with "FieldRefs"




>> Save the project

Step5: List Definition from the Content type

>> Right click on the project >> Add >> New Item >> Choose  "List Definition from the Content type"












>> It will ask for new annotation type we just created a moments ago.We check the "Create an instance for this list. " and click OK. It will create some assets for us. The first asset will be instance definition.








>> Open the "instance.xml", modify the title element "AnnotationList Instance" to "Annotations". Add other elements like "Description", "OnQuickLaunch" etc.









>> Open the next asset "schema.xml". We minimize  the outlining of the elements of schema.xml so that we can seek through. Under "Metadata" we have element called as "Views". The BaseViewId="1" is the default view. If we expand that view, it defines elements called as "ViewFields". These are the columns which we will see i.e. "Attachments" and "LinkTitle". We will add 3 more "FieldRefs" in the default view namely "AnnotationID", "MediaPath" and "TimeCode".



















Step6: Feature Receiver

>> Apparently, when we provision the SharePoint solution and when we try to deactivate the list, it does not clean up automatically. We will do it on this part here.












>> Add SharePoint reference. (using Microsoft.SharePoint)
>> Make the class public and inherit from SPFeatureReceiver and implement abstract classes.

>> In "FeatureDeactivating" method we clean the "Annotation" list

  public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            using (var web = properties.Feature.Parent as SPWeb)
            {                 if (null != web)
                {
                       SPList list = web.Lists["Annoataions"];
                       if (null != list)
                          list.Delete();
              }
           }
        }


>> On top of class "ListFeatureReceiver", we add one attribute [CLSCompliant(false)]

Step7: WSP View

>> Open up the feature.xml under "Videos" folder.
>> We add 2 main elements
i) ReceiverClass: "Msdn.Web.ListFeatureReceiver"
ii) ReceiverAssembly:. For this, we have to compile the solution and use "WSPBuilder" option to "Copy to GAC".


Go to C:\Windows\Assembly, locate the Msdn.Web, right click and get the "PublicKeyToken"
and copy the token in the code as follows:
ReceiverAssembly="Msdn.Web, Version=1.0.0.0, Culture = neutral, PublicKeyToken = 9f4da00116c38ec5"

>> Deploy the solution










If you followed the steps, you will be able to test the solution.













------------------------------------------------------------------------------------------

PartB: Moving VSeWSS project to WSPBuilder project.

Well, migrating the VSeWSS to WSPBuilder is easy but there are some tricks. Its because VSeWSS DOES NOT follow 12 hive structure but WSPBuilder does. There are some other tricks which I will present in following steps.

Field Control and field validations:

Step8: Open upVisual Studio >> File >> New >> Project >> WSPBuilder project. Project name: WSPFieldControl


Right click on the project  >> Add >> New Item >> WSPBuilder >> Feature with receiver
ListFeatureReceiver and update the feature settings as follows:











Step9:
  Now, we have to follow the 12 hive structure here. In 12 hive ,we have XML folder where fieldtypes are defined. under 12 hive Therefore, we create a "XML" folder and copy "fldtypes_TimeCode.xml".


Moreover, in the "FeatureCode" folder, we copy "TimeCode.Field.cs" and "TimeCode.FieldControl.cs".
Build the solution and may get this error:

BUG1:





Just Add Reference >> Locate Microsoft.SharePoint.Security and build it again.
Build WSP >> Deploy.

>> Go to the SharePoint site >> Site Actions >> Site Settings >> Activate "Field Control".
To test of new field control is added, Go to the "Tasks" list >> List Settings >> "Create Column"

Strange! New Field control is not added.


















>> The reason is that we to rename the namespace "Msdn.Web" to "WSPFieldControl" in "TimeCode.Field.cs" and "TimeCode.FieldControl.cs"











>> Deploy the solution

 To test of new field control is added, Go to the "Tasks" list >> List Settings >> "Create Column" >> Choose "TimeCodeField" and hit "Ok" button.

We will get this error:






In general,
BUG2:

Field type <fieldname> is not installed properly. Go to the list settings page to delete this field.
Apparently, troubleshooting this issue took lot of time. I compared "Msdn.Web" project, and examined  "fldtypes_TimeCode.xml".







I had to use the assembly, which is "WSPFieldControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=600c68ca084bfb1c""






>> Deployed the solution again and To test of new field control is added, Go to the "Tasks" list >> List Settings >> "Create Column" >> Choose "TimeCodeField" and hit "Ok" button.
Again, you will get this error.






BUG3: 
The given assembly name or codebase was invalid.

>> After some more research, I found besides assembly, I have to also add the class i.e.
namespace.classname, assembly name, version, culture, publickeytoken


"WSPFieldControl.TimeCodeField, WSPFieldControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=600c68ca084bfb1c"


>> Deployed the solution again and To test of new field control is added, Go to the "Tasks" list >> List Settings >> "Create Column" >> Choose "TimeCodeField" and hit "Ok" button. It will work properly this time. Phew!!

Content type


Step10:  For developing the content type is quite simple. Under "ListFeatureReceiver" feature, we copy the content types in "elements.xml"













Also modify the "feature.xml" and update the scope to "Site" as content types are deployed on site level.
List definition with content types 

Step11:  Follow the same steps in previous blog post.
>> In "ListFeatureReceiver" feature create 3 folders "DocLib", "ListInstances", and "ListTemplates"
>> In feature.xml, get the feature ID and copy this is to ListDefinition.xml, schema.xml and ListInstances.xml.
>> a) feature.xml


   















b) schema.xml






c) ListTemplates.xml



 






 d) elements.xml (List Instance)









>> Deploy the solution.
>> Go to the SharePoint site >> Site Actions >> Site Collection Feature >> Activate the feature "Field Control".





>> On the home page, we can see the "Annotations" list.





Cheers,
--Aaroh

Saturday, August 15, 2009

How to: Extending the List Template programatically with "Content Types"

Hi All,

In previous last post, I had created a List Template and an List Instance programatically using VSeWSS and WSPBuilder. In the List Template (and also List Instance) we can also add "Content types" very easily.

>> We have can create the "content types" through SharePoint UI,
>> Attach the content types to the List Template and List Instance.
>> Use the SharePoint Solution Generator 2008 to reverse engineer the list and we can use this list as WSP package.

These are following steps:

Step1: Create content types through SharePoint UI by navigating to
Site Actions >> Site Settings >> Galleries > Site Content Types












Step2: Create new content type as follows:











Step3: We will create 2 content types for this list. Firstly, Create "Desktop" content type; Select parent content type: "Document Content Types";Parent Content Type: Document and create new group as "System Checklists"




















We will follow Secondly content type "Servers" with "System Checklists" group.


Step4: We navigate to "Test System Checklists" document library which we created through SharePoint UI, Settings >> Document Library Settings >> Add from existing site content type as follows:










Step5: Select site content types from "System Checklists" and both the content types i.e. Desktop and Servers and click OK.














Step6: Select the "Document" from the content type












Step7: Delete this default content type














Step8: Now, you will get these content type when you click on New button.













Step9: We need to SharePoint Solution Generator 2008, Choose "List Definition" >> Choose list (Test System Checklists) >> Project Name: System Checklists v2 >> Finish.

Copy schema.xml of "SystemChecklistsv2" (SharePoint Solution Generator 2008) to "IT.SystemChecklists". Modify the ID of schema.xml and use same as ListTemplates.xml and ListInstances.xml.

Build >> Upgrade the WSPBuilder.

Now, delete the "IT System Checklists" document library, deactivate the site feature "[IT] System Checklists" and activate the feature again.

You will see 2 content types for IT System Checklists.















Happy Programming!

--Aroh

Wednesday, August 12, 2009

How to: Create custom List Template and List Instance Programatically

Hi all,

I will show, how to create a list template and based this template creating list instances. I have used a Visual Studio 2008 Extensions as its creates XML files extremely fast but its not very useful to create WSP solutions. For this we can use WSPBuilder (click here) to package the solution.

Its always better to use Visual Studio 2008 Extensions. This can be downloaded here.
For our case, we will use both techniques i.e. VSeWSS and WSPBuilder.


Step1) Use VSeWSS extensions

Create a New >> New Project >> SharePoint >> Empty >> Project name: ListTemplateInstance












Step2) List definition settings

















Step3) ListDefinition.xml, Instance.xml and Schema.xml synchronized all the time since we are using IDs as follows:

List Instance:








List Template:








Schema.xml







We have to just modify schema.xml. Its huge file and if we try to modify by hand, you be overwhelmed and high probability and succumb to errors. Apparently, its an easy technique. Create the list using the SharePoint UI and export it using the
SharePoint Solution Generator 2008 which comes with the VSeWSS 1.3.

What is happening that when we create a Document Libary through a SharePoint UI and try to export this list, then SharePoint Solution Generator 2008 reverse engineer the lists and we can use this list as WSP package.

Step4) We create a document library namely "Test System Checklists" using SharePoint UI.











Step5)

We can also add new column (Period, Choice Type, Choices Daily,Weekly,Monthly,Yearly), in view "All Documents" we can select additional columns like created by, create and Group By Period






Now, we need to
SharePoint Solution Generator 2008, Choose "List Definition" >> Choose list (Test System Checklists) >> Project Name: System Checklists >> Finish

Copy schema.xml of "SystemChecklists" (SharePoint Solution Generator 2008) to "ListTemplateInsance".








Keep in mind that we have to modify the schema.xml ID like ListInstance.xml and ListDefintion.xml as SharePoint Solution Generator 2008 created a new ID. All the IDs must be consistent.

Right click on the project >> Properties >> Click on the DEBUG tab >> Choose "Start browser with URL: http://<>/sites/systemcheklists".

--------------------------------------------------------------------------------
CAUTION: If you forget this step then we will get this error:

Attempted to perform an unauthorized operation.
--------------------------------------------------------------------------------

Fix : Goto the project properties and inside the debug tab select the start action as 'start browser with url' and enter the valid site collection URL. Please check the site collection before you use it over here.

Final step is to build and deploy the solution.


We can List Instance and List Templates as follows:


(List Instance)









(List Template)













Step6)
Now, create a new WSPBuilderProject called as
IT.SystemChecklists Right-Click on project >> Add >> Add New Item >> Choose "Feature with Receiver" >> Name: ListTemplateReceiver. The structure should be as follows:




















Rename ListTemplateReceiver to IT.SystemChecklists.






















Now, under IT.Checklists, we need to create 3 folders namely: ListTemplates, ListInstances and DocLib.

Copy these files from ListTemplateInstance to IT.SystemChecklists:

>> ListTemplates: ListDefinition.xml
>> ListInstances: ListInstances.xml
>> DocLib: schema.xml and other aspx pages.






















The MOST important part of this step is that when you define ListTemplate, the NAME attribute is exactly
same as the Folder Name you have the schema.xml File stored in. Trust me, it took almost 2 days to fix this issue.

If you don't use some other folder name then you will get this error:

---------------------------------------------------------------------------------------

Caution: Exception from HRESULT: 0x81070201
--------------------------------------------------------------------------------------








Step7) In feature.xml, get the feat
ure ID and copy this is to ListDefinition.xml, schema.xml and ListInstances.xml.


feature.xml (ID must be same as ListDefinition.xml, schema.xml and ListInstances.xml)







schema.xml






Instances.xml








ListTemplates.xml







Step8)
These is an elements.xml file which is empty. Cut the ListInstance element of ListInstance.xml and copy to elements.xml.

We to provision the List Template (ListTemplates\ListDefinition.xml), List Instances (elements.xml) and schema.xml (DocLib\schema.xml and other aspx pages) in feature.xml as follows:





























feature.xml
 

<?xml version="1.0" encoding="utf-8"?>
<Feature Id="eb656c28-ba1c-4d6e-a117-7e06015b2bc9"
Title="[IT] System Checklists"
Description="Description for ListTemplateReceiver"
Version="12.0.0.0"
Hidden="FALSE"
Scope="Web"
DefaultResourceFile="core"
ReceiverAssembly="IT.SystemChecklists, Version=1.0.0.0, Culture=neutral, PublicKeyToken=135fa78ef0185fbd"
ReceiverClass="IT.SystemChecklists.ListTemplateReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/">

<ElementManifests>

<ElementManifest Location="ListTemplates\ListDefinition.xml" />
<ElementManifest Location="elements.xml"/>

<ElementFile Location="DocLib\schema.xml" />
<ElementFile Location="DocLib\AllItems.aspx" />
<ElementFile Location="DocLib\Combine.aspx" />
<ElementFile Location="DocLib\DispForm.aspx" />
<ElementFile Location="DocLib\EditForm.aspx" />
<ElementFile Location="DocLib\Repair.aspx" />
<ElementFile Location="DocLib\Upload.aspx" />
<ElementFile Location="DocLib\WebFldr.aspx" />

</ElementManifests>

</Feature
>

elements.xml



<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<ListInstance FeatureId="eb656c28-ba1c-4d6e-a117-7e06015b2bc9"
Id="BBC82E2A-043C-42d6-A4E7-B0DE6A45687B"
Title="IT System Checklists"
Url="Lists/SystemChecklists"
OnQuickLaunch="TRUE"
TemplateType="101">
</ListInstance>

</Elements>


ListTemplates.xml

<?xml version="1.0" encoding="utf-8" ?>

<Elements Id="eb656c28-ba1c-4d6e-a117-7e06015b2bc9" xmlns="http://schemas.microsoft.com/sharepoint/">

<ListTemplate Name="DocLib"
DisplayName="IT System Checklists"
Description=""
BaseType="1"
Type="101"
OnQuickLaunch="TRUE"
SecurityBits="11"
Sequence="110"
Image="/_layouts/images/itdl.gif"
DocumentTemplate="101" />

</Elements>


Step9) Activate the feature and test it.

Activate the feature (IT.SystemChecklists).





Hopefully, the List Instance should be shown on quick launch menu.









and also List Template as follows:








-------------------------------------------------------------------------------
CAUTION: At times, during the testing and try to activate the "IT.SystemChecklists", I used to get this Error:
Exception from HRESULT 0x81070215

It happens when open a list, either the list is has not properly been deleted and is in a corrupted state.

Fix:

Although the help message displays information about using the forcedeleteweb operation, you have to use forcedeletelist instead. The syntax is:
stsadm.exe -o forcedeletelist -url <url>
For e.g. if the list called as "Annotations" has corrupted just fire up this command:

stsadm -o forcedeletelist -url http://server/apac/lists/annotations

For more info:
http://bloggingabout.net/blogs/harold/archive/2009/01/10/deleting-a-broken-sharepoint-list-using-stsadm.aspx

http://technet.microsoft.com/en-us/library/cc262609.aspx

Just fire the stsadm command and activate the feature.
-------------------------------------------------------------------------------

Happy Programming!
--aaroh

Low Code Reimagined with AI + Copilot Pitch Deck - Copy Copilot day (Virtual) - 2023

 Hi All,  I presneded a session at Pune UG on Low Code Reimagined with AI + Copilot Pitch Deck.  Video is at this address  https://www.youtu...