Friday 23 September 2011

Managing blocked file types in Sharepoint 2010 with Web UI

Jim, my work mate, was trying to enable exe files in a Sharepoint web application. Unfortunatly he wasn’t very happy, just because nothing worked. He asked my for help and sadly I didn’t know the answer, well I knew the answer but something wasn’t going well.

We managed to find the answer. The problem was that we were using a different Web Application.

I am going to do a Step by Step to show you how to unblock exe files from your web application.

MSDN suggests these files are blocked by default:

 

.ade
.adp
.app
.asa
.ashx
.asmx
.asp
.bas
.bat
.cdx
.cer
.chm
.class
.cmd
.com
.config
.cpl
.crt
.csh
.dll
.exe
.fxp
.hlp
.hta
.htr
.htw
.ida
.idc
.idq
.ins
.isp
.its
.jse
.ksh
.lnk
.mad
.maf
.mag
.mam
.maq
.mar
.mas
.mat
.mau
.mav
.maw
.mda
.mdb
.mde
.mdt
.mdw
.mdz
.msc
.msh
.msh1
.msh1xml
.msh2
.msh2xml
.mshxml
.msi
.msp
.mst
.ops
.pcd
.pif
.prf
.prg
.printer
.pst
.reg
.rem
.scf
.scr
.sct
.shb
.shs
.shtm
.shtml
.soap
.stm
.url
.vb
.vbe
.vbs
.ws
.wsc
.wsf
.wsh

- Step 1:
Go to central administration (be sure you are administrator) and click on “Security”
image

- Step 4:
Now click on “Define blocked types”.
image

- Step 5:
Select the Web Application you want to change by clicking in “Change Web Application”. After that, remove the exe extension from the list. If you want to block more extensions, just add a new line with the extension name. Click OK, and work done!
image

Wednesday 21 September 2011

SpecificFinder vs Finder in Business Data Connectivity (BDC)

I was trying to find the difference between SpecificFinder and Finder. I am not going deep inside the subject in this article, but if you really need know more about it, please visit this MSDN article.

A SpecificFinder can return a single entity instance by creating a Specific Finder method. The Business Data Connectivity (BDC) service executes the Specific Finder method when a user selects an entity in a Business Data Web Part or External list.

Anyway, the issue here is that we can use Finder as well… so what is the difference. Well, I will go deeper and deeper in this subject…but there is a superb explanation from Jonathon Palmer, so if you don’t mind I am going to reuse it.

- SpecificFinder is meant to find "one specific  instance" of the entity:

Customer GetCustomer(int id);


- Finder is meant to find "zero, one or more instances" for an entity:

Customer[] GetCustomers(string filter);

SPUserCodeService and ResourceMeasures

ResourceMeasures Gets the collection of measures for regulating the resource usage of services in the Microsoft SharePoint Foundation farm.

With this class you can have full control over the measures. That means you can disable them or just adjust the value you think are more appropriate for your farm. I will say it is dangerous to play around with these properties because it gives you a really powerful weapon.

For the time being these are the measures we can access, disable/enable or just assign a particular value:

  1. AbnormalProcessTerminationCount
  2. CPUExecutionTime
  3. CriticalExceptionCount
  4. InvocationCount
  5. PercentProcessorTime
  6. ProcessCPUCycles
  7. ProcessHandleCount
  8. ProcessIOBytes
  9. ProcessThreadCount
  10. ProcessVirtualBytes
  11. SharePointDatabaseQueryCount
  12. SharePointDatabaseQueryTime
  13. UnhandledExceptionCount
  14. UnresponsiveprocessCount

I am going to show you two simple snippets two show you how these works.

- This example disables CriticalExceptionCount:

Microsoft.SharePoint.Administration.SPUserCodeService _spUserCode = Microsoft.SharePoint.Administration.SPUserCodeService.Local;
_spUserCode.ResourceMeasures["CriticalExceptionCount"].ResourcesPerPoint = 0;
_spUserCode.Update();


- This example assigns a limit of 50 to the CPUExecutionTime:

