Wednesday, December 22, 2010

Create Batch File to Start or End Window Services

www.tech-recipes.com

The important commands are the following:
NET START – starts the service
NET STOP – ends the service

For example:

NET STOP "Error Reporting Service"

Output: The Error Reporting Service service was stopped successfully.

Knowing the commands, one can now easily create batch files called something like beforegame.bat and aftergame.bat.

Before.bat would contain all the NET STOP commands to end the nonessential services.
After.bat would be exactly the same except all the NET STOP commands would be replaced with NET START commands to restart all the common services.

A sample of the before.bat file might look something like this:

NET STOP "Error Reporting Service"
NET STOP "FTP Publishing Service"
SET STOP "IIS Admin"
NET STOP "Messenger"


Likewise, the after.bat file might look something like this:

NET START "Error Reporting Service"
NET START "FTP Publishing Service"
SET START "IIS Admin"
NET START "Messenger"

STOP SERVICES and FOR LOOPS in Batch files

www.tech-recipes.com


The key is to use delimaters...well, sorta. You want to trick the FOR loop into looking for delimiters.
~~ SERVICES.TXT ~~
; be sure to surround your values by QUOTES (")
"Apache Tomcat 4.1.31"
"Apache Tomcat 5.0.27"
"MySQL41"
; and with the EOL switch, lines beginning in ";" are ignored

~~ START.EM.UP.BAT ~~
FOR /F "eol=; tokens=1,2,3,4,5,6,7* delims= " %%a IN (SERVICES.TXT) DO NET STOP %%a %%b %%c %%d %%e %%f %%g

also notice a few things
    1. no quotes around filename
    2. the "%%x" variables have two % symbols (this is because i'm running inside of a BAT already.
    3. there are just as many "tokens" as there are "%%x" variables
    4. there is only a space after the delims= declaration

lastly, the resulting output:NET STOP "Apache Tomcat 4.1.31"
NET STOP "Apache Tomcat 5.0.27"
NET STOP "MySQL41"

Thursday, September 16, 2010

Display Maximo System info in IE title bar

in the Installserver.cmd file edit the following

Use the JVM parameter -Dmxe.name= to name each server, where
is the name that you use to identify the server.

set CMDLINE="%JAVA_VM% %MEM_ARGS% %JAVA_OPTIONS% -classpath \"%CLASSPATH%\" -Dmxe.name=UI2MAN1-372 -Dweblogic.Name=%SERVER_NAME% -Dweblogic.management.username=%WLS_USER% -Dweblogic.management.server=\"%ADMIN_URL%\" -Dweblogic.ProductionModeEnabled=%PRODUCTION_MODE% -Djava.security.policy=\"%WL_HOME%\server\lib\weblogic.policy\" -Dcom.sun.xml.namespace.QName,useCompatibleSerialVersionUID=1.0 -DJMSQSEQCONSUMER.SEQQOUT1=1 weblogic.Server"

REF:http://www-01.ibm.com/support/docview.wss?uid=swg21366402&aid=4

Thursday, September 2, 2010

Delete all hyperlinks on a sheet in Excel

REF: http://www.techonthenet.com/excel/macros/delete_hl.php

Question: I've had a hyperlink problem in my Excel files for ages: false hyperlinks had crept in (even in empty cells) and were multiplying regularly whenever I inserted new lines. How can I delete all hyperlinks in a sheet at once and not have to delete them cell by cell?

Answer: You will need to create a macro to delete the hyperlink addresses in your Excel sheet.

Open your Excel spreadsheet that you wish to remove the hyperlinks from. Press -F11 to go to the Visual Basic editor. Create a new module. You can do this by selecting Module under the Insert menu.

Paste the following code into your new module:

Sub RemoveHyperlinks()

'Remove all hyperlinks from the active sheet
ActiveSheet.Hyperlinks.Delete

End Sub

Close the Visual Basic editor window by selecting "Close and Return to Microsoft Excel" under the File menu.

Now, go to the sheet that contains the hyperlinks that you wish to delete.

Under the Tools menu, select Macro > Macros. Highlight the macro called "RemoveHyperlinks" and click on the Run button

Friday, August 20, 2010

Start or stop Windows service from command line

REF: http://www.windows-commandline.com/2010/08/start-stop-service-command-line.html

We normally use Services.msc to start or stop or disable or enable any service. We can do the same from command line also using net and sc utilities. Below are commands for controlling the operation of a service.

To stop a service from command prompt:

net stop servicename

To start a service from command prompt:

net start servicename

To disable a service from command prompt:

sc config servicename start= disabled

To reenable a service from command prompt:

sc config servicename start= demand

To make a service automatic from command prompt:

sc config servicename start= auto


Note: Space is mandatory after '=' in the above sc commands

Add user to group from command line

We can add users to a group from command line too. We can use net localgroup command for this.

For example to add user John to administrators group we can run the below command.

net localgroup administrators John /add


REF:http://www.windows-commandline.com

Wednesday, July 14, 2010

Accessing SharePoint List Data as XML

REF: http://vspug.com/dwise/2008/01/10/accessing-sharepoint-list-data-as-xml


The other day, I found myself in need of a way to access SharePoint list data as XML but the only method available to me was a simple http GET. This is not too bad, but what can I get from SharePoint via GET? RSS is too limited and scraping the page is too painful and error-prone to even contemplate.

It turns out that there is an option available in 2007 that was carried forward from SharePoint 2003 / FrontPage days: owssvr.dll. But this isn't some forgotten FrontPage artifact, it is still a central part of SharePoint. In fact, if you pull up a list view and then view the source looking for owssvr.dll, you will see that this is the mechanism behind both the Export to Spreadsheet and Open with Access options on the list Actions menu.

How It Works
Simply put together a URL like this:

http://MyServer/[site]/_vti_bin/owssvr.dll?Cmd=Display&List={listGuid}&XMLDATA=TRUE

This will only return the fields that are defined on the default view of the list. If you need specific fields then you need to create a view with those fields and pass the View ID as well, like this:

http://…/owssvr.dll?Cmd=Display&List={listGuid}&view={viewGuid}&XMLDATA=TRUE

Specifying Fields to be Returned
There is also a Query parameter that lets you specify which fields are to be included in the resulting XML, regardless of how the view is defined. For example, if you wanted just to bring back the Title and Status Fields, you would add the field names separated by spaces (URL Encoded, of course) like "&Query=Title%20Status". If you want to return all fields, use an asterisk (*) instead of field names.

http://…/owssvr.dll?Cmd=Display&List={listGuid}&query=Title%20Status&XMLDATA=TRUE

Filtering Data
Regardless of whether you pass a view or use the default it will still use the filter defined by that view. Not bad, but you can trim this data even more by including a filter of your own using the FilterFieldn and FilterValuen arguments in the querystring. These are the same values that are passed when you use the filter options in the column headers of a view which makes it pretty easy to track down exactly what needs to be passed. Simply pull up the view that is your starting point and use the column filters to create your desired filter. Once you have it, grab all of the FilterField and FilterValue items from the querystring and add them on to yours.

http://…/owssvr.dll?Cmd=Display&List={listGuid}&query=Title%20Status&XMLDATA=TRUE&FilterField1=Status&FilterValue1=In%20Progress

For a full list of what can be done with this technique, check out the URL Protocol or the older Using the URL Protocol on MSDN.

Tuesday, July 13, 2010

Importing/Exporting SharePoint Document Libraries to/from the File System

REF: SPIEFolder
REF: http://blog.krichie.com/

SPIEFolder - Allows you to either Import a file system folder (And all files and subfolders) into a SharePoint Document Library, and also export a SharePoint Document Library to the file system for
WSS 2.0/SPS2003 or WSS 3.0/MOSS 2007. This tool completely replicates the document libraries folder hierarchy to the file system when exporting, and replicates the folder hierarchy from the file system to the document library when importing.

Friday, July 9, 2010

Node Manager SSL comunication

REF: Thread: Problem whit Node Manager SSL comunication

Also if you dont want your NodeManager to listen over SSL, you can set

SecureListener=false

And also under machines, change the Listen Type to Plain.

Then the communication between Admin Server and NodeManger will not be over SSL.

Tuesday, July 6, 2010

PSEXEC - Remote control another server with your admin account

psexec \\computer -u domain\admin -p mypass -e cmd.exe

Managing Terminal Services Sessions Remotely

REF: http://weblogs.asp.net/owscott/archive/2003/12/30/Managing-Terminal-Services-Sessions-Remotely.aspx

Look:
qwinsta /server:12.12.12.12

Remove:
rwinsta/server:12.12.12.12 3

For example, let's say that I can't gain access to a server using Terminal Services because both sessions are used up. I can use another server to check the status of the first one. As long as the logged in user has administrative rights on the non-accessible machine I would run this:

qwinsta /server:12.12.12.12

Where 12.12.12.12 is the IP address or name of the non-accessible machine.

This will display something like this:

> qwinsta /server:12.12.12.12
SESSIONNAME USERNAME ID STATE TYPE DEVICE
console 0 Conn wdcon
rdp-tcp 65536 Listen rdpwd
rdp-tcp#470 Bob 1 Active rdpwd
rdp-tcp#471 Jane 3 Active rdpwd

Now I know that Bob and Jane are the two that are logged in. Since Jane left the office 20 minutes ago I know that she forgot to log off. I don't know where Bob is but I only need one session so I'll ignore him for now.

To disconnect Jane's session I would type this:

rwinsta /server:12.12.12.12 3

Notice the 3 which is the session ID I found from using qwinsta above.

Yet another option with W2K3 is a new feature that lets you connect to the desktop directly and gain a 3rd session.

If you're like me, you probably noticed that rwinsta and qwinsta seems like strange names. This came from the Citrix Metaframe days which Terminal Services has descended from. It stands for:

qwinsta = Query WINdows STAtion
rwinsta = Reset WINdows STAtion

One final comment. Microsoft has replaced these two tools with Query but since qwinsta and rwinsta is fully compatible with W2K WinXP and W2K3 I choose to use it instead.

Friday, May 14, 2010

Filtering a List by Workflow Status Column

REF: http://mossipqueen.wordpress.com/2010/01/25/filtering-a-list-by-spd-workflow-status/

I can’t believe I hadn’t attempted to do this earlier but last week I was setting up a sort of dashboard page for a SharePoint audit site and I found I wanted to display a list of the site’s In Progress workflows. I had set up a simple SPD workflow on a list, which acted as the source and storage for the workflow forms, so consequently it had the Workflow Name column to display the status. When I created an “In Progress” view on the list web part, I got a strange Render Error. It became clear that I could not filter the list where the Workflow Name column value = In Progress. So after some digging around I discovered that the SPD workflow statuses are actually represented by numerical values not text, so here are the mappings:

2: In Progress

5: Complete

15: Cancelled

Create a minimal master page

REF: http://msdn.microsoft.com/en-us/library/aa660698.aspx

How to: Create a Minimal Master Page

Edit Html to view code or follow the link above

<%-- Identifies this page as a .master page written in Microsoft Visual C# and registers tag prefixes, namespaces, assemblies, and controls. --%>
<%@ Master language="C#" %>

<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingNavigation" Namespace="Microsoft.SharePoint.Publishing.Navigation" Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="wssuc" TagName="Welcome" src="~/_controltemplates/Welcome.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="DesignModeConsole" src="~/_controltemplates/DesignModeConsole.ascx" %>
<%@ Register TagPrefix="PublishingVariations" TagName="VariationsLabelMenu" src="~/_controltemplates/VariationsLabelMenu.ascx" %>
<%@ Register Tagprefix="PublishingConsole" TagName="Console" src="~/_controltemplates/PublishingConsole.ascx" %>
<%@ Register TagPrefix="PublishingSiteAction" TagName="SiteActionMenu" src="~/_controltemplates/PublishingActionMenu.ascx" %>
<%-- Uses the Microsoft Office namespace and schema. --%>




<%-- The head section includes a content placeholder for the page title and links to CSS and ECMAScript (JScript, JavaScript) files that run on the server. --%>








<%-- When loading the body of the .master page, SharePoint Server 2007 also loads the SpBodyOnLoadWrapper class. This class handles .js calls for the master page. --%>

<%-- The SPWebPartManager manages all of the Web part controls, functionality, and events that occur on a Web page. --%>






<%-- The PlaceHolderMain content placeholder defines where to place the page content for all the content from the page layout. The page layout can overwrite any content placeholder from the master page. Example: The PlaceHolderLeftNavBar can overwrite the left navigation bar. --%>


<%-- These ContentPlaceHolders ensure all default SharePoint Server pages render with this master page. If the system master page is set to any default master page, the only content placeholders required are those that are overridden by your page layouts. --%>





















http://sharepointmagazine.net/technical/development/deploying-the-master-page

Friday, May 7, 2010

Create a Link to Launch New Form or Item

Use this temp to create the link

http://ServerLocation/_layouts/FormServer.aspx?XsnLocation=http://ServerLocation/Forms/template.xsn&DefaultItemOpen=1


http://ServerLocation
/_layouts/FormServer.aspx?XsnLocation=
http://ServerLocation/Forms/template.xsn
&DefaultItemOpen=1

On wss2:
http://ServerLocation/NewForm.aspx?&DefaultItemOpen=1


Related: http://www.cleverworkarounds.com/2008/02/06/form-services-and-spd-workflows

Friday, April 9, 2010

How to "Unlock" a data source schema (.xsd)

REF: http://www.infopathdev.com/blogs/hilary/archive/2009/03/13/locked-schema-got-you-down.aspx

Locked Schema Got You Down?
Sometimes we want to create a new template off an existing schema. Microsoft has a great article Here , but for those of you who have already created a form off an existing schema, and just want to know how to unlock it, it can be a bit much to dredge through (also, they don't even mention the little .xsf hack I'm going to show you....). Fortunately, you have me, and I feel your pain.

The Problem

You saved a beloved form as source files, because its schema was perfect, and you want to base another form off of it. You create a new form template, chosing XML or Schema for the source

and you happily design away... until you want to add a field. Or change the name of an existing field. That's when you realize.... you're stuck. See those little locks on the data fields? And at the bottom of the Data Source Task Pane, Add a Field or Group is grayed out....

The Reason

If you read the article I've linked in the first paragraph, it says:

When you design a form that is based on an external schema, Microsoft Office InfoPath 2007, or Microsoft Office InfoPath 2003 assumes that the schema is finalized and therefore prevents any modification of the schema in the Data Source task pane.

So there you have it. InfoPath figured you were perfectly happy with the schema when you built the form off it.

One Solution

You can manually add elements to your schema. Save your form as source files and open myschema.xsd in a text editor.
Another Solution

But what if you just want it unlocked, so you can add fields like a normal old data source? For that, again, we need to save as source files. Open manifest.xsf with a text editor. Look for your schema file in the files element. You'll see a property named editability which has helpfully been set to 'none':

Set this property to 'full':


Save your changes, and open your template in design mode again:

All your fields will be fully editable.

The Usual Warnings Apply

Save a copy of your form someplace safe before manipulating form files. This is by no means a full discussion of potential pitfalls that can be encountered -- more information on xsf structure is available here. Happy unlocking!


Published Mar 13 2009, 05:32 PM by Hilary Stoupa

More:
REF: http://www.infopathdev.com/forums/p/9499/33583.aspx

Tuesday, March 23, 2010

InfoPath 2007 - Conditional SUM

REF: http://blogit.create.pt/blogs/miguelisidoro/archive/2008/08/02/InfoPath-2007-_2D00_-Conditional-SUM.aspx


This blog post will show you how to create an expression box in an InfoPath 2007 form whose value is based on the result of an conditional sum. Consider the following InfoPath form template:



The previous image shows a simple expense report. To support the introduction of the expense information, a Repeating Table control is used with three columns:

Expense - Expense Description. A simple Text Box control;
Value - Expense value. A simple Text Box control;
Expense Type - Drop-down List Box control that allows 4 expense types: Food, Land Travel, Air Travel and Parking.
Below the repeating table there are 5 expression boxes that show the total amount of the expense report and the total amount for each expense type. The total amount expression box is based on a simple sum expression and each of the expense type expression boxes are based on conditional sums filtered by the value of the expense type Drop-down List Box control. The expressions used for each expense type are the following:

Expression Box Expression XPath Expression
Expense Total sum(expensevalue) sum(my:accounting/my:expensevalue)
Food Expense Total sum(accounting[expensetype = "Food"]/expensevalue) sum(my:accounting[my:expensetype = "Food"]/my:expensevalue)
Land Travel Expense Total sum(accounting[expensetype = "Land Travel"]/expensevalue) sum(my:accounting[my:expensetype = "Land Travel"]/my:expensevalue)
Air Travel Expense Total sum(accounting[expensetype = "Air Travel"]/expensevalue) sum(my:accounting[my:expensetype = "Air Travel"]/my:expensevalue)
Parking Expense Total sum(accounting[expensetype = "Parking"]/expensevalue) sum(my:accounting[my:expensetype = "Parking"]/my:expensevalue)

As the previous table shows, the conditional sum expressions for each expense type are relatively simple and pretty straightforward for those who are familiarized with XPath, since XPath syntax is used for each expression. This comes as no surprise since the underlying data of the InfoPath form is stored in XML. The following image shows an expense report example filled with some sample values:



Posted: Saturday, August 02, 2008 3:52 PM by misidoro

Monday, March 22, 2010

SPD Workflows - Out of the Box

REF: http://www.mannsoftware.com/workflow/Wiki%20Pages/Out%20of%20the%20Box%20Actions%20and%20Conditions.aspx

SPD Workflows all come down to three things:

1. Steps

2. Conditions

3. Actions

That’s it. Master those three things and you’re golden.

Like anything else, the devil’s in the details, so here’s some links to existing information to help you build workflows in SPD:

Office Designer 2007 Overview from MSDN

Ted Pattison Screencast on Channel 9

Create a Workflow from Office Online

Those are all fairly basic, but a good start nonetheless. Here is some additional information:

Steps: A Step in an SPD workflow is a logical grouping of Actions and Conditions. They are used to provide structure

Conditions: Conditions are the circumstances that signal that a given Step in a workflow should execute. The default Conditions available in SPD are:

Condition
Description

Compare
FieldAllows you to specify a value for a column in the list this workflow is attached to. If the payload item has that value in the specified column, then this step will process.

Compare Any Data Source
Allows you to specify a set of values to be compared. Each value can contain either a hard-coded value or a lookup to another list on the site. See the section

Title Field Contains Keyword
Allows you to specify a value to look for in the Title column. If the current list item has that value in the title, then this step will process.

Modified in a Specific Date Span
Allows you to specify begin and end dates for when the list item was modified. If the current list item was modified within this span, then this step will process.

Modified by a Specific Person
Allows you to specify the name of a person. If that person modified the list item, this step will execute.

Created in a Specific Date Span
Same as Modified in a Specific Date Span but works off the list item creation date.

Created by a Specific Person
Same as Modified by a Specific Person but works off the original list item creator, not the last modifier.

The File Type Is a Specific Type
Allows you to specify a certain type of file. If the file payload matches this file extension, the step will process

The File Size in a Specific Range
Allows you to specify a range of kilobytes. If the file of Kilobytes payload falls within this range, the step will process.





Actions: An Action is what happens in a workflow step – they are the tasks that will be completed by the workflow as part of that step. The default Actions available in SPD are:

Action
Description

Add Time to Date
Allows you to work with date values and store the result in a variable. You can add (or subtract, by indicating a negative value) time (minutes, hours, days, months, or years) to a specified date and store the result in either an existing variable or in a new variable created in this step.

Assign a Form to a Group
Launches a custom wizard that allows you to easily build a form to collect information from users. The wizard is similar to the Variables Editor discussed in a moment. You can indicate which users are assigned the survey as part of the configuration for this action.

Assign a To-do Item
Launches a dialog box that allows you to specify the parameters for creating a simple task for a specified user.

Build Dynamic String
Configure this step to create a string value and assign it to a variable. The string value can contain values retrieved from the current workflow instance by using lookups. We discuss lookups later in this chapter. The variable used to store the string value can be either preexisting or created as part of this action.

Check In Item
Checks in an item so other users can edit it. You can specify Current Item or provide a column name and value to identify which item to check in. Also allows you to specify a check-in comment, which can be either hard-coded or set via a workflow lookup.

Check Out Item
Checks out an item so other users cannot edit it. You can specify Current Item or provide a column name and value to identify which item to check out.

Collect Data from a User
Creates and assigns a task to the specified user. Tasks are used to collect specific information from the assigned user or to have the user complete a process. The ID of the task is stored in a variable so that the information from that task is available later in the workflow via a workflow lookup. Configuring this action will launch the custom task wizard, which is similar to the Variables Editor discussed in a moment. This action is similar to the Assign a To-Do Item action, but allows you to collect information for later use instead of just creating a task.

Copy List Item
Creates an exact duplicate of an existing list item in a different list on the current site. You specify both the source and destination lists. You can specify Current Item or provide a column name and value to identify which item to copy.

Create List Item
Creates a new list item in any list on the current site. You specify the list as well as values for all necessary columns. Values can either be hard-coded or based on a workflow lookup.

Delete Item
Deletes an item from a list on the current site. You can specify Current Item or provide a column name and value to identify which item to delete.

Discard Check Out Item
Pretty self-explanatory, but this allows you to undo the checkout of an item. All changes to that item will be lost.

Do Calculation
Performs a simple calculation (plus, minus, multiply, divide, modulo) with two values, which you can either specify or base on a workflow lookup. The results of the calculation are stored in a variable. Typically, this variable would be one created specifically for this workflow.

Log to History List
Allows you to write an entry to the designated history list for this workflow instance. You can use either fixed text or a workflow lookup value (but not both) as the text to be written.

Pause for Duration
Allows you to specify that the workflow should suspend processing for a time period you specify (in days, hours, and minutes) when you configure this action.

Pause Until Date
Similar to the previous action, except that you configure a specific date on which to continue processing the workflow.

Send an Email
Sends an email when it is executed. The action can be customized to specify the recipient, CC, subject, and body of the message. Each of these fields can be either hard-coded or based on formulas, lookups, or workflow variables.

Set Content Approval Status
Allows you to specify the current status of the payload item. You can also specify comments, but keep in mind that those comments will be the same for every instance of this workflow unless you use lookups.

Set Field in Current Item
Allows you to set the value of a specific column in the payload item to a specified value. You can specify this value with either fixed text or a workflow lookup value (but not both).

Set Time Portion of Date/Time Field
Similar to the Add Time to Date action, except that you specify a specific value for hours and minutes (i.e., not a relative time—plus 5 minutes from when the action executes) and store the results in a variable.

Set Workflow Variable
Sets a variable for this workflow to a specified value. The value can be either hard-coded or set via a workflow lookup. You can reference a previously created variable or create a new one.

Stop Workflow
Causes the workflow to stop processing. You can specify text to be logged to the history list with either fixed text or a lookup.

Update List Item
Updates one or more existing columns in one or more lists. You can specify the list(s), the column(s), and the value(s). You can also specify Current Item to indicate the item that triggered the current workflow instance.

Wait for Field Change in Current Item
Pauses the workflow until the specified column for this item from the attached SharePoint list equals the value specified. The value can be hard-coded or based on a workflow lookup.





It is important to note that you can create custom Conditions and custom Actions and use them in your SPD workflow. We’ll cover that in a later posting.

There are a few things that you need to understand about a workflow developed with SPD:

1. They operate on a single List. When you start building the workflow, you pick the list to attach it to. Once that is set, there’s no changing it. You can’t take the workflow and attach it to another list or the same list type on another site

2. You can’t deploy SPD-developed workflows from one environment to another – or rather, you can’t deploy without recreating the workflow on the new environment

3. You can’t debug SPD workflows

4. You must have the .Net Framework 3.0 on the machine where you are running SPD

Sunday, March 21, 2010

Calculate the difference between two date picker controls in InfoPath using rules and formulas - no code!

REF: http://www.bizsupportonline.net/infopath2007/calculate-date-difference-infopath-rules-formulas.htm


Use rules, conditions, and the number(), floor(), and substring() functions in formulas to calculate the difference between two date picker controls in InfoPath.

Problem
You have an InfoPath form template with two date picker controls and you would like to calculate the difference between the two date picker controls without writing code.

Solution
Use rules, conditions, and the number(), floor(), and substring() functions in formulas to calculate the difference between two date picker controls in InfoPath.

Discussion
You can accomplish this functionality as follows:

Design an InfoPath form template as shown in figure 1 with two Date Picker controls named startDate and endDate, and one Text Box control named difference.

Figure 1. InfoPath form template in Design mode.

The Main data source of the InfoPath form template should resemble the following figure:

Figure 2. The Main data source of the InfoPath form template.
Add the following Rule to the startDate field:
Action: Set a field's value
Field: difference
Value:

(number(substring(../my:endDate, 9, 2)) + floor((153 * (number(substring(../my:endDate, 6, 2)) + 12 * (floor((14 - number(substring(../my:endDate, 6, 2))) div 12)) - 3) + 2) div 5) + (number(substring(../my:endDate, 1, 4)) + 4800 - (floor((14 - number(substring(../my:endDate, 6, 2))) div 12))) * 365 + floor((number(substring(../my:endDate, 1, 4)) + 4800 - (floor((14 - number(substring(../my:endDate, 6, 2))) div 12))) div 4) - floor((number(substring(../my:endDate, 1, 4)) + 4800 - (floor((14 - number(substring(../my:endDate, 6, 2))) div 12))) div 100) + floor((number(substring(../my:endDate, 1, 4)) + 4800 - (floor((14 - number(substring(../my:endDate, 6, 2))) div 12))) div 400) - 32045) - (number(substring(., 9, 2)) + floor((153 * (number(substring(., 6, 2)) + 12 * (floor((14 - number(substring(., 6, 2))) div 12)) - 3) + 2) div 5) + (number(substring(., 1, 4)) + 4800 - (floor((14 - number(substring(., 6, 2))) div 12))) * 365 + floor((number(substring(., 1, 4)) + 4800 - (floor((14 - number(substring(., 6, 2))) div 12))) div 4) - floor((number(substring(., 1, 4)) + 4800 - (floor((14 - number(substring(., 6, 2))) div 12))) div 100) + floor((number(substring(., 1, 4)) + 4800 - (floor((14 - number(substring(., 6, 2))) div 12))) div 400) - 32045)

with the following Conditions on the Rule:
startDate is not blank and
endDate is not blank
Add a second Rule to the startDate field with the following settings:
Action: Set a field's value
Field: difference
Value: 0

with the following Conditions on the Rule:
startDate is blank or
endDate is blank

Add the following Rule to the endDate field:
Action: Set a field's value
Field: difference
Value:

(number(substring(., 9, 2)) + floor((153 * (number(substring(., 6, 2)) + 12 * (floor((14 - number(substring(., 6, 2))) div 12)) - 3) + 2) div 5) + (number(substring(., 1, 4)) + 4800 - (floor((14 - number(substring(., 6, 2))) div 12))) * 365 + floor((number(substring(., 1, 4)) + 4800 - (floor((14 - number(substring(., 6, 2))) div 12))) div 4) - floor((number(substring(., 1, 4)) + 4800 - (floor((14 - number(substring(., 6, 2))) div 12))) div 100) + floor((number(substring(., 1, 4)) + 4800 - (floor((14 - number(substring(., 6, 2))) div 12))) div 400) - 32045) - (number(substring(../my:startDate, 9, 2)) + floor((153 * (number(substring(../my:startDate, 6, 2)) + 12 * (floor((14 - number(substring(../my:startDate, 6, 2))) div 12)) - 3) + 2) div 5) + (number(substring(../my:startDate, 1, 4)) + 4800 - (floor((14 - number(substring(../my:startDate, 6, 2))) div 12))) * 365 + floor((number(substring(../my:startDate, 1, 4)) + 4800 - (floor((14 - number(substring(../my:startDate, 6, 2))) div 12))) div 4) - floor((number(substring(../my:startDate, 1, 4)) + 4800 - (floor((14 - number(substring(../my:startDate, 6, 2))) div 12))) div 100) + floor((number(substring(../my:startDate, 1, 4)) + 4800 - (floor((14 - number(substring(../my:startDate, 6, 2))) div 12))) div 400) - 32045)

with the following Conditions on the Rule:
startDate is not blank and
endDate is not blank
Add a second Rule to the endDate field with the following settings:
Action: Set a field's value
Field: difference
Value: 0

with the following Conditions on the Rule:
startDate is blank or
endDate is blank
Add the following Rule to the difference field:
Action: Set a field's value
Field: .
Value: 0

with the following Condition on the Rule:
difference does not match pattern Custom Pattern: -{0,1}\d+
You should now have a fully functional InfoPath form that will calculate the difference between the dates soon after you have entered valid dates. This solution also works for InfoPath 2003 form templates and InfoPath 2007 browser-enabled form templates.

Friday, March 12, 2010

Writing CAML Queries For Retrieving List Items from a SharePoint

http://sharepointmagazine.net/technical/development/writing-caml-queries-for-retrieving-list-items-from-a-sharepoint-list

Introduction
The Collaborative Application Markup Language (better known as CAML) is an XML-based query language that helps you querying, building and customizing Web sites based on Windows SharePoint Services. The XML elements define various aspects of a WSS site.

In this first series of articles I will explain in detail how to build and execute CAML queries to retrieve list items from a SharePoint list. List items can be retrieved in several different ways: using the SharePoint object model, using the SharePoint Lists web service or even by using Powershell. Use the SharePoint object model when your code runs on the server (like f.e. when you’re developing a web part or an application page). Use the SharePoint Web Services when your code doesn’t run on the server where SharePointis installed, for example when you develop office clients or windows applications. Powershell, at the other side, can be used by administrators when they quickly need to retrieve some information. In any way the CAML query is the same.

Building the CAML
CAML is an XML-based query language. Its root element is Query. Within the Query element two other elements are possible but not required: the OrderBy element and the Where element.

The OrderBy element is the simplest one. It is used to sort the returning list items. You have to specify the field(s) on which you want to sort the items and the sort direction. The syntax looks as follows:

The OrderBy clause is not required and you can specify one or more fields on which you want to sort. If you omit the Ascending attribute, your resulting rows will be sorted in ascending order. If you want to order in descending order you have to specify Ascending=’False’.

The Where clause is used to specify one or more filter criteria. This clause can be very simple but can end up being rather complex. In its most simple form you specify an operator, a field name for which you want to specify a criterion, and a value.

Janssens OperatorsYou have different operators:

Eq Equals

Neq Not equal

Gt Greater than

Geq Greater than or equal

Lt Lower than

Leq Lower than

IsNull Is null

BeginsWith Begins with

Contains Contains

FieldsThe FieldRef element can be any field of the list on which you want to execute the CAML query. If you use the Name attribute you need to specify the internal name of the field. But you can also use the IDattribute to specify the Guid of the field.

ValueThe Valueelement specifies the value part of the criterion. The attribute Typeis optional and specifies the data type of the field you want to specify the criterion for. If omitted the data type is considered as being Text. In all other cases you have to specify the Type attribute. DateTime fields are a special case and will be described in more detail later in this article.

If the field type is a Lookup you need to specify the text value.For example you have an Employees list and the Country field is a lookup field referring to the Countries list. In that case an employee living in Belgium will have f.e. following value: #15;Belgium. If you have to query for the employees living in Belgium you will have to write your query as follows:

Belgium You can find this not good coding practice because the name of the country can change in time. In that case you can also query on the id of the country specifying the LookupId attribute in the FieldRef element:

15 If you want to specify two filter criteria you also have to specify a join operator And or Or.

Janssens 21 If you want to specify more filter criteria you have to nest them in a very specific way:

Janssens 21 60 For each extra criterion you have to add an extra join operator at the outside of the query and add the criterion at the end:

Janssens 21 60 Belgium Retrieving List Items with CAML using the SharePoint Object Model
If you need to retrieve items from a list when developing web parts, application pages or custom field types you can best use the SPQueryobject from the SharePoint object model. This object is located in the Microsoft.SharePoint namespace of the Microsoft.SharePoint.dll located in the Global Assembly Cache.

Instantiate the object as follows:

SPQuery qry = new SPQuery();The most important property is the Query property, which needs to be set to your CAML query:

string camlquery = "" + "Smith" + ";qry.Query = camlquery;At this point you can execute the query on your list:

SPListItemCollection listItemsCollection = list.GetItems(qry);A small remark with the GetItems method of the SPList instance: this method returns a collection of type SPListItemCollection. It is possible that it is easier working with a DataTable. In that case you can execute the query as follows:

DataTable listItemsTable = list.GetItems(qry).GetDataTable();The query will not only return all list items that have their last name set to Smith, but also all columns of each list item. In cases you work with large lists it can be important to retrieve a subset of list items containing only the columns you need. In that case you will have to set the ViewFields property of the SPQuery object. You can do this by specifying all columns you want to see returned:

qry.ViewFields = "";This will return the first name and the last name of the retrieved employees, but also the system fields like the ID and the Created date.

The major disadvantage of the SPQuery object is that you can query only one list. If you want to query more than one list you will have to use the SPSiteDataQuery. More on this object in a later article because it earns special attention.

It is common knowledge by now but let me remind you that it’s always a good idea to use SPQuery to retrieve a subset of list items. You can loop through the list item collection to find the list items that match your needs but this will have a serious negative impact on the performance of your work.

Retrieving List Items with CAML using the SharePoint Web Services
If you are developing office clients or any other application that will not run on the server where SharePoint is installed you will need to use the SharePoint Web Services to retrieve (or update) information from SharePoint. If you want to query a list you will need to execute the GetListItems method from the Lists.asmxSharePoint web service.

Working with the SharePoint web services is different in Visual Studio 2005 then in Visual Studio 2008.

Retrieving List Items from the Lists.asmx using Visual Studio 2005First you have to reference the web service in your Visual Studio project. If you work with Visual Studio 2005 you have to add a Web Reference to theLists.asmx.

Then you have to instantiate the web service and pass the url of the SharePoint site, plus the location and name of the SharePoint web service. The SharePoint web services are all located in the ISAPI directory of the SharePoint 12 hive but are accessible from outside via the _vti_bin directory.

Initialize the Lists.asmx web service:

ListService listsWs = new ListService.Lists();listsWs.Url = siteUrl + @"/_vti_bin/lists.asmx";Then you have to set the credentials. In case you don’t need to specify a username or password you can proceed as follows:

listsWs.Credentials = System.Net.CredentialCache.DefaultCredentials;If you have to specify a user name and password:

listsWs.Credentials = new System.Net.NetworkCredential(userName, password);If you also have to specify a domain, use the other overload:

listsWs.Credentials = new System.Net.NetworkCredential(userName, password, domain);Then you are ready to call the GetListItems method, which requires the following syntax:

resultNode = _sharepointSite.ListsWSS.GetListItems(listName, viewName, queryNode, viewFieldsNode, rowLimit, queryOptionsNode, webID);Not all arguments are required. Arguments like view name, row limit and web ID are optional.

The query node argument will contain the CAML query as explained in previous sections but need to be enclosed within a and tag:

XmlDocument camlDocument = new XmlDocument();XmlNode queryNode = camlDocument.CreateElement("Query");queryNode.InnerXml = "" + "Smith" + ";The same applies to the ViewFields node:

XmlNode viewFieldsNode = camlDocument.CreateElement("ViewFields");viewFieldsNode.InnerXml = "" + "";As you will have noticed, you also need a QueryOptions node. This node will be explained later in this series. If you have no QueryOptions to specify you can pass in an empty node:

XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");Retrieving List Items from the Lists.asmx using Visual Studio 2008But in case you are working with Visual Studio 2008 you will have to add a Service Reference to theLists.asmxweb service. If you don’t want to work asynchronously you have to uncheck the Generate Asynchronous Operations option in the Advanced dialog. When closing the dialog box Visual Studio automatically adds an app.config or web.config file. Open this file and locate the security section. The following XML is generated automatically:

Replace it with the following:

Return to your code and instantiate the web service:

ListsWS.ListsSoapClient ws = new ListsWS.ListsSoapClient();You also have to set the necessary credentials. If you can work with the default credentials you can write the following:

ws.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials; ws.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;If necessary you can also pass user name, password and domain:

ws.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("Administrator", "secret", "U2UCOURSE"); ws.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;If necessary you can set the URL to the web service dynamically:

ws.Endpoint.Address = new System.ServiceModel.EndpointAddress( "http://wss.u2ucourse.com/_vti_bin/lists.asmx");Now you are ready to call the GetListItems method of the web service. There is no difference in calling this method from within Visual Studio 2005:

XmlDocument camlDocument = new XmlDocument(); XmlNode queryNode = camlDocument.CreateElement("Query");queryNode.InnerXml = "" + "Smith" + "; XmlNode viewFieldsNode = camlDocument.CreateElement("ViewFields");viewFieldsNode.InnerXml = "" + ""; XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions"); resultNode = _sharepointSite.ListsWSS.GetListItems(listName, viewName, queryNode, viewFieldsNode, rowLimit, queryOptionsNode, webID);The returned XML is rather complex and needs some special attention. I will come back on this in a later article.

Query Options
Executing a query is not only about CAML. When working with the SPQuery object you can set different properties to influence the returned list items. When working with the SharePoint web services, these options are translated into CAML and are part of the QueryOptions element.

RowLimitSetting this property limits the number of rows returned in the result set.

When working with the SPQuery object:

qry.RowLimit = 10;When working with the GetListItems method of the Lists.asmx web service:

XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");queryOptionsNode.InnerXml = "10";IncludeMandatoryColumnsWhen this Boolean property is set to True, the result set will not only return the columns as defined in the ViewFields property, but also the columns that you defined in the list as required.

When working with the SPQuery object:

qry.IncludeMandatoryColumns = true;When working with the GetListItems method of the Lists.asmx web service:

XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");queryOptionsNode.InnerXml = "True";DatesInUtcSetting this Boolean property specifies whether the query returns dates in Coordinated Universal Time (UTC) format. The syntax is similar to that of the previously described property.

ExpandUserFieldWhen you omit this property or set it to false, user fields will return the login name of the user.

Setting this Boolean property to true (or include it in the QueryOptions node), user fields are returned as follows:

Karine Bosch,#U2UCOURSE\karine,#karine@U2UCOURSE.COM,#,#Karine BoschThe returned value includes the login name, e-mail address, Session Initiation Protocol (SIP) address, and title, when present, which causes a user field to behave as a multilookup field. The syntax is similar to that of the previously described property.

There are some other query options to set but they will be explained in detail in the next section.

Special Types of Queries
Some special types of lists require more specialized CAML queries. In some cases it only affects the CAML but in other cases you have to set extra SPQuery properties. If you execute this query against the Lists web service it will affect another argument of the GetListItems method, i.e. the QueryOptions argument.

Building queries for working with FoldersA first variant I will explain is how you can work with folders and sub folders. A folder is a special list item on a list or document library. If you execute a standard CAML query you will end up with list items from the root folder.

If you want to query all folders and sub folders of a list or document library, you have to define extra query options. If you are working with the object model you have to set the ViewAttributes property of the SPQuery object as follows:

qry.ViewAttributes = "Scope='Recursive'";If you work with GetListItems method of the Lists.asmx SharePoint web service, you have to define an extra node with the QueryOptions element:

XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");queryOptionsNode.InnerXml = "";If you want to query a specific sub folder using the SPQuery object, you have to set the Folder property:

qry.Folder = list.ParentWeb.GetFolder("Folders DocLib/2008");When working with the web services you have to do the following:

XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");queryOptionsNode.InnerXml = "Folders DocLib/2008";Building Queries for working with DateTime ValuesFiltering on DateTime fields also requires some extra attention. First of all when querying for a specific date, you have to use the SharePoint datetime notation:

2008-08-10T10:00:00Z But in this case the date is hard coded and the time part will not be taken into account. This query will return all list items with a start date as of 10 August 2008, also those starting before 10 o’clock. If you want your query to take into account the time part, you have to use a special attribute IncludeTimeValue that you can set on the FieldRef element:

2008-08-10T10:00:00Z This query will return all list items with a start date as of 10 August 10 o’clock.

As already said, this way the date is hard coded. If you want your query a bit more dynamic, you can always use the element Today.

Today will not take a time part into account. Unfortunately a Now element doesn’t exist.

You can also add or subtract a number of days from today’s date. In that case you have to add the Offset attribute to the Today element. The Offset attribute accepts a positive value for adding days and a negative value for subtracting days.

As all this is pure CAML, the query is the same whether you work with the object model or the SharePoint web services.

Building Queries for Calendar ListsCalendar lists also require a little more attention. A calendar list is based on the Event content type. Normal events can be retrieved with the usual CAML queries. It’s only when you start working with recurring events (events that occur once a day or twice a week or month) that you run into problems.

The Event content type defines a field named fRecurrence, which is set to 1 when a recurring event is created.


Defining a recurring event

When the Calendar view is rendered a recurring event is split into a number of event instances, one for each recurrence.


Calendar view showing event instances for recurring event

The definition of the recurrence is XML stored in another field defined by the Event content type, i.e. RecurrenceData. An example of such a definition looks as follows:

su FALSE Fortunately you don’t have to parse the XML yourself to get the actual instances of the recurring event. You can use a combination of CAML syntax and query options to achieve this.

When working with the SPQuery object you need to set the ExpandRecurrences property to true. You also have to specify a date in the CalendarDate property. This date will be used to compare the recurring event instances.

Next you have to add a DateRangesOverlap element to the Where clause of the CAML query. This element is used in queries to compare the dates in a recurring event with the date specified in the CalendarDateproperty to see whether they overlap. The CAML looks as follows:

The element is used to specify that all occurrences within a month need to be returned. You can also specify Day, Week or Year.

In case you need to work with the GetListItems method of the Lists.asmx web service, you translate the query options into XML:

XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");queryOptionsNode.InnerXml = "TRUE" + "2008-08-12T10:00:00Z";Read more about Calendar lists here: http://blogs.msdn.com/sharepoint/archive/2007/05/14/understanding-the-sharepoint-calendar-and-how-to-export-it-to-ical-format.aspx

This is it about retrieving List Items using CAML. Don’t hesitate to post your comments and questions below.

Thursday, March 11, 2010

Syntax for directly calling the Web Service using HTTP GET

The syntax for directly calling the Web Service using HTTP GET is

http://server/webServiceName.asmx/functionName?parameter=parameterValue

Therefore, the call for our Web Service will be

http://localhost/work/aspx/SampleService.asmx/GetSecurityInfo?Code=IBM

Creating a .NET Web Service

REF: http://www.15seconds.com/Issue/010430.htm



Microsoft .NET marketing has created a huge hype about its Web Services. This is the first of two articles on Web Services. Here we will create a .NET Web Service using C#. We will look closely at the Discovery protocol, UDDI, and the future of the Web Services. In the next article, we will concentrate on consuming existing Web Services on multiple platforms (i.e., Web, WAP-enabled mobile phones, and windows applications).


Why do we need Web Services?


After buying something over the Internet, you may have wondered about the delivery status. Calling the delivery company consumes your time, and it's also not a value-added activity for the delivery company. To eliminate this scenario the delivery company needs to expose the delivery information without compromising its security. Enterprise security architecture can be very sophisticated. What if we can just use port 80 (the Web server port) and expose the information through the Web server? Still, we have to build a whole new Web application to extract data from the core business applications. This will cost the delivery company money. All the company wants is to expose the delivery status and concentrate on its core business. This is where Web Services come in.


What is a Web Service?


Web Services are a very general model for building applications and can be implemented for any operation system that supports communication over the Internet. Web Services use the best of component-based development and the Web. Component-base object models like Distributed Component Object Model (DCOM), Remote Method Invocation (RMI), and Internet Inter-Orb Protocol (IIOP) have been around for some time. Unfortunately all these models depend on an object-model-specific protocol. Web Services extend these models a bit further to communicate with the Simple Object Access Protocol (SOAP) and Extensible Markup Language (XML) to eradicate the object-model-specific protocol barrier (see Figure 1).

Web Services basically uses Hypertext Transfer Protocol (HTTP) and SOAP to make business data available on the Web. It exposes the business objects (COM objects, Java Beans, etc.) to SOAP calls over HTTP and executes remote function calls. The Web Service consumers are able to invoke method calls on remote objects by using SOAP and HTTP over the Web.


Figure 1. SOAP calls are remote function calls that invoke method executions on Web Service components at Location B. The output is rendered as XML and passed back to the user at Location A.

How is the user at Location A aware of the semantics of the Web Service at Location B? This question is answered by conforming to a common standard. Service Description Language (SDL), SOAP Contract Language (SCL) and Network Accessible Specification Language (NASSL) are some XML-like languages built for this purpose. However, IBM and Microsoft recently agreed on the Web Service Description Language (WSDL) as the Web Service standard.

The structure of the Web Service components is exposed using this Web Service Description Language. WSDL 1.1 is a XML document describing the attributes and interfaces of the Web Service. The new specification is available at msdn.microsoft.com/xml/general/wsdl.asp.


The task ahead


The best way to learn about Web Services is to create one. We all are familiar with stock quote services. The NASDAQ, Dow Jones, and Australian Stock Exchange are famous examples. All of them provide an interface to enter a company code and receive the latest stock price. We will try to replicate the same functionality.

The input parameters for our securities Web service will be a company code. The Web service will extract the price feed by executing middle-tier business logic functions. The business logic functions are kept to a bare minimum to concentrate on the Web service features.


Tools to create a Web Service


The core software component to implement this application will be MS .NET Framework SDK, which is currently in beta. You can download a version from Microsoft. I used Windows 2000 Advance Server on a Pentium III with 300 MB of RAM.

The preferred Integration Development Environment (IDE) to create Web Services is Visual Studio .NET. However, you can easily use any text editor (WordPad, Notepad, Visual Studio 6.0) to create a Web Service file.

I assume you are familiar with the following concepts:

Basic knowledge of .NET platform
Basic knowledge of C#
Basic knowledge of object-oriented concepts
Creating a Web Service


We are going to use C# to create a Web Service called "SecurityWebService." A Web Service file will have an .ASMX file extension. (as opposed to an .ASPX file extension of a ASP.NET file). The first line of the file will look like

<%@ WebService Language="C#" class="SecurityWebService" %>

This line will instruct the compiler to run on Web Service mode and the name of the C# class. We also need to access the Web Service namespace. It is also a good practice to add a reference to the System namespace.
using System;
using System.Web.Services;

The SecurityWebService class should inherit the functionality of the Web Services class. Therefore, we put the following line of code:
public class SecurityWebService : WebService

Now we can use our object-oriented programming skills to build a class. C# classes are very similar to C++ or Java classes. It will be a walk in the park to create a C# class for anyone with either language-coding skills.
Dot-net Web Services are intelligent enough to cast basic data types. Therefore, if we return "int," "float," or "string" data types, it can convert them to standard XML output. Unfortunately, in most cases we need get a collection of data regarding a single entity. Let's take an example.

Our SecurityWebService stock quotes service requires the user to enter a company code, and it will deliver the full company name and the current stock price. Therefore, we have three pieces of information for a single company:


Company code (data type - string)
Company name (data type - string)
Price (data type - Double)
We need to extract all this data when we are referring to a single stock quote. There are several ways of doing this. The best way could be to bundle them in an enumerated data type. We can use "structs" in C# to do this, which is very similar to C++ structs.
public struct SecurityInfo
{
public string Code;
public string CompanyName;
public double Price;
}

Now we have all the building blocks to create our Web Service. Therefore, our code will look like.

<%@ WebService Language="C#" class="SecurityWebService" %>

using System;
using System.Web.Services;

public struct SecurityInfo
{
public string Code;
public string CompanyName;
public double Price;
}

public class SecurityWebService : WebService
{
private SecurityInfo Security;

public SecurityWebService()
{
Security.Code = "";
Security.CompanyName = "";
Security.Price = 0;
}

private void AssignValues(string Code)
{
// This is where you use your business components.
// Method calls on Business components are used to populate the data.
// For demonstration purposes, I will add a string to the Code and
// use a random number generator to create the price feed.

Security.Code = Code;
Security.CompanyName = Code + " Pty Ltd";
Random RandomNumber = new System.Random();
Security.Price = double.Parse(new System.Random(RandomNumber.Next(1,10)).NextDouble().ToString("##.##"));
}


[WebMethod(Description="This method call will get the company name and the price for a given security code.",EnableSession=false)]
public SecurityInfo GetSecurityInfo(string Code)
{
AssignValues(Code);
SecurityInfo SecurityDetails = new SecurityInfo();
SecurityDetails.Code = Security.Code;
SecurityDetails.CompanyName = Security.CompanyName;
SecurityDetails.Price = Security.Price;
return SecurityDetails;
}

}


Remember, this Web Service can be accessed through HTTP for any use. We may be referring to sensitive business data in the code and wouldn't want it to fall into the wrong hands. The solution is to protect the business logic function and only have access to the presentation functions. This is achieved by using the keyword "[Web Method]" in C#. Let's look at the function headers of our code.
[WebMethod(Description="This......",EnableSession=false)]
public SecurityInfo GetSecurityInfo(string Code)

This function is exposed to the public. The "description" tag can be used to describe the Web Service functionality. Since we will not be storing any session data, we will disable the session state.
private void AssignValues(string Code)

This is a business logic function that should not be publicly available. We do not want our sensitive business information publicly available on the Web. (Note:- Even if you change the "private" keyword to "public," it will still not be publicly available. You guessed it, the keyword "[Web Method]" is not used.)
We can use the business logic in this function to get the newest stock price quote. For the purpose of this article I have added some text to the company code to create the company name. The price value is generated using a random number generator.

We may save this file as "SampleService.asmx" under an Internet Information Service (IIS)-controlled directory. I have saved it under a virtual directory called "/work/aspx." I'll bring it up on a Web browser.



This is a Web page rendered by the .NET Framework. We did not create this page. (The page is generated automatically by the system. I did not write any code to render it on the browser. This graphic is a by-product of the previous code.) This ready-to-use functionality is quite adequate for a simple Web Service. The presentation of this page can be changed very easily by using ASP.NET pagelets and config.web files. A very good example can be found at http://www.ibuyspy.com/store/InstantOrder.asmx.

Notice a link to "SDL Contract." (Even if we are using WSDL, .NET Beta still refers to SDL. Hopefully this will be rectified in the next version). This is the description of the Web Service to create a proxy object. (I will explain this in the next article.) This basically gives an overview of the Web Service and it's public interface. If you look closely, you will only see the "Web-only" methods being illustrated. All the private functions and attributes are not described in the SDL contract. The SDL contract for the SecurityWebService can be found in Appendix A.


view demo of SecurityWebService

How do we use a Web Service?


Now we can use this Web Service. Let's enter some values to get a bogus price feed.



By clicking the Invoke button a new window will appear with the following XML document



This is how the Web Service releases information. We need to write clients to extract the information from the XML document. Theses clients could be

A Web page
A console / Windows application
A Wireless Markup Language (WML) / WMLScript to interact with mobile phones
A Palm / Win CE application to use on Personal Digital Assistants (PDAs).
I will explain this process in the next article.
You can also call the Web Service directly using the HTTP GET method. In this case we will not be going through the above Web page and clicking the Invoke button. The syntax for directly calling the Web Service using HTTP GET is

http://server/webServiceName.asmx/functionName?parameter=parameterValue

Therefore, the call for our Web Service will be

http://localhost/work/aspx/SampleService.asmx/GetSecurityInfo?Code=IBM

This will produce the same result as clicking the Invoke button.

Now we know how to create a Web Service and use it. But the work is half done. How will our clients find our Web Service? Is there any way to search for our Web Service on the Internet? Is there a Web crawler or a Yahoo search engine for Web Services? In order to answer these questions we need to create a "discovery" file for our Web Service.


Creating a Discovery file


Web Service discovery is the process of locating and interrogating Web Service descriptions, which is a preliminary step for accessing a Web Service. It is through the discovery process that Web Service clients learn that a Web Service exists, what its capabilities are, and how to properly interact with it. Discovery file is a XML document with a .DISCO extension. It is not compulsory to create a discovery file for each Web Service. Here is a sample discovery file for our securities Web Service.






We can name this file "SampleService.disco" and save it to the same directory as the Web Service. If we are creating any other Web Services under the "/work/aspx" directory, it is wise to enable "dynamic discovery." Dynamic discovery will scan for all the *.DISCO files in all the subdirectories of "/work/aspx" automatically.




An example of an active discovery file can be found at http://services3.xmethods.net/dotnet/default.disco. By analyzing the discovery file we can find where the Web Services reside in the system. Unfortunately both these methods require you to know the exact URL of the discovery file. If we cannot find the discovery file, we will not be able to locate the Web Services. Universal Description, Discovery, and Integration (UDDI) describes mechanisms to advertise existing Web Services. This technology is still at the infant stage. UDDI is an open, Internet-based specification designed to be the building block that will enable businesses to quickly, easily, and dynamically find and transact business with one another using their preferred applications. A reference site for UDDI is http://uddi.microsoft.com.
There have been a lot of Web Services written by developers. www.xmethods.com is one of the sites that has an index of Web Services. Some developers are building WSDL search engines to find Web Services on the Web.


Deploying a Web Service


Deploying the Web Services from development to staging or production is very simple. Similar to ASP.NET applications, just copy the .ASMX file and the .DISCO files to the appropriate directories, and you are in business.

The future of the Web Services

The future looks bright for the Web Service technology. Microsoft is not alone in the race for Web Service technology. Sun and IBM are very interested. There are SOAP toolkits available for Apache and Java Web servers. I believe Web Services needs a bit of work, especially the Web Service discovery process. It is still very primitive.

On a positive note, Web Services have the potential to introduce new concepts to the Web. One I refer to as "pay per view" architecture. Similar to pay-TV, we can build Web sites that can generate revenue for each request a user sends (as opposed to a flat, monthly subscription). In order to get some data, we can sometimes pay a small fee. Commercially this could be handy for a lot of people.


Examples


Online newspaper sites can publish a 10-year-old article with a $2 "pay per view" structure.
Stock market portals can itemize every user portfolio for every single stock quote and build pricing and discount structures.
And the list goes on ...
On a very optimistic note, Web Services can be described as the "plug and play" building blocks of enterprise Business to Business (B2B) Web solutions.

Appendix A




xmlns="urn:schemas-xmlsoap-org:sdl.2000-01-25">








This method call will get the company name and the price for a given security code.














This method call will get the company name and the price for a given security code.












This method call will get the company name and the price for a given security code.



elementFormDefault="qualified" xmlns="http://www.w3.org/1999/XMLSchema">























Some handy web services

REF: http://www.actionscript.org/forums/showthread.php3?t=70742

Scientific Web Services

http://www.webservicex.net/ConvertAc...tion.asmx?WSDL - Convert acceleration
http://www.webservicex.net/CovertPressure.asmx?WSDL - Convert Pressure
http://www.webservicex.net/ConvertDensity.asmx?WSDL - Convert Density
http://www.webservicex.net/ConverPower.asmx?WSDL - Convert Power
http://www.webservicex.net/ConvertAngle.asmx?WSDL - Convert Angles
http://www.webservicex.net/ConvertTorque.asmx?WSDL - Convert Torque
http://www.webservicex.net/convertMe...ight.asmx?WSDL - Convert Weight
http://www.webservicex.net/convertVolume.asmx?WSDL - Convert Volume
http://www.webservicex.net/ConvertTemperature.asmx?WSDL - Convert Temperature
http://www.webservicex.net/convertFrequency.asmx?WSDL - Convert Frequency
http://www.webservicex.net/Astronomical.asmx?WSDL - Convert Astronomical Values (i.e. - the speed of light)
http://www.webservicex.net/ConvertForec.asmx?WSDL - Convert Force
http://www.webservicex.net/ConvertEnergy.asmx?WSDL - Convert Energy
http://www.webservicex.net/ConvertArea.asmx?WSDL - Convert Area
http://www.webservicex.net/ConvertCooking.asmx?WSDL - Convert Cooking units
http://www.webservicex.net/ConvertComputer.asmx?WSDL - Convert Computer units (i.e. - megabytes)
http://www.webservicex.net/ConvertWeight.asmx?WSDL - Convert Weights
http://www.webservicex.net/ConvertSpeed.asmx?WSDL - Convert Speeds
http://www.webservicex.net/length.asmx?WSDL - Convert Distances
http://www.webservicex.net/periodictable.asmx?WSDL - Periodic Table (i.e. - find atomic weight of Oxygen)

Validation Web Services

http://www.webservicex.net/CreditCard.asmx?WSDL - validate a credit card number
http://www.webservicex.net/ValidateEmail.asmx?WSDL - validate email address
http://www.tpisoft.com/smartpayments/validate.asmx?WSDL - validate credit card number
http://ws.cdyne.com/emailverify/Emai...mail.asmx?wsdl - validate email
http://ws.cdyne.com/phoneverify/phoneverify.asmx?wsdl - validate phone number

Business Web Services

http://www.webservicex.net/stockquote.asmx?WSDL - get stock quote of a particular company

Geographic Web Services

http://www.webservicex.net/uklocation.asmx?WSDL - get location of place in the UK
http://www.webservicex.net/AustralianPostCode.asmx?WSDL - get location in Austrailia of a certain Post code
http://www.webservicex.net/uszip.asmx?WSDL - find location in US based on the ZIP code
http://www.webservicex.net/country.asmx?WSDL - Get country details (i.e. - the currency)
http://www.webservicex.net/geoipservice.asmx?WSDL - get IP address of the persons computer
http://www.webservicex.net/whois.asmx?WSDL - a WHOIS domain lookup
http://ws.cdyne.com/ip2geo/ip2geo.asmx?wsdl - find geo location on earth based on Zip code
http://www.innergears.com/WebService...yZip.asmx?WSDL - Get City and state based on ZIP
http://www.innergears.com/WebService...Zips.asmx?WSDL - Calculate distance between 2 zip codes
http://www.innergears.com/WebService...tate.asmx?WSDL - get a list of ZIP codes in a City
http://www.innergears.com/WebService...ords.asmx?WSDL - calculate distance between Lat/Long

Communication Web Services

http://demo.wsabi.org/axis/services/...ngService?wsdl - check and see if a Yahoo! user is online/offline
http://ws.acrosscommunications.com/Fax.asmx?WSDL - send a FAX to someone
http://www.abysal.com/soap/AbysalEmail.wsdl - send an email (this does add a small ad at the bottom of the outgoing email, but it's just text. It looks like the ad at the bottom of Hotmail emails)
http://ws.strikeiron.com/ReversePhoneLookup?WSDL - reverse Phone number lookup/validator

Weather Web Services

http://www.ejse.com/WeatherService/Service.asmx?WSDL - get the weather based on Zip code/City Name
http://www.innergears.com/WebService...yZip.asmx?WSDL - get the weather based on ZIP
http://www.innergears.com/WebService...yZip.asmx?WSDL - get a 9 day forecast
http://www.innergears.com/WebService...ICAO.asmx?WSDL - get the weather forecast based on ICAO code
http://www.innergears.com/WebService...ings.asmx?WSDL - Get state weather warnings
http://www.innergears.com/WebService...ICAO.asmx?WSDL - get weather around an airport
http://weather.terrapin.com/soap/HurricaneService.wsdl - get information on current storms/hurricanes

Miscellaneous Web Services

http://www.27seconds.com/Holidays/US...ates.asmx?WSDL - Get the date of a certain Holiday
http://www.27seconds.com/Holidays/US...vice.asmx?WSDL - the other half of the Holdiay Web Service above, now includes Great Britain Holidays. (Documentation)
http://webservices.codingtheweb.com/bin/qotd.wsdl - Quote of the day
http://www.boyzoid.com/comp/randomQuote.cfc?wsdl - a random Quote
http://www.swanandmokashi.com/HomePa...cope.asmx?WSDL - get the Horoscope reading
http://www.hlrs.de/quiz/quiz.wsdl - a quiz webservice, returns a question, 4 options, and the correct answer

Friday, March 5, 2010

Custom Save Button for Web Enabled Form

REF: http://blogs.microlinkllc.com/dmcwee/archive/2009/04/30/custom-save-button-for-web-enabled-form.aspx David McWee's Blog

I recently found the need to submit and save Infopath 2007 browser enabled form data. The submit is very straight forward when using browser enabled forms, but the ability to save the form is not so straight forward or so you might think. After thinking for a little while on how to work around the save capability I found a very simple process to allow users to Submit and Save InfoPath Browser enabled forms back to the SharePoint Library without any custom code.


Designing the Form


Begin by creating an InfoPath 2007 form with a button and some text box control(s).

Add an additional Data Source called submitFormName

Add a Data Connection


Create the Data Source Connection that will allow the form to be submitted to the SharePoint site using the following steps.

Click on the Manage Data Connections… and then click the Add button


Select Create a new connection to: and Submit Data then click Next >


On the next screen Select a destination for submitting your data choose the To a document library on a SharePoint site then choose Next >


Now provide a URL to the document library you want to submit your data to. In the next to the file name textbox click on the fx button. Click on the Insert Field or Group… button and select the submitFormName field.


Click the OK button on the Select a Field or Group window and on the Insert Formula Window. On the data connection wizard check the Allow overwrite if file exists option. Click Next >


You can now provide a custom name for your data connection then click Next >.

Click Close on the Data Connections window

Add the actions to the Custom Button

Double Click on the button control added to the InfoPath form

Select Rules and Custom Code for the Action and provide a label and control ID, if desired, of your choice.

Click on the Rules… button and then click on the Add button in the Rules Window.


Name this rule Set File Name and click on the Set Condition… button. For the Condition check if the submitFormName is blank. Click the OK button.



Click the Add Action… button. For the action select Set a field's value, for the Field select submitFormName, for the Value use, using the fx builder use the expression concat("Account Request - ", now()) then click OK.


Click OK on the Rule Window. Now click on the Add… button again on the Rules window. Name this rule Submit Form and do not specify a condition. Add an action to Submit using a data connection and select the Data connection created in the last section.


Click the OK button on the Action and Rule windows.


Click the Add… button on the Rule Window. Name this rule Close Form and do not specify a condition. Add an action to close the form.


Click OK on all of the windows until you are back to the InfoPath form designer.



Now publish your form to the SharePoint site library that was specified in the Data Connection section. Once the form is published go to that library and choose Settings->Form Library Settings


Under the General Settings choose Advanced settings



In Advanced Settings under the Browser-enabled Documents choose Display as a Web page and then click OK


This will force the InfoPath form to be opened using Form Services.


Now complete a form and submit it. Then click on the form, change a value and submit again. You should see your changes applied after you submit.

Prepare your Master Pages

REF: http://vspug.com/dwise/2007/01/08/one-master-to-rule-them-all-two-actually/

« HowTo: Filter a View based on Workflow StatusMystery Master Page or CMS Gotcha »One .Master to Rule Them All (Two, actually)
One of the biggest annoyances with Sharepoint 2007 is the quirky things you have to do in order to customize a site. This is especially true when it comes to custom master pages. You create a stunning master page in Designer, configure the site to use it, then load the page and wait to bask in the glory. Lo and Behold! It worked! Job done, go grab a beer … but you better drink it fast because Sharepoint has a nasty surprise in store for you. That master page only works on the content pages in your site. System pages (i.e. viewlists.aspx) will refuse to use your amazing Master page. All that work is wasted on a half complete user experience. Or is it?

Why is it not doing what I tell it to do?
This is because those system pages are hard-wired to use a different master page (application.master) . To make matters worse, you only get one application.master for everywhere. You could go modify this file, but be careful: changes to this will affect ALL pages based on that master, everywhere. It's not something that can be customized on a site-by-site basis. To make matters still worse, Microsoft *will* update this file in upcoming patches, so odds are good that it will break on you sometime in the future, and likely with little warning.

Ok, so what's the skinny?
Create a custom httpModule and install it on your Sharepoint site that remaps which .Master pages your pages use. If you aren't familiar with httpModules, fear not, they are extremely simple.

The httpModule sits in the middle of the http request processing stream and can intercept page events when they initialize. The pages load up and say "I'm going to use application.master", to which your module replies "not on my watch, buddy" and not so gently forces the page to use the Master page of your choice.

The Gory Details
(this assumes that you already have the aforementioned Nifty Master Page created. If not, please search Google for any of the hundreds of tutorials on how to do this)

Prepare your Master Pages
You will need two .Master pages. One to replace default.master and the other to replace application.master. It is very important that when you are creating these pages that you include all of the ContentPlaceHolders that exist in the .Master page you are replacing. Throw any ContentPlaceHolders that you are not using in a hidden DIV at the bottom of the page – but before the closing FORM tag (the only exception to this seems to be "PlaceHolderUtilityContent" which goes in after the closing form tag). Once in place, you can use the normal Master Page options in the UI to select the default.master replacement.

Second, be sure to remove the Search Control from your Application.Master replacement. The reason for this is that the search box does not normally appear on system pages and will cause an error during rendering.

You can probably simplify this a bit by using nested master pages, but I haven't had a chance to look into that yet.

Step 1 – Create the httpModule
Create a new Class Library project in Visual Studio and start with the code below. So simple, even a manager could do it (maybe). Obviously, you will have to change the path to match your environment. Oh, and sign the assembly as well.


using System;
using System.Web;
using System.Web.UI;
using System.IO;

public class MasterPageModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
Page page = HttpContext.Current.CurrentHandler as Page;
if (page != null)
{
page.PreInit += new EventHandler(page_PreInit);
}
}
void page_PreInit(object sender, EventArgs e)
{
Page page = sender as Page;
if (page != null)
{
// Is there a master page defined?
if (page.MasterPageFile != null)
{
// only change the application.master files as those are the offenders
if (page.MasterPageFile.Contains("application.master"))
{
page.MasterPageFile = "/_catalogs/masterpage/MyCustom.master";
}
}
}
}

