Tuesday, 25 June 2013
Thursday, 16 May 2013
Backup/Restore of SharePoint 2010 site Collection using Power Shell
In this article I am showing you how to perform backup/restore operation using Power Shell
1. On the Start menu, click All Programs.
1. On the Start menu, click All Programs.
2. Click Microsoft SharePoint 2010 Products.
3. Click SharePoint 2010 Management Shell.
4. At the Windows Power Shell command prompt type the following command:
5. You will get a Power shell command prompt like below
6. In SharePoint 2010, Power Shell command Backup-SPSite is used for taking backup
7. Please see the screen shot for the backup Power Shell command
8. Backup-SPSite -Identity http://ServerName:port -Path "c:\backup\file.bak"
9. If you want to overwrite a previously used backup file, use the Force parameter. You can use the NoSiteLock parameter to keep the read-only lock from being set on the site collection while it is being backed up. However, using this parameter can allow users to change the site collection while it is being backed up and might lead to possible data corruption during backup.
10. Once this done you will get the backup.
11. Next you have to create site collection then use the below command to restore the backup that we currently taken.
12. Restore-SPSite -Identity http://Servername:port -Path "c:\backup\file.bak" -force
13. I am using force command because I want to overwrite the existing site collection that I created now.
Sunday, 12 May 2013
Friday, 1 February 2013
Using the SharePoint 2010 Client Object Model in JavaScript
Why use the SharePoint Client Object Model for JavaScript?
Using
the COM allows developers to create a web page that can interact with
SharePoint without requiring a page refresh. In the background, the page
uses JavaScript to communicate with SharePoint via the COM to retrieve
or update data in SharePoint. JavaScript can then update the page to
reflect the updated data from SharePoint.
Accessing SharePoint
The
first thing to note about the COM with JavaScript is that it is
disconnected from SharePoint in the sense that in order to retrieve or
update data in SharePoint, asynchronous calls to the server must be
made. Because of its asynchronous nature, the page can continue to be
responsive to the user while the data is being retrieved or updated in
the background. This can be both an asset and a liability if not handled
properly.
In
order to access the COM in a webpage, a reference to the JavaScript
file containing the COM code must be included. There are 3 JavaScript
files which contain the code for the COM: SP.js, SP.Core.js, and
SP.Runtime.js. SharePoint provides the SharePoint:ScriptLink server control tag for referencing JavaScript files. Using the ScriptLink control will:
- assure that the JavaScript file is loaded only once
- assure that dependency files are also loaded
In a SharePoint Application page, the ScriptLink tag should be declared within the PlaceHolderAdditionalPageHead Content Placeholder.
<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server" />
<SharePoint:ScriptLink Name="SP.js" LoadAfterUI="true" runat="server" />
</asp:Content>
<SharePoint:ScriptLink Name="SP.js" LoadAfterUI="true" runat="server" />
</asp:Content>
How to retrieve a ListItem from a SharePoint List
The following code sample shows how to connect to create a connection to SharePoint and access the Root Web.
var ListItem;
function GetListItemById(listName, listItemId)
{
var SPContext = new SP.ClientContext.get_current();
var web = SPContext.get_web();
var list = web.get_lists().getByTitle(listName);
ListItem = list.getItemById(listItemId);
SPContext.load(ListItem, "Id", "Title");
SPContext.executeQueryAsync(GetListItemById_Success, GetListItemById_Fail);
}
function GetListItemById_Success(sender, args)
{
var id = ListItem.get_id();
var title = ListItem.get_item("Title");
alert("Updated List Item: \n Id: " + id + " \n Title: " + title);
}
// Display an appropriate error message
function GetListItemById_Fail(sender, args)
{
alert("GetListItemById Failed. \n" + args.get_message() + "\n" + args.get_stackTrace());
}
function GetListItemById(listName, listItemId)
{
var SPContext = new SP.ClientContext.get_current();
var web = SPContext.get_web();
var list = web.get_lists().getByTitle(listName);
ListItem = list.getItemById(listItemId);
SPContext.load(ListItem, "Id", "Title");
SPContext.executeQueryAsync(GetListItemById_Success, GetListItemById_Fail);
}
function GetListItemById_Success(sender, args)
{
var id = ListItem.get_id();
var title = ListItem.get_item("Title");
alert("Updated List Item: \n Id: " + id + " \n Title: " + title);
}
// Display an appropriate error message
function GetListItemById_Fail(sender, args)
{
alert("GetListItemById Failed. \n" + args.get_message() + "\n" + args.get_stackTrace());
}
Let's
break down the code. First, we declare a global variable which will
contain the data returned from SharePoint via the COM. Since we must use
asynchronous calls to SharePoint, the data must be stored somewhere
that is accessible by the CallBack function that will be called once the data has been retrieved from SharePoint.
var SPContext = new SP.ClientContext.get_current();
Next,
the code creates an object which will facilitate the communication
between JavaScript and SharePoint. This is done by accessing the current property of the SP.ClientContext object by calling the get_current() method.
Note:
In JavaScript, COM properties are access by calling a function which is
named "get_" + the name of the property. For example, the id property
which all COM objects have is accessed by calling the object's get_id()
method.
var web = SPContext.get_web();
var list = web.get_lists().getByTitle(listName);
var list = web.get_lists().getByTitle(listName);
Next, the Root Web property of the SPClientContext object can be accessed by calling the get_web() method. The Web has a SharePoint Lists collection property which is accessed by calling get_lists() method.
ListItem = list.getItemById(listItemId);
Then to identify the specific List, a call is made to the getByTitle() method passing in the name of the List. Finally, to identify a specific List Item in the List, a call is made to the getItemById() method passing in the List Item's ID value.
At
this point, there still has been no data retrieved from SharePoint. The
code has simply been identifying which data will be retrieved.
Since
it is the List Item data that will be retrieved and accessed in the
CallBack function, it must be assigned to a global variable that can be
accessed later by the CallBack function.
SPContext.load(ListItem, "Id", "Title");
Now
that the specific data to be retrieved has been identified, we need to
tell it specifically what data to return. It is the client context
object's load() method which specifies which data will be retrieved. The load() method's first parameter is the object to return data for, followed by the names of the List Fields to return.
Note:
While it is possible to call the load() method without specifying the
List Fields, this will return data for every Field in the List,
including hidden fields. Since loading all of the List Fields can add 10
times the amount of data needed, it will always be in your best
interest to specify the specific Fields to load.
SPContext.executeQueryAsync(GetListItemById_Success, GetListItemById_Fail);
Finally, a call to the executeQueryAsync()
method will initiate the actual call to the server. This method takes
the 2 CallBack functions to call. The first will be called if the data
is successfully retrieved from SharePoint, while the second will be
called in the case there was an error retrieving the data.
function GetListItemById_Success(sender, args)
function GetListItemById_Fail(sender, args)
function GetListItemById_Fail(sender, args)
Each CallBack function can take the sender and args parameters which return additional information about the results of the server call.
var id = ListItem.get_id();
var title = ListItem.get_item("Title");
var title = ListItem.get_item("Title");
In the "success" CallBack function, the objects and their properties which were specified in the load() method can now be accessed using the object's get_item() method passing in the name of the field.
How to create a ListItem in a SharePoint List
function CreateListItem(listName, title)
{
var SPContext = new SP.ClientContext.get_current();
var web = SPContext.get_web();
// Create a new List Item
var SPContext = new SP.ClientContext.get_current();
var list = web.get_lists().getByTitle(listName);
ListItem = list.addItem(new SP.ListCreationInformation());
ListItem.set_item("Title", title);
ListItem.update();
SPContext.executeQueryAsync(CreateListItem_Success, CreateListItem_Fail);
}
function CreateListItem_Success(sender, args)
{
alert("New List Item Created");
}
// Display an appropriate error message
function CreateListItem_Fail(sender, args)
{
alert("CreateListItem Failed. \n" + args.get_message() + "\n" + args.get_stackTrace());
}
{
var SPContext = new SP.ClientContext.get_current();
var web = SPContext.get_web();
// Create a new List Item
var SPContext = new SP.ClientContext.get_current();
var list = web.get_lists().getByTitle(listName);
ListItem = list.addItem(new SP.ListCreationInformation());
ListItem.set_item("Title", title);
ListItem.update();
SPContext.executeQueryAsync(CreateListItem_Success, CreateListItem_Fail);
}
function CreateListItem_Success(sender, args)
{
alert("New List Item Created");
}
// Display an appropriate error message
function CreateListItem_Fail(sender, args)
{
alert("CreateListItem Failed. \n" + args.get_message() + "\n" + args.get_stackTrace());
}
This example is very similar to the previous one, so I will only point out the differences.
ListItem = list.addItem(new SP.ListCreationInformation());
ListItem.set_item("Title", title);
ListItem.set_item("Title", title);
Once
the List has been identified, a new List Item is created and added to
the List. This is done by creating an instance of the
SP.ListCreationInformation class. Then the properties of the new List
Item object are set by using the set_item() method passing in the name of the property and the value to set it to.
ListItem.update();
SPContext.executeQueryAsync(CreateListItem_Success, CreateListItem_Fail);
SPContext.executeQueryAsync(CreateListItem_Success, CreateListItem_Fail);
The update() method is called to tell SharePoint to save the changes that were made. Finally the call to executeQueryAsync() method is made to send the request to SharePoint.
Note:
In this example, the load() method was not called, and therefore there
will not be any SharePoint data accessible in the "success" CallBack
function. However, the load() method could have been called. In which
case, the newly created List Item would be available.
How to update a ListItem in a SharePoint List
function UpdateListItem(listName, title)
{
var SPContext = new SP.ClientContext.get_current();
var web = SPContext.get_web();
var list = web.get_lists().getByTitle(listName);
ListItem = list.getItemById(listItemId);
// Update an existing List Item
ListItem.set_item("Title", title);
ListItem.update();
SPContext.executeQueryAsync(UpdateListItem_Success, UpdateListItem_Fail);
}
function UpdateListItem_Success(sender, args)
{
alert("List Item Updated");
}
// Display an appropriate error message
function UpdateListItem_Fail(sender, args)
{
alert("UpdateListItem Failed. \n" + args.get_message() + "\n" + args.get_stackTrace());
}
{
var SPContext = new SP.ClientContext.get_current();
var web = SPContext.get_web();
var list = web.get_lists().getByTitle(listName);
ListItem = list.getItemById(listItemId);
// Update an existing List Item
ListItem.set_item("Title", title);
ListItem.update();
SPContext.executeQueryAsync(UpdateListItem_Success, UpdateListItem_Fail);
}
function UpdateListItem_Success(sender, args)
{
alert("List Item Updated");
}
// Display an appropriate error message
function UpdateListItem_Fail(sender, args)
{
alert("UpdateListItem Failed. \n" + args.get_message() + "\n" + args.get_stackTrace());
}
Updating
a List Item is simply a combination of identifying an existing List
Item as seen in the first example and then setting the property values
of the List Item as seen in the second example.
Again, if we actually want to access the values of the List Item as stored in SharePoint after it is updated, a call to the load() method could be made specifying the objects and their fields to retrieve from SharePoint.
How to delete a ListItem from a SharePoint List
function DeleteListItem(listName, title)
{
var SPContext = new SP.ClientContext.get_current();
var web = SPContext.get_web();
// Retrieve the List Item
var list = web.get_lists().getByTitle(listName);
ListItem = list.getItemById(listItemId);
// Delete the List Item
ListItem.deleteObject();
SPContext.executeQueryAsync(DeleteListItem_Success, DeleteListItem_Fail);
}
function DeleteListItem_Success(sender, args)
{
alert("List Item Deleted");
}
// Display an appropriate error message
function DeleteListItem_Fail(sender, args)
{
alert("DeleteListItem Failed. \n" + args.get_message() + "\n" + args.get_stackTrace());
}
{
var SPContext = new SP.ClientContext.get_current();
var web = SPContext.get_web();
// Retrieve the List Item
var list = web.get_lists().getByTitle(listName);
ListItem = list.getItemById(listItemId);
// Delete the List Item
ListItem.deleteObject();
SPContext.executeQueryAsync(DeleteListItem_Success, DeleteListItem_Fail);
}
function DeleteListItem_Success(sender, args)
{
alert("List Item Deleted");
}
// Display an appropriate error message
function DeleteListItem_Fail(sender, args)
{
alert("DeleteListItem Failed. \n" + args.get_message() + "\n" + args.get_stackTrace());
}
Again,
deleting a List Item is very similar. In order to delete a List Item,
the List Item must first be identified as in the first example and then a
call made to its deleteObject() method to tell SharePoint to delete the List Item. Finally a call to the executeQueryAsync() method to send the updates to SharePoint.
SharePoint 2010 Client Object Model
Introduction
In this article I would like to discuss about the Client Object Model feature of SharePoint 2010.Overview
Client Object Model is a new feature of SharePoint 2010. It provides features to program against a SharePoint site using .NET Managed Code or JavaScript.The Client Object Model provides almost all the programming features of the Server Object Model plus advantages in deployment. The Client OM (Client Object Model) is being used as the core programming aid for SharePoint 2010 and thus widely used in the market.
Advantages
- Less Deployment Hassles: Using Client OM, you do not need to install the components required by the Server Object Model. Thus Client OM provides much ease to the end user.
- Language Flexibility: We can use the following languages to work with the Client OM:
- Microsoft .NET
- Silverlight
- ECMA Script (JavaScript /JScript)
- Query Speed Optimizations: In the Client OM, reduced network traffic is attained using Query Optimizations. Thus the user will feel reduced round trips and other advantages like paged results, etc.
How it works?
The Client OM works by sending an XML Request. The server will return a JSON response which is converted to the appropriate Object Model.Supported Languages
Following are the programming language/platforms supported for Client Object Model:- .NET Languages (C#, VB.NET etc.)
- Silverlight
- Scripting Languages (JavaScript, Jscript)
Core Assemblies
There are two assemblies to be referred for working with the Client Object Model.- Microsoft.SharePoint.Client.dll
- Microsoft.SharePoint.Client.Runtime.dll
Classes inside Client Object Model
In C#, comparing with classes of the Server Object Model, we can see that Client Object Model has similar classes with a suffix in the namespace and no SP prefix in the class name.For example:
SPSite in the Server Object Model is represented in
the Client OM as Site with namespace
Microsoft.SharePoint.Client.|
Client Object Model |
Server Object Model |
|
Microsoft.SharePoint.Client.ClientContext |
SPContext |
|
Microsoft.SharePoint.Client.Site |
SPSite |
|
Microsoft.SharePoint.Client.Web |
SPWeb |
|
Microsoft.SharePoint.Client.List |
SPList |
Example
Following is an example of retrieving a list from the server using Client OM:ClientContext context = new ClientContext("http://hp");
List list = context.Web.Lists.GetByTitle("Tasks");
context.Load(list);
context.ExecuteQuery();
Console.WriteLine(list.Title);
Console.ReadKey(false);
I should remark something about the above code:- Even though there are multiple calls, they are not sent to the server until
ExecuteQuery()is called. - Network round trips between the client and server are reduced by combining multiple calls into one.
- Object Identity is used to setup the queries. Object Identities are those which refer to the Server Object Model. Object Identities are valid only for the current client context.
More Examples with Client Object Model
Here I would like to list some examples using the Client Object Model. For starting with the examples, please do the following:- Create a Windows Application
- Change the Target Framework to .NET 4.0
- Add reference to Microsoft.SharePoint.Client, Microsoft.SharePoint.Client.Runtime
Tasks list. We will be changing the data items during our session.1. Get List Items
Here we are querying the list items of theTasks list.ClientContext context = new ClientContext(ServerText.Text);
List list = context.Web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View/>";
ListItemCollection items = list.GetItems(query);
context.Load(list);
context.Load(items);
context.ExecuteQuery();
After executing the code, the result can be stored into a DataTable as shown below.DataTable table = new DataTable();
table.Columns.Add("Id");
table.Columns.Add("Title");
foreach (ListItem item in items)
table.Rows.Add(item.Id, item["Title"]);
datagrid.DataSource = table;
On my machine, the data retrieved is shown below:2. Update List Items
Here I would like to show the modification code. All the titles are appended with two asterisks whose IDs are even number.ClientContext context = new ClientContext(ServerText.Text);
List list = context.Web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View/>";
ListItemCollection items = list.GetItems(query);
context.Load(items);
context.ExecuteQuery();
foreach(ListItem item in items)
if ((item.Id % 2) == 0)
{
item["Title"] += "**";
item.Update();
}
context.ExecuteQuery();
After executing the query, please refresh the data grid using the Get Data button. You can see the following result.You can see that the Titles are modified for those with even number IDs.
3. Get By Row Limit
Here we can experiment with theRowLimit tag inside CAML queries. You can note that while accessing
the list we are actually using a
CAMLQuery class instance. Inside the
query it is possible to set the RowLimit tag as well.The
RowLimit tag restricts the number of items retrieved
from the server. Thus we can save a lot of bandwidth by reducing the
rows while doing search.ClientContext context = new ClientContext(ServerText.Text);
Web web = context.Web;
List list = web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><RowLimit>3</RowLimit></View>";
ListItemCollection listItems = list.GetItems(query);
context.Load(listItems);
context.ExecuteQuery();
You can see that the RowLimit is set to 3. On executing the query and displaying the results to a data grid, you can see
three items as shown below.4. Get By Search Criteria
Now we can try selecting the list items using the search criteria. Here we are trying to get the items of Status as ‘In Progress’.ClientContext context = new ClientContext(ServerText.Text);
List list = context.Web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = @"<View>
<Query>
<Where>
<Eq>
<FieldRef Name='Status'/>
<Value Type='Text'>In Progress</Value>
</Eq>
</Where>
</Query>
</View>";
ListItemCollection listItems = list.GetItems(query);
context.Load(listItems, items => items.Include(
item => item["Id"],
item => item["Title"],
item => item["Status"]
));
context.ExecuteQuery();
On executing the code above, you will get the results filtered by the Status field.5. Insert an Item
Here we can try inserting a new item into the Tasks list.ClientContext context = new ClientContext(ServerText.Text);
Web web = context.Web;
List list = web.Lists.GetByTitle("Tasks");
ListItemCreationInformation newItem = new ListItemCreationInformation();
ListItem listItem = list.AddItem(newItem);
listItem["Title"] = "New Item Created through C#";
listItem.Update();
context.ExecuteQuery();
You can see that we are using a new class named ListItemCreationInformation along with the
ListItem class. This information will be recorded and passed to the server
once the ExecuteQuery() method is called.On executing the above code and retrieving the results, you can see the output as below:
6. Update an Item
The Update operation is next in the series of the CRUD pattern. Already we have seen updating the Title. Here you can see how to update the Status.ClientContext context = new ClientContext(ServerText.Text);
List list = context.Web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View/>";
ListItemCollection listItems = list.GetItems(query);
context.Load(listItems);
context.ExecuteQuery();
ListItem item = listItems[listItems.Count - 1];
item["Status"] = "In Progress";
item.Update();
context.ExecuteQuery();
On executing the code, you can see that the last item was updated.7. Delete an Item
Now we can try deleting an item from the List. Here is the code to achieve that.ClientContext context = new ClientContext(ServerText.Text);
List list = context.Web.Lists.GetByTitle("Tasks");
ListItemCollection listItems = list.GetItems(new CamlQuery() { ViewXml = "<View/>" });
context.Load(listItems);
context.ExecuteQuery();
listItems[listItems.Count - 1].DeleteObject();
context.ExecuteQuery();
We need to call the DeleteObject() method of the item followed by the ExecuteQuery().8. Reducing the Result Size by Specifying Properties
So what if you wanted only one property value for an item with 10 properties? There will be unwanted transferring of 9 columns. Here we can see how to specify only the needed columns for an item.ClientContext context = new ClientContext(ServerText.Text);
Web web = context.Web;
context.Load(web, w => w.Title);
context.ExecuteQuery();
MessageBox.Show("The title is: " + web.Title);
MessageBox.Show("Now trying to access a field not in Result Set (expect exception)");
try
{
MessageBox.Show(web.Description); // You will get Error here
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Here we can see that only the Title property has been specified for retrieval. Accessing the Description column throws an exception.9. Reducing the Result Size in List
In the case of the list the problem is worse as there are n number of columns for the list. The result will be multiplied n times. So if we need only 1 column and retrieve 10 columns for a list of 1000 items, we end up getting 9 x 1000 unwanted column values.So to specify the list columns in the Result Set the syntax will be slightly different.
ClientContext context = new ClientContext(ServerText.Text);
List list = context.Web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View/>";
ListItemCollection listItems = list.GetItems(query);
context.Load(listItems, items => items.Include(item => item["Id"]));
context.ExecuteQuery();
Please note the way Id is specified. While filling the results, you should take care that only the ID column value is accessed.DataTable table = new DataTable();
table.Columns.Add("Id");
foreach (ListItem item in listItems)
table.Rows.Add(item.Id);
datagrid.DataSource = table;
10. Specifying Credentials
You can specify user credentials while accessing the SharePoint server. The propertyCredentials is for this purpose.ClientContext context = new ClientContext(ServerText.Text);
context.Credentials = new NetworkCredential("User", "Password");
Web web = context.Web;
context.Load(web);
context.ExecuteQuery();
MessageBox.Show(web.Title);
Please specify the correct user name and password of your site otherwise an Unauthorized Exception will be thrown.So this concludes the article with Client Object Model examples for the most common scenarios. In the real world you will need much more complicated steps and I believe these will provide a base to achieve them.
When to use Server Object Model?
We can use it on the SharePoint server where the Server Object Model binaries are available. Typical example would be inside Web Parts / Workflows.When to use Client Object Model?
We can use it from client machines where the entire SharePoint binaries are not available. A typical example would be from a Windows Forms application in a client machine.http://www.codeproject.com/Articles/399156/SharePoint-2010-Client-Object-Model-Introduction
Monday, 15 October 2012
Wednesday, 19 September 2012
Monday, 20 August 2012
CREATE WORKFLOW WITH CUSTOM TASK FORM (ASPX PAGE) IN SHAREPOINT 2010
Article purpose:
When create new a requirement => will appear a register form (ASPX Form), after register successful, workflow auto run and send Task for any people, and that requirement when people receive it will open Task to Approve on form (ASPX Form)
Steps implement
CREATE NEW CONTENT TYPE FOR LIST TARGET
CREATE NEW LIST DEFINITION FOR LIST TARGET
CREATE NEW MODULE
CREATE NEW CUSTOM ASPX FORM (APPLICATION PAGE) FOR LIST TARGET
CREATE NEW CONTENT TYPE FOR LIST TASK
TẠO CUSTOM ASPX FORM (APPLICATION PAGE) FOR LIST TASK
CREATE NEW BASIC WORKFLOW
CREATE NEW EVENT RECEIVER TO ACTIVE WORKFLOW RUN WHEN ADD CONTENT TYPE ITEM
Implement
Open visual studio | New Project | Visual C# | Sharepoint | 2010 | Empty Sharepoint Project | name í MSTechSharing_TaskFormASPX
Choose “Deploy as a farm solution”
CREATE NEW CONTENT TYPE FOR LIST TARGET
Right click to project | New Item | Content type | name is MSTechSharing_TaskFormASPX_ContentTypeTargetList
Choose Content Type Item
Structure of Element.xml file content type as follows
CREATE NEW LIST DEFINITION FOR LIST TARGET
Right click to project | Add new item | List Definition From Content Type | Name is MSTechSharing_TaskFormASPX_ListDefinition_TargetList
Choose content type inherit from content type “MSTechSharing_TaskFormASPX_ContentTypeTargetList” had created above
Structure of List Definition as follows
change 100 number in Element.xml file of ListInstance1 if you want to your List is custom list
Must change 100 number in Element file of MSTechSharing_TaskFormASPX_ListDefinition_TargetList (image 10)
This is structure of Schema.xml in MSTechSharing_TaskFormASPX_ListDefinition_TargetList list
In tag <FieldRefs> </ FieldRefs> insert Fields as follows (option)
<!--Insert to here-->
<FieldRef ID="FA564E0F-0C70-4AB9-B863-0177E6DDD247" Name="Title" Hidden="TRUE" Required="FALSE"/>
<FieldRef ID="{D37DE7CA-1296-47CF-91EB-2C8D09D94C00}" Name="Description" />
<!--End Insert to here-->
Insert the segment code to register form aspx when display you Add New Item
<!--Insert to here-->
<XmlDocuments>
<XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<FormTemplates xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<Display>ListForm</Display>
<Edit>ListForm</Edit>
<New>ListForm</New>
</FormTemplates>
</XmlDocument>
<XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
<FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url" >
<New>Form/TargetList_AddNew.aspx</New>
</FormUrls>
</XmlDocument>
</XmlDocuments>
<!--End Insert to here-->
In tag <Fields> </Fields> insert segment code as follows
<!--Insert to here-->
<Field Type="Text" ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" ReadOnly="TRUE" Required="FALSE"Hidden="TRUE"
SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Title"></Field>
<Field ID="{d37de7ca-1296-47cf-91eb-2c8d09d94c00}" Type="Text" Name="Description" DisplayName="Description" />
<!--End Insert to here-->
TẠO MỚI MODULE
Right click to Project | Add new Item | Module | name is Form then delete file Sample.txt
CREATE NEW CUSTOM ASPX FORM (APPLICATION PAGE) FOR LIST TARGET
Right click to Project | Add new Item | Application Page | name is TargetList_AddNew.aspx
Application Page structure as follows
Change DynamicMasterPageFile to MasterPageFile by delete Dynamic character
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TargetList_AddNew.aspx.cs"
Inherits="MSTechSharing_TaskFormASPX.Layouts.MSTechSharing_TaskFormASPX.TargetList_AddNew"PageFile="~masterurl/default.master" %>
Copy segment code into PlaceHolderMain (image 20)
<table style="width: 900px;">
<tr>
<td class="column1">
Họ và tên
</td>
<td class="column2">
<asp:TextBox ID="TextBox_HoTen" runat="server" Width="309px"></asp:TextBox>
</td>
</tr>
</table>
Copy Target list to PlaceHolderAdditionalPageHead, PlaceHolderPageTitle, PlaceHolderPageTitleInTitleArea
Using and change class inherit from LayoutsPageBase to WebPartPage as follows:
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.Utilities;
Copy code Button_Submit_Click, Button_Cancel_Click, CloseForm below Page_Load method
using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.Utilities;
namespace MSTechSharing_TaskFormASPX.Layouts.MSTechSharing_TaskFormASPX
{
public partial class TargetList_AddNew : WebPartPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button_Submit_Click(object sender, EventArgs e)
{
SPList spList = SPContext.Current.List;
SPListItem spListItem = spList.Items.Add();
spListItem["Title"] = txtDescription.Text + "";
spListItem["Description"] = txtDescription.Text + "";
spListItem.Update();
spList.Update();
CloseForm();
}
protected void Button_Cancel_Click(object sender, EventArgs e)
{
CloseForm();
}
private void CloseForm()
{
if ((SPContext.Current != null) && SPContext.Current.IsPopUI)
{
this.Context.Response.Write("<script type='text/javascript'>window.frameElement.commitPopup();</script>");
this.Context.Response.Flush();
this.Context.Response.End();
}
else
{
string str = this.Page.Request.QueryString["Source"];
if ((str != null) && (str.Length > 0))
{
SPUtility.Redirect(string.Empty, SPRedirectFlags.UseSource, this.Context);
}
}
}
}
}
Cut TargetList_AddNew.aspx into Form Module
You see the path auto insert to file Element.xml of Form module
Deploy Project create new Item content type as follows
Result as follows:
CREATE NEW CONTENT TYPE FOR LIST TASK
Right click to project | Add new item | Content type | MSTechSharing_TaskFormASPX_ContentTypeTask
Choose Task Content Type
You see default number string of content type Task is 0x010800 you must change to 0x01080100
After change number then delete Inherits= “True” properties (image 30)
After number string was changed and Inherits= “True” properties was deleted, result as follows
Below close tag </FieldRefs> insert code to know path of Form Display and Edit of Task form
CREATE NEW CUSTOM ASPX FORM (APPLICATION PAGE) FOR LIST TASK
Right click to project | New Item | Application Page | Name is CustomFormTaskList.aspx
Change DynamicMasterPageFile to MasterPageFile by delete Dynamic character
Copy code into PlaceHolderMain
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<!--Insert code to here-->
<table style="width: 500px;" class="lcttable">
<tr>
<td>
Description
</td>
<td>
<%=Description%>
</td>
</tr>
<tr>
<td>
</td>
<td>
<asp:Button ID="Button_Ok" runat="server" Text="OK" Width="100px" OnClick="Button_Ok_Click" />
<asp:Button ID="Button_Cancel" runat="server" Text="Cancel" Width="100px" OnClick="Button_Cancel_Click" />
</td>
</tr>
</table>
<!--End Insert code to here-->
</asp:Content>
Copy Custom Form Task List to PlaceHolderAdditionalPageHead, PlaceHolderPageTitle, PlaceHolderPageTitleInTitleArea
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CustomFormTaskList.aspx.cs"
Inherits="MSTechSharing_TaskFormASPX.Layouts.MSTechSharing_TaskFormASPX.CustomFormTaskList"
MasterPageFile="~masterurl/default.master" %>
<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
Custom Form Task List
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<!--Insert code to here-->
<table style="width: 500px;" class="lcttable">
<tr>
<td>
Description
</td>
<td>
<%=Description%>
</td>
</tr>
<tr>
<td>
</td>
<td>
<asp:Button ID="Button_Ok" runat="server" Text="OK" Width="100px" OnClick="Button_Ok_Click" />
<asp:Button ID="Button_Cancel" runat="server" Text="Cancel" Width="100px" OnClick="Button_Cancel_Click" />
</td>
</tr>
</table>
<!--End Insert code to here-->
</asp:Content>
<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
Custom Form Task List
</asp:Content>
<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
Custom Form Task List
</asp:Content>
Using and change class inherit from LayoutsPageBase -> WebPartPage
Copy code as follows
using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebPartPages;
namespace MSTechSharing_TaskFormASPX.Layouts.MSTechSharing_TaskFormASPX
{
public partial class CustomFormTaskList : WebPartPage
{
public string Description;
protected void Page_Load(object sender, EventArgs e)
{
try
{
SPListItem spListItem = SPContext.Current.ListItem;
string urlLink = spListItem["WorkflowLink"].ToString().Split(',')[0];
int idItem = Convert.ToInt32(urlLink.Split('=')[1]);
SPSite ObjSite;
SPWeb ObjWeb;
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (ObjSite = new SPSite(SPContext.Current.Site.ID))
{
using (ObjWeb = ObjSite.RootWeb)
{
SPList objList = ObjWeb.GetListFromUrl(urlLink);
SPListItem target = objList.GetItemById(idItem);
Description = target["Description"] + "";
string action = Page.Request.QueryString["action"] + "";
if (action == "display")
{
Button_Cancel.Visible = false;
Button_Ok.Visible = false;
}
}
}
});
}
catch
{
// Nothing
}
}
protected void Button_Ok_Click(object sender, EventArgs e)
{
try
{
SPListItem spListItem = SPContext.Current.ListItem;
if (spListItem.ParentList.ContentTypes[SPBuiltInContentTypeId.SummaryTask] != null)
{
spListItem.ParentList.ContentTypes.Delete(SPBuiltInContentTypeId.SummaryTask);
}
if (spListItem.ParentList.ContentTypes[SPBuiltInContentTypeId.Task] != null)
{
spListItem.ParentList.ContentTypes.Delete(SPBuiltInContentTypeId.Task);
}
spListItem["PercentComplete"] = 1F;
spListItem.Update();
CloseForm();
}
catch
{
// Nothing
}
}
protected void Button_Cancel_Click(object sender, EventArgs e)
{
SPListItem spListItem = SPContext.Current.ListItem;
spListItem["PercentComplete"] = 0;
spListItem.Update();
CloseForm();
}
private void CloseForm()
{
if ((SPContext.Current != null) && SPContext.Current.IsPopUI)
{
this.Context.Response.Write("<script type='text/javascript'>window.frameElement.commitPopup();</script>");
this.Context.Response.Flush();
this.Context.Response.End();
}
else
{
string str = this.Page.Request.QueryString["Source"];
if ((str != null) && (str.Length > 0))
{
SPUtility.Redirect(string.Empty, SPRedirectFlags.UseSource, this.Context);
}
}
}
}
}
Cut CustomFormTaskList.aspx from Layouts Folder to Form module
CREATE NEW BASIC WORKFLOW
Right to Project | Add New Item | Sequential Workflow | Name is MSTechSharing_TaskFormASPX_Workflow
Choose List Workflow (image 40)
Uncheck as below image
Design workflow as follow
Configurate properties for createTaskWithContentType1 (reference how to create workflow sequential at here part How to create workflow approval)
Configure properties for onTaskChanged1
Configure properties for logToHistoryListActivity1
Double click to createTaskWithContentType1
Paste code to createTaskWithContentType1_MethodInvoking (note: ID content type of list task is same)
private void createTaskWithContentType1_MethodInvoking(object sender, EventArgs e)
{
createTaskWithContentType1_TaskId1 = Guid.NewGuid();
createTaskWithContentType1_ContentTypeId1 = "0x0108010059177a2760644cd3b054dd3f929e0380";
createTaskWithContentType1_TaskProperties1.AssignedTo = "win-67038mbkel7\\administrator";
createTaskWithContentType1_TaskProperties1.Title = "Custom From ASPX Task List ";
}
Double click to onTaskChanged1
paste code to onTaskChanged1_Invoked
private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
{
onTaskChanged1_AfterProperties1.PercentComplete = 1F;
}
//All Code
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WorkflowActions;
namespace BasicWFASPXTaskForm.BasicWFASPXTaskForm_Workflow
{
public sealed partial class BasicWFASPXTaskForm_Workflow : SequentialWorkflowActivity
{
public BasicWFASPXTaskForm_Workflow()
{
InitializeComponent();
}
public Guid workflowId = default(System.Guid);
public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
public Guid createTaskWithContentType1_TaskId1 = default(System.Guid);
public SPWorkflowTaskProperties createTaskWithContentType1_TaskProperties1 = newMicrosoft.SharePoint.Workflow.SPWorkflowTaskProperties();
public String createTaskWithContentType1_ContentTypeId1 = default(System.String);
public SPWorkflowTaskProperties onTaskChanged1_AfterProperties1 = newMicrosoft.SharePoint.Workflow.SPWorkflowTaskProperties();
public SPWorkflowTaskProperties onTaskChanged1_BeforeProperties1 = newMicrosoft.SharePoint.Workflow.SPWorkflowTaskProperties();
private void createTaskWithContentType1_MethodInvoking(object sender, EventArgs e)
{
createTaskWithContentType1_TaskId1 = Guid.NewGuid();
createTaskWithContentType1_ContentTypeId1 = "0x01080100349325c1e86c4e8c992a9a1c041fbcd1";
createTaskWithContentType1_TaskProperties1.AssignedTo = "win-67038mbkel7\\administrator";
createTaskWithContentType1_TaskProperties1.Title = "Custom ASPX From Task List";
}
private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
{
onTaskChanged1_AfterProperties1.PercentComplete = 1F;
}
}
}
//////////////////////////////////// ***End All Code ***////////////////////////////////////
Open file Element.xml of Workflow and change as follow (image 50)
CREATE NEW EVENT RECEIVER TO CALL WORKFLOW RUN WHEN ADD CONTENT TYPE ITEM
delete Feature2 when workflow was created (no require)
Open Feature1 change scope from web to site
Move feature workflow to right
Right click to Feature1 | Add Event Receiver
Using : using Microsoft.SharePoint.Workflow; and declare 3 variable
private string _workflowName = "MSTechSharing_TaskFormASPX - MSTechSharing_TaskFormASPX_Workflow";
private string _contentTypeName = "MSTechSharing_TaskFormASPX - MSTechSharing_TaskFormASPX_ContentTypeTargetList";
private string nameWorkflowOnContentType = "Wf CustomASPXTaskForm";
////////////////////////////////////// *** All code *** //////////////////////////////////////
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Workflow;
namespace MSTechSharing_TaskFormASPX.Features.Feature1
{
/// <summary>
/// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
/// </summary>
/// <remarks>
/// The GUID attached to this class may be used during packaging and should not be modified.
/// </remarks>
[Guid("c52f6eae-fc7e-47a5-89e1-3b2b0fa32c2b")]
public class Feature1EventReceiver : SPFeatureReceiver
{
private string _workflowName = "MSTechSharing_TaskFormASPX - MSTechSharing_TaskFormASPX_Workflow";
private string _contentTypeName = "MSTechSharing_TaskFormASPX - MSTechSharing_TaskFormASPX_ContentTypeTargetList";
private string nameWorkflowOnContentType = "Wf CustomASPXTaskForm";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using (SPSite site = ((SPSite)properties.Feature.Parent))
{
using (SPWeb web = site.OpenWeb())
{
SPContentType theCt = web.ContentTypes[_contentTypeName];
SPWorkflowTemplate theWf = null;
foreach (SPWorkflowTemplate tpl in web.WorkflowTemplates)
{
if (tpl.Name == _workflowName)
{
theWf = tpl;
}
}
SPWorkflowAssociation wfAssociation = theCt.WorkflowAssociations.GetAssociationByName(nameWorkflowOnContentType, web.Locale);
if (wfAssociation != null)
{
theCt.WorkflowAssociations.Remove(wfAssociation);
}
theCt.UpdateWorkflowAssociationsOnChildren(true, true, true, false);
// Name of workflow on ContentType that is associated to definition workflow
wfAssociation = SPWorkflowAssociation.CreateWebContentTypeAssociation(theWf, nameWorkflowOnContentType,"Task MSTechSharing_TaskFormASPX", "History MSTechSharing_TaskFormASPX");
wfAssociation.AutoStartCreate = true;
wfAssociation.AutoStartChange = true;
if (theCt.WorkflowAssociations.GetAssociationByName(wfAssociation.Name, web.Locale) == null)
{
theCt.WorkflowAssociations.Add(wfAssociation);
}
else
{
theCt.WorkflowAssociations.Update(wfAssociation);
}
theCt.UpdateWorkflowAssociationsOnChildren(true, true, true, false);
}
}
}
// Uncomment the method below to handle the event raised before a feature is deactivated.
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
using (SPSite site = ((SPSite)properties.Feature.Parent))
{
using (SPWeb web = site.OpenWeb())
{
SPContentType theCt = web.ContentTypes[_contentTypeName];
SPWorkflowAssociation wfAssociation = theCt.WorkflowAssociations.GetAssociationByName(_workflowName, web.Locale);
if (wfAssociation != null)
{
theCt.WorkflowAssociations.Remove(wfAssociation);
}
theCt.UpdateWorkflowAssociationsOnChildren(true, true, true, false);
}
}
}
// Uncomment the method below to handle the event raised after a feature has been installed.
//public override void FeatureInstalled(SPFeatureReceiverProperties properties)
//{
//}
// Uncomment the method below to handle the event raised before a feature is uninstalled.
//public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
//{
//}
// Uncomment the method below to handle the event raised when a feature is upgrading.
//public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
//{
//}
}
}
////////////////////////////////////// *** End All code *** //////////////////////////////////////
Deploy project, you see list definition was created as follows
Create new item
Workflow run automatically
Edit Item
Appear ASPX form in list Task
After approve (OK) status of workflow is completed
Note:
Error can not Add solution => change name of content type
Error can not Actived solution => change Name WF, Name content type in event receiver same with in xml file of workflow and content type target list
Error failing in started => insert ContentType;# to <AssociationCategories>ContentType;#List</AssociationCategories>
Error can not display Form ASPX=> delete List contain that Form then deploy
REF:
Subscribe to:
Posts (Atom)




























