Microsoft.SharePoint.Administration.SPUserCodeService _spUserCode = Microsoft.SharePoint.Administration.SPUserCodeService.Local;
_spUserCode.ResourceMeasures["CPUExecutionTime"].AbsoluteLimit = 40;
_spUserCode.Update();


Conclusion: Before playing around with these values, I highly recommend to back up the server. That is my conclusion… so good luck!

CreateTask.SpecialPermissions in Workflows

I am sure that at some point you have came with this problem; You crate tasks in your task list and another user has deleted them, because he/she thought they were rubbish.

Well, there is a way to tell Sharepoint 2010 to display the tasks for a particular user and prevent this to happen.

You will be using CreateTask.SpecialPermissions. This is an example of how to use it.

//## It creates a task.
CreateTask _ctTask = new CreateTask();
//## We assign the properties for the task.
_ctTask.TaskProperties.AssignedTo = @"DOMAIN/USER";
_ctTask.TaskProperties.Title = "Task title";
_ctTask.TaskProperties.Description = "Task description";
_ctTask.TaskProperties.DueDate = DateTime.Now.AddDays(3);
_ctTask.TaskProperties.EmailBody ="Email body";
_ctTask.TaskProperties.SendEmailNotification = true;
//## This part will give permisions to teh user with the admin role
System.Collections.Specialized.HybridDictionary _hPermissions = new System.Collections.Specialized.HybridDictionary();            
_hPermissions.Add(_ctTask.TaskProperties.AssignedTo, SPRoleType.Administrator);
//## SpecialPermissions assigned!
_ctTask.SpecialPermissions = _hPermissions;


Conclusion: As you can see SpecialPermissions will be a really important tool to consider when you build your workflows.

Tuesday 20 September 2011

SPUserToken and the Impersonating process in Sharepoint 2010

Some times you will need to work with SPSecurity.RunWithElevatedPrieveleges but you will notice that if you follow that path you could end having a lot of trouble. So instead of going to the extreme with approach you can find a really nice class called SPUserToken class what is really easy to use.

What you, basically, it is tell to Sharepoint you are the system and you want to be able to perform some operations.

How? You just pass the parameter in the SPSite object when you open it:

SPUserToken _tUserToken= SPContext.Current.Site.SystemAccount.UserToken;
using(SPSite _sSite = new SPSite(SPContext.Current.Site.ID, _tUserToken= ))
{
     using (SPWeb _wWeb = _sSite.OpenWeb(SPContext.Current.Web.ID))
     {
       //## WRITE YOUR CODE HERE
     }
} 


You can always inherit the user token from a site:

SPSite _sSiteTemp = new SPSite(@"http://SHAREPOINTSITE");
SPUserToken _UserToken= _sSiteTemp.SystemAccount.UserToken;
using (SPSite _sSite= new SPSite(siteStr, systoken))
{
       using (SPWeb _wWeb= _sSite.OpenWeb())
       {
          //## WRITE YOUR CODE HERE
       }
}
   
if (_sSiteTemp!=null) _sSiteTemp.Dispose();


Conclusion: Remember, before using SPSecurity.RunWithElevatedPrieveleges think about this option.

Monday 19 September 2011

RESTful, Sharepoint Web Services , JavaScript(SP.js) and ASP.NET all together in a Sharepoint 2010 application form