public void Dispose()
{
}
}

Note the path above: that is required so that all pages can find the Master page as not all pages are running from the site context

This is a simplified example but you can see the potential here. With this in place, YOU control the horizontal and YOU control the vertical. Or, for a more modern reference, YOU decide who gets the red pill and who gets the blue pill.

Build it and then throw the DLL in the /bin folder in your Sharepoint site root (usually something like InetpubwwwrootwssVirtualDirectories80 in). You may have to create the in folder if one is not there. Once you have it working the way you want, you will need to sign it and move it to the GAC, but this works for getting started.

Step 2 – Register the httpModule
Another easy step – throw in the bolded line below in your web.config file at the bottom of the httpModules section. This section should already be there.


… stuff you dont care about …



Step 3 – Load the Page
Navigate to the home page of your site. That should work normal as it is using the normal Sharepoint Master page logic. Now go to a System page, like 'Documents' , 'Lists' or 'Pictures'. These should now be using your Master page

If you've followed the this tip you will actually be able to see the real error, if any, when you load the page.

Step 4 – Go get that beer
Do you really need instructions for this?

Special thanks to K. Scott Allen for his post showing how to change the .Master page using an httpModule. You will notice that the code above bears an amazing resemblance to his.



3/1/2007 – UPDATE!
In response to comments, I have updated these instructions, in particular, I have added the "Prepare your Master Pages" section that addresses most of the issues encountered in the comments.

Also, do not use this method if your sharepoint install has the shared Service Provider (SSP) installed on the same web application as your main sharepoint environment. The system pages used by the SSP do not work properly when their master page is replaced like this. I'm sure there is a logical reason why, I simply haven't had the time to dive into it.