If you see one of my previous post (http://netsourcecode.blogspot.com/2011/09/using-javascript-spjs-in-web-parts-in.html) you will notice I play around with an ASP.NET Application page and one web part from Sharepoint 2010 to display the current user in a message box. I also query a list with another button. I do all of this with JavaScript(SP.js)

The fact is that Andy, my work mate, came on Friday with the idea of detecting a user, query it by getting the properties of the USER PROFILE in a modal form. Good challenge isn’t it?, he is a good man so I always I accept his challenges. I start studying the documentation for the SP.js library and after hours trying to find the way to access to custom user properties I couldn't find anything. You can only get the name, email etc… basic stuff but if you want something else, forget it.

Andy was looking for two fields he created:
       - Department
       - Title

My limitation was extreme, I didn’t have access to the Sharepoint.Client.dll, JavaScript or the Server Model, so I decided to implement the Sharepoint Web Services against JavaScript and use both platforms JavaScript (SP.js) and Web Services (/_vti_bin/UserProfileService.asmx with the method GetUserPropertyByAccountName()).

I have to admit it was hard work, but at the end I managed to make it work.

In the code I am going to post are three buttons which call 3 functions:

  • SayHello(): It says hello.
  • DisplauUser(): It displays the current user.
  • DisplayList(): Displays the “remaining seats”(custom metadata field) of the Shared Documents list.

What do we need to make this work?

  1. Visual Studio 2010.
  2. Sharepoint 2010.
  3. A list called “Shared Documents” with an extra field called remaining seats.
  4. Two extra fields in the user profile (Department, Title).
  5. Change the references in the JavaScript to the URLs
  6. And good luck…

You need to create an application page to run this thing. You can download the project I create in http://netsourcecode.blogspot.com/2011/09/using-javascript-spjs-in-web-parts-in.html and paste the code in the form, if you don’t want to work.

2 PARTS
   -First Part: JavaScript Code
   -Second Part: ASP.NET Code behind.

1 Part JavaScript:

<%@ 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="GetUsers.aspx.cs" Inherits="netsourcecodeJavaScript.Layouts.netsourcecodeJavaScript.GetUsers" DynamicMasterPageFile="~masterurl/default.master" %>
<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<% #if SOME_UNDEFINED_CONSTANT %>
    <script type="text/javascript" src="/_layouts/SP.debug.js" ></script>
    <script type="text/ecmascript" src="/_layouts/SP.js" ></script>
    <script type="text/ecmascript" src="/_layouts/SP.Core.js" ></script>
    <script type="text/ecmascript" src="/_layouts/SP.Runtime.Debug.js" ></script>   
<% #endif %>
 
<script language="ecmascript" type="text/ecmascript">
    //## Activate this function if you want to load the script at the very beginig
    //ExecuteOrDelayUntilScriptLoaded(DisplayList, "sp.js");
       
    //## Variables
    var context = null;
    var web = null;
    var currentUser = null;
    var collListItems = null;
    var username = null;
    var loginname = null;
    var isgettinglist = false;
   
    //## 1
    //## This function gets the login name and display it in a MessageBox
    function DisplayUser() {
        isgettinglist = false;
        GetUserData();
    }
    //## 2
    //## This function displays the values from the list
    function DisplayList() {
        isgettinglist = true;
        GetUserData();
    }
    //## 3
    //## This function says hello.
    function SayHello() {
        alert('Hellow!');
    }
    //## Getting the user
    function GetUserData() {
        //## Getting the context
        context = new SP.ClientContext.get_current();
        //## Getting the web
        web = context.get_web();
        //## Getting the current user
        currentUser = web.get_currentUser();
                             
        //## Load the query
        currentUser.retrieve();
        context.load(web);
       
        //## Execute the query Async
        context.executeQueryAsync(Function.createDelegate(this, this.onSuccessMethod), Function.createDelegate(this, this.onFailureMethod));
    }
   
    //## SUCCESS FOR USER EVENT
    function onSuccessMethod(sender, args) {
        //## Setting the object to get the current user...again...
        var userObject = web.get_currentUser();
       
        //## Adding the user into a Variable
        username = userObject.get_title();
        loginname = userObject.get_loginName();
        if (isgettinglist == false) {
            alert('User name:' + username + '\n Login Name:' + loginname);
        }
        if (isgettinglist == true) {
            //## Getting the results from the list
            var department = GetPropertyFromUserProfile("http://ecmdemo.panint.com/lms/_vti_bin/UserProfileService.asmx", "Department", loginname);
            var title = GetPropertyFromUserProfile("http://ecmdemo.panint.com/lms/_vti_bin/UserProfileService.asmx", "Title", loginname);           
            GetListByName(loginname,department,title);
        }
    }
    //## FAILURE FOR USER EVENT
    function onFailureMethod(sender, args) {
        alert('request failed ' + args.get_message() + '\n' + args.get_stackTrace());
    }   
    //## It gets the property froma  user profile
    function GetPropertyFromUserProfile(url,name,value)
    {
        var responsefromwebservice = null;
        var parameters = new SOAPClientParameters();
        parameters.add("acountName", value);
        parameters.add("propertyName", name);
        //## SYNC MODE
        var response = SOAPClient.invoke(url, "GetUserPropertyByAccountName", parameters, false);
        //#############
        //## ASYNC MODE
        //SOAPClient.invoke("http://ecmdemo.panint.com/lms/_vti_bin/UserProfileService.asmx", "GetUserPropertyByAccountName", pl, true, GetDepartMentFromUserProfile_callBack);
        //function GetDepartMentFromUserProfile_callBack(r)
        //{alert(r);}
        //alert(response.Values[0].Value);
        //#############
        if (response != null) responsefromwebservice = response.Values[0].Value;
        return responsefromwebservice;
    }
    //## It gets the number of seats quering the login, department and title
    function GetListByName(username,department,title) {
        //## Get the context again
        context = new SP.ClientContext.get_current();
        //## Get the list
        var list = context.get_site().get_rootWeb().get_lists().getByTitle('Shared Documents');
        //## Builds a CAMEL querty to return items
        var query = new SP.CamlQuery();
        //query.set_viewXml('<View><Query><Where><Eq><FieldRef Name="Author"/><Value Type="User">' + username + '</Value></Eq></Where></Query><ViewFields><FieldRef Name="Title"/><FieldRef Name="FileLeafRef"/></ViewFields></View>');
        query.set_viewXml('<Query> <Where> <And> <Contains><FieldRef Name="Grade" /> <Value Type="Text">' + title + '</Value> </Contains> <And><Contains><FieldRef Name="Group" /><Value Type="Text">' + department + '</Value></Contains><And> <Geq> <FieldRef Name="Start" /> <Value IncludeTimeValue="TRUE" Type="DateTime">' + GetDateTimeNowForCAMLQuery() + '</Value> </Geq> <Gt><FieldRef Name="Remaining_x0020_Seats" /> <Value Type="Number">0</Value> </Gt> </And></And> </And></Where></Query>');
        //## Geting the items
        this.collListItems = list.getItems(query);
        context.load(collListItems);
        //## Execute the query Async
        context.executeQueryAsync(Function.createDelegate(this, this.GetListByNameSuccessFunctionEvent), Function.createDelegate(this, this.GetListByNameFailFunctionEvent));
    }
    //## SUCCESS FOR LIST EVENT
    function GetListByNameSuccessFunctionEvent() {
        //## Do something useful like loop through your returned list items and output in a variable        
        var listItemEnumerator = this.collListItems.getEnumerator();
        var strHtml = "";
        while (listItemEnumerator.moveNext()) {
            var oListItem = listItemEnumerator.get_current();
            strHtml += oListItem.get_item('Remaining_x0020_Seats').toString();
        }
        return strHtml;
        //alert(strHtml);
    }
    //## FAIL FOR USER EVENT
    function GetListByNameFailFunctionEvent() { alert('Request fail'); }
    //###################################################################
    //###################################################################
    //################ U T I L I T I E S ################################
    //###################################################################
    //###################################################################
    function GetDateTimeNowForCAMLQuery()
    {
        //## FORMAT 2011-09-16T16:15:18z
        var currentTime = new Date()              
        return currentTime.getFullYear()+'-'+currentTime.getMonth()+'-'+currentTime.getDay()+'T'+currentTime.getHours()+':'+currentTime.getMinutes()+':'+currentTime.getSeconds()+'z';
    }   
    function SOAPClientParameters() {
        var _pl = new Array();
        this.add = function (name, value) {
            _pl[name] = value;
            return this;
        }
        this.toXml = function () {
            var xml = "";
            for (var p in _pl) {
                switch (typeof (_pl[p])) {
                    case "string":
                    case "number":
                    case "boolean":
                    case "object":
                        xml += "<" + p + ">" + SOAPClientParameters._serialize(_pl[p]) + "</" + p + ">";
                        break;
                    default:
                        break;
                }
            }
            return xml;
        }
    }
    SOAPClientParameters._serialize = function (o) {
        var s = "";
        switch (typeof (o)) {
            case "string":
                s += o.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); break;
            case "number":
            case "boolean":
                s += o.toString(); break;
            case "object":
                // Date
                if (o.constructor.toString().indexOf("function Date()") > -1) {
                    var year = o.getFullYear().toString();
                    var month = (o.getMonth() + 1).toString(); month = (month.length == 1) ? "0" + month : month;
                    var date = o.getDate().toString(); date = (date.length == 1) ? "0" + date : date;
                    var hours = o.getHours().toString(); hours = (hours.length == 1) ? "0" + hours : hours;
                    var minutes = o.getMinutes().toString(); minutes = (minutes.length == 1) ? "0" + minutes : minutes;
                    var seconds = o.getSeconds().toString(); seconds = (seconds.length == 1) ? "0" + seconds : seconds;
                    var milliseconds = o.getMilliseconds().toString();
                    var tzminutes = Math.abs(o.getTimezoneOffset());
                    var tzhours = 0;
                    while (tzminutes >= 60) {
                        tzhours++;
                        tzminutes -= 60;
                    }
                    tzminutes = (tzminutes.toString().length == 1) ? "0" + tzminutes.toString() : tzminutes.toString();
                    tzhours = (tzhours.toString().length == 1) ? "0" + tzhours.toString() : tzhours.toString();
                    var timezone = ((o.getTimezoneOffset() < 0) ? "+" : "-") + tzhours + ":" + tzminutes;
                    s += year + "-" + month + "-" + date + "T" + hours + ":" + minutes + ":" + seconds + "." + milliseconds + timezone;
                }
                // Array
                else if (o.constructor.toString().indexOf("function Array()") > -1) {
                    for (var p in o) {
                        if (!isNaN(p))   // linear array
                        {
                            (/function\s+(\w*)\s*\(/ig).exec(o[p].constructor.toString());
                            var type = RegExp.$1;
                            switch (type) {
                                case "":
                                    type = typeof (o[p]);
                                case "String":
                                    type = "string"; break;
                                case "Number":
                                    type = "int"; break;
                                case "Boolean":
                                    type = "bool"; break;
                                case "Date":
                                    type = "DateTime"; break;
                            }
                            s += "<" + type + ">" + SOAPClientParameters._serialize(o[p]) + "</" + type + ">"
                        }
                        else    // associative array
                            s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">"
                    }
                }
                // Object or custom function
                else
                    for (var p in o)
                        s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">";
                break;
            default:
                break; // throw new Error(500, "SOAPClientParameters: type '" + typeof(o) + "' is not supported");
        }
        return s;
    }
    function SOAPClient() { }
    SOAPClient.username = null;
    SOAPClient.password = null;
    SOAPClient.invoke = function (url, method, parameters, async, callback) {
        if (async)
            SOAPClient._loadWsdl(url, method, parameters, async, callback);
        else
            return SOAPClient._loadWsdl(url, method, parameters, async, callback);
    }
    // private: wsdl cache
    SOAPClient_cacheWsdl = new Array();
    // private: invoke async
    SOAPClient._loadWsdl = function (url, method, parameters, async, callback) {
        // load from cache?
        var wsdl = SOAPClient_cacheWsdl[url];
        if (wsdl + "" != "" && wsdl + "" != "undefined")
            return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
        // get wsdl
        var xmlHttp = SOAPClient._getXmlHttp();
        xmlHttp.open("GET", url + "?wsdl", async);
        if (async) {
            xmlHttp.onreadystatechange = function () {
                if (xmlHttp.readyState == 4)
                    SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
            }
        }
        xmlHttp.send(null);
        if (!async)
            return SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
    }
    SOAPClient._onLoadWsdl = function (url, method, parameters, async, callback, req) {
        var wsdl = req.responseXML;
        SOAPClient_cacheWsdl[url] = wsdl; // save a copy in cache
        return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
    }
    SOAPClient._sendSoapRequest = function (url, method, parameters, async, callback, wsdl) {
        // get namespace
        var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;
        // build SOAP request
        var sr =
    "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
    "<soap:Envelope " +
    "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
    "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
    "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
    "<soap:Body>" +
    "<" + method + " xmlns=\"" + ns + "\">" +
    parameters.toXml() +
    "</" + method + "></soap:Body></soap:Envelope>";
        // send request
        var xmlHttp = SOAPClient._getXmlHttp();
        if (SOAPClient.userName && SOAPClient.password) {
            xmlHttp.open("POST", url, async, SOAPClient.userName, SOAPClient.password);
            // Some WS implementations (i.e. BEA WebLogic Server 10.0 JAX-WS) don't support Challenge/Response HTTP BASIC, so we send authorization headers in the first request
            xmlHttp.setRequestHeader("Authorization", "Basic " + SOAPClient._toBase64(SOAPClient.userName + ":" + SOAPClient.password));
        }
        else
            xmlHttp.open("POST", url, async);
        var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + method;
        xmlHttp.setRequestHeader("SOAPAction", soapaction);
        xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        if (async) {
            xmlHttp.onreadystatechange = function () {
                if (xmlHttp.readyState == 4)
                    SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp);
            }
        }
        xmlHttp.send(sr);
        if (!async)
            return SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp);
    }
    SOAPClient._onSendSoapRequest = function (method, async, callback, wsdl, req) {
        var o = null;
        var nd = SOAPClient._getElementsByTagName(req.responseXML, method + "Result");
        if (nd.length == 0)
            nd = SOAPClient._getElementsByTagName(req.responseXML, "return"); // PHP web Service?
        if (nd.length == 0) {
            if (req.responseXML.getElementsByTagName("faultcode").length > 0) {
                if (async || callback)
                    o = new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
                else
                    throw new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
            }
        }
        else
            o = SOAPClient._soapresult2object(nd[0], wsdl);
        if (callback)
            callback(o, req.responseXML);
        if (!async)
            return o;
    }
    SOAPClient._soapresult2object = function (node, wsdl) {
        var wsdlTypes = SOAPClient._getTypesFromWsdl(wsdl);
        return SOAPClient._node2object(node, wsdlTypes);
    }
    SOAPClient._node2object = function (node, wsdlTypes) {
        // null node
        if (node == null)
            return null;
        // text node
        if (node.nodeType == 3 || node.nodeType == 4)
            return SOAPClient._extractValue(node, wsdlTypes);
        // leaf node
        if (node.childNodes.length == 1 && (node.childNodes[0].nodeType == 3 || node.childNodes[0].nodeType == 4))
            return SOAPClient._node2object(node.childNodes[0], wsdlTypes);
        var isarray = SOAPClient._getTypeFromWsdl(node.nodeName, wsdlTypes).toLowerCase().indexOf("arrayof") != -1;
        // object node
        if (!isarray) {
            var obj = null;
            if (node.hasChildNodes())
                obj = new Object();
            for (var i = 0; i < node.childNodes.length; i++) {
                var p = SOAPClient._node2object(node.childNodes[i], wsdlTypes);
                obj[node.childNodes[i].nodeName] = p;
            }
            return obj;
        }
        // list node
        else {
            // create node ref
            var l = new Array();
            for (var i = 0; i < node.childNodes.length; i++)
                l[l.length] = SOAPClient._node2object(node.childNodes[i], wsdlTypes);
            return l;
        }
        return null;
    }
    SOAPClient._extractValue = function (node, wsdlTypes) {
        var value = node.nodeValue;
        switch (SOAPClient._getTypeFromWsdl(node.parentNode.nodeName, wsdlTypes).toLowerCase()) {
            default:
            case "s:string":
                return (value != null) ? value + "" : "";
            case "s:boolean":
                return value + "" == "true";
            case "s:int":
            case "s:long":
                return (value != null) ? parseInt(value + "", 10) : 0;
            case "s:double":
                return (value != null) ? parseFloat(value + "") : 0;
            case "s:datetime":
                if (value == null)
                    return null;
                else {
                    value = value + "";
                    value = value.substring(0, (value.lastIndexOf(".") == -1 ? value.length : value.lastIndexOf(".")));
                    value = value.replace(/T/gi, " ");
                    value = value.replace(/-/gi, "/");
                    var d = new Date();
                    d.setTime(Date.parse(value));
                    return d;
                }
        }
    }
    SOAPClient._getTypesFromWsdl = function (wsdl) {
        var wsdlTypes = new Array();
        // IE
        var ell = wsdl.getElementsByTagName("s:element");
        var useNamedItem = true;
        // MOZ
        if (ell.length == 0) {
            ell = wsdl.getElementsByTagName("element");
            useNamedItem = false;
        }
        for (var i = 0; i < ell.length; i++) {
            if (useNamedItem) {
                if (ell[i].attributes.getNamedItem("name") != null && ell[i].attributes.getNamedItem("type") != null)
                    wsdlTypes[ell[i].attributes.getNamedItem("name").nodeValue] = ell[i].attributes.getNamedItem("type").nodeValue;
            }
            else {
                if (ell[i].attributes["name"] != null && ell[i].attributes["type"] != null)
                    wsdlTypes[ell[i].attributes["name"].value] = ell[i].attributes["type"].value;
            }
        }
        return wsdlTypes;
    }
    SOAPClient._getTypeFromWsdl = function (elementname, wsdlTypes) {
        var type = wsdlTypes[elementname] + "";
        return (type == "undefined") ? "" : type;
    }
    // private: utils
    SOAPClient._getElementsByTagName = function (document, tagName) {
        try {
            // trying to get node omitting any namespaces (latest versions of MSXML.XMLDocument)
            return document.selectNodes(".//*[local-name()=\"" + tagName + "\"]");
        }
        catch (ex) { }
        // old XML parser support
        return document.getElementsByTagName(tagName);
    }
    // private: xmlhttp factory
    SOAPClient._getXmlHttp = function () {
        try {
            if (window.XMLHttpRequest) {
                var req = new XMLHttpRequest();
                // some versions of Moz do not support the readyState property and the onreadystate event so we patch it!
                if (req.readyState == null) {
                    req.readyState = 1;
                    req.addEventListener("load",
         function () {
             req.readyState = 4;
             if (typeof req.onreadystatechange == "function")
                 req.onreadystatechange();
         },
         false);
                }
                return req;
            }
            if (window.ActiveXObject)
                return new ActiveXObject(SOAPClient._getXmlHttpProgID());
        }
        catch (ex) { }
        throw new Error("Your browser does not support XmlHttp objects");
    }
    SOAPClient._getXmlHttpProgID = function () {
        if (SOAPClient._getXmlHttpProgID.progid)
            return SOAPClient._getXmlHttpProgID.progid;
        var progids = ["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
        var o;
        for (var i = 0; i < progids.length; i++) {
            try {
                o = new ActiveXObject(progids[i]);
                return SOAPClient._getXmlHttpProgID.progid = progids[i];
            }
            catch (ex) { };
        }
        throw new Error("Could not find an installed XML parser");
    }
    SOAPClient._toBase64 = function (input) {
        var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;
        do {
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }
            output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
  keyStr.charAt(enc3) + keyStr.charAt(enc4);
        } while (i < input.length);
        return output;
    }
  </script>
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<SharePoint:FormDigest ID="FormDigest1"  runat="server" />
<asp:Button ID="Button1" runat="server" Text="Get User" />
<asp:Button ID="Button2" runat="server" Text="Query List" />
<asp:Button ID="Button3" runat="server" Text="Say Hello" />
</asp:Content>
<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
Application Page
</asp:Content>
<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
My Application Page
</asp:Content>

2 Part ASP.NET:

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace netsourcecodeJavaScript.Layouts.netsourcecodeJavaScript
{
    public partial class GetUsers : LayoutsPageBase
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Button1.Attributes.Add("onclick", "DisplayUser()");
            Button2.Attributes.Add("onclick", "DisplayList()");
            Button3.Attributes.Add("onclick", "SayHello()");
        }
    }
}

Conclusion: As you can see you can achieve almost everything with the native webservices. Unfortunately Intellisense doesn't work properly for JavaScript in Visual Studio 2010…so it is a nightmare to do something with it.