Monday, January 14, 2013

Create a new BDC application


  1. c heck the server service to make sure the BDC service is started; other you need to create a new BDC service application.
 
2.When you create the BDC service application, make sure the application pool account must have admin group.
      3. When add connection in SP designer, your windows account must have access to your external database. It is used to create a connection. Otherwise you will get access is denied by BDC. Later you need to tweak you BDC model manually to set the SQL credential. Otherwise  you will get “NT authority/net work is denied”. The original BDC try to use iusernet account to access to the database.
   4. Go to CA and click Service Connections Manage form the ribbon for the application,

 

to change the content type group of a list, check this  item, click edit property on the ribbon and change the content type in the interface.

Monday, January 7, 2013

Self Hosting

In web service, we can host the service only in IIS, but WCF provides the user to host the service in any application (e.g. console application, Windows form etc.). Very interestingly developer is responsible for providing and managing the life cycle of the host process. Service can also be in-pro i.e. client and service in the same process. Now let's us create the WCF service which is hosted in Console application. We will also look in to creating proxy using 'ClientBase' abstract class.
Note: Host process must be running before the client calls the service, which typically means you have to prelaunch it.

Step 1: First let's start create the Service contract and it implementation. Create a console application and name it as MyCalculatorService. This is simple service which return addition of two numbers.
 
Step 2: Add the System.ServiceModel reference to the project.
Step 3: Create an ISimpleCalculator interface, Add ServiceContract and OperationContract attribute to the class and function as shown below. You will know more information about these contracts in later session. These contracts will expose method to outside world for using this service.
IMyCalculatorService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace MyCalculatorService
{
    [ServiceContract()]
    public interface ISimpleCalculator
    {
        [OperationContract()]
        int Add(int num1, int num2);
    }

}
Step 4: MyCalculatorService is the implementation class for IMyCalculatorService interface as shown below.
MyCalculatorService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyCalculatorService
{
    class SimpleCalculator : ISimpleCalculator
    {
        public int Add(int num1, int num2)
        {
            return num1 + num2;
        }

    }
}
Step 5: Now we are ready with service. Let's go for implementing the hosting process. Create a new console application and name it as 'MyCalculatorServiceHost'
Step 6: ServiceHost is the core class use to host the WCF service. It will accept implemented contract class and base address as contractor parameter. You can register multiple base addresses separated by commas, but address should not use same transport schema.
 
Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator");

Uri tcpUrl = new Uri("net.tcp://localhost:8090/MyService/SimpleCalculator");

ServiceHost host 
= new ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl, tcpUrl);
Multiple end points can be added to the Service using AddServiceEndpoint() method. Host.Open() will run the service, so that it can be used by any client.
Step 7: Below code show the implementation of the host process.
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace MyCalculatorServiceHost
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create a URI to serve as the base address
            Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator");
            //Create ServiceHost
            ServiceHost host 
            = new ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl);
            //Add a service endpoint
            host.AddServiceEndpoint(typeof(MyCalculatorService.ISimpleCalculator)
            , new WSHttpBinding(), "");
            //Enable metadata exchange
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            host.Description.Behaviors.Add(smb);
            //Start the Service
            host.Open();

            Console.WriteLine("Service is host at " + DateTime.Now.ToString());
            Console.WriteLine("Host is running... Press <Enter> key to stop");
            Console.ReadLine();

        }
    }
}
Step 8: Service is hosted, now we need to implement the proxy class for the client. There are different ways of creating the proxy
  • Using SvcUtil.exe, we can create the proxy class and configuration file with end points.
  • Adding Service reference to the client application.
  • Implementing ClientBase<T> class
Of these three methods, Implementing ClientBase<T> is the best practice. If you are using rest two method, we need to create proxy class every time when we make changes in Service implementation. But this is not the case for ClientBase<T>. It will create the proxy only at runtime and so it will take care of everything.
MyCalculatorServiceProxy.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using MyCalculatorService;
namespace MyCalculatorServiceProxy
{
    public class MyCalculatorServiceProxy : 
        //WCF create proxy for ISimpleCalculator using ClientBase
        ClientBase<ISimpleCalculator>,
        ISimpleCalculator
    {
        public int Add(int num1, int num2)
        {
            //Call base to do funtion
            return base.Channel.Add(num1, num2);
        }
    }
}
Step 9: In the client side, we can create the instance for the proxy class and call the method as shown below. Add proxy assembly as reference to the project.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace MyCalculatorServiceClient
{
    class Program
    {
        static void Main(string[] args)
        {
            MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy ;
            proxy= new MyCalculatorServiceProxy.MyCalculatorServiceProxy();
            Console.WriteLine("Client is running at " + DateTime.Now.ToString());
            Console.WriteLine("Sum of two numbers... 5+5 ="+proxy.Add(5,5));
            Console.ReadLine();
        }
    }
}
Step 10 : End point (same as service) information should be added to the configuration file of the client application.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint address ="http://localhost:8090/MyService/SimpleCalculator" 
                binding ="wsHttpBinding"
                contract ="MyCalculatorService.ISimpleCalculator">
        
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>
Step 11: Before running the client application, you need to run the service. Output of the client application is shown below.
This self host shows advantage such as in-Pro hosting, programmatic access and it can be used when there need singleton service. I hope you have enjoyed the Self hosting session, now let go for hosting using Windows Activation service.

WCF Service with custom username password authentication

Tools used

  1. Pluralsight Self-Cert Tool. This tool is provided by Pluralsight to create and install certificates.
  2. WinHttpCertCfg.exe. Windows HTTP Services Certificate Configuration Tool is a command line tool to grant specific users read right access on a certificate's private key file.
  3. Environment: Visual Studio 2010, and IIS7 or above.

Contents

  1. Introduction
  2. Creating the service
  3. Configuring the service
  4. Configuring IIS and publishing the website
  5. Installing the server side certificate
  6. Setting up the client

Introduction

Windows Communication Foundation comes with a rich set of security features such as transport level message and transport with message; each security type has its own advantages and overheads as well. My application has lots of diverse clients used to connect with the service, and they have to be authenticated from the database, so the best possible solution is message level security using custom username - password authentication. After digging in to the net, I found pieces of information, and with some effort, I implemented a concrete solution which I am hoping is helpful for others.

Creating the service

The solution is created using VS2010, and contains three projects: the WCF Service, the website, and the desktop application which is the client application.
The WCF Service just contains a function GetServertime():
[ServiceContract]
public interface IService1
{
    [OperationContract]
    string GetServertime();
}

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Service1 : IService1
{  
    public string GetServertime()
    {
        return DateTime.Now.ToString();
    }   
}
We create a class and name it UserNamePassValidator. We the implement this code in it:
using System;
using System.ServiceModel;

namespace CustomUsernamePasswordAuth.Service
{
    class UserNamePassValidator : 
          System.IdentityModel.Selectors.UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if(  userName==null ||  password==null)
            {
                throw new ArgumentNullException();
            }

            if (!(userName == "fayaz" && password == "soomro") )
            {
                throw new FaultException("Incorrect Username or Password");
            }
        }
    }
}
This class must be derived from System.IdentityModel.Selectors.UserNamePasswordValidator and override the Validate method. And to validate the user, use any data source; in this example, we will use a hard coded value.

Creating the web application

Add a reference to the service in the web application. Add a text file and rename it to UserNamePassService.svc, and add the following line of code:
<%@ ServiceHost Language="C#" Debug="true" 
    Service="CustomUsernamePasswordAuth.Service.Service1" %>

Configuring the Web Service

Modify the web.config and add following lines in it.
Add a service behavior and name it Behavior1. Enable the service meta data by adding <serviceMetadata httpGetEnabled="true"/> so that when we add a service reference into the client application, it fetched the information and creates the proxy classes for us. And the essential part is the service certificate. Certificate creation will be covered in a later section, but now, we have to remember the certificate settings. FindValye="MyWebSite" will be the subject for the certificate CN=MyWebSite, and you can change this value to your domain name or project name.
Set the usernamepasswordvalidation mode to custom, and customUsernameapsswordValidator has to be specify the custom validation class and namespace.
<system.serviceModel>        
    <behaviors>
        <serviceBehaviors>
            <behavior name="Behavior1">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceCredentials> 
                    <serviceCertificate findValue="MyWebSite" 
                          storeLocation="LocalMachine"
                          storeName="My" 
                          x509FindType="FindBySubjectName" />
                    <userNameAuthentication userNamePasswordValidationMode="Custom"
                     customUserNamePasswordValidatorType="CustomUsernamePasswordAuth.
                        Service.UserNamePassValidator, CustomUsernamePasswordAuth.Service" />
                </serviceCredentials>
            </behavior>             
        </serviceBehaviors>
    </behaviors>
Set up the binding configuration as shown below. Name it Binding1 and set the security mode as Message and clientCredentialType as "username".
<bindings>
    <wsHttpBinding>
        <binding name="Binding1">
            <security mode="Message">
                <message clientCredentialType="UserName"/>
            </security>
        </binding>
    </wsHttpBinding>
</bindings>
Now we will set up the service endpoint. There are two endpoints: wsHttp endpoint, and Mex end point for metadata exchange. The base address is http://localhost/. The fully qualified service address will be http://localhost/UserNamePassService.svc.
<services>
    <service behaviorConfiguration="Behavior1" 
              name="CustomUsernamePasswordAuth.Service.Service1">
    <endpoint address="" binding="wsHttpBinding"    
              bindingConfiguration="Binding1"
              contract="CustomUsernamePasswordAuth.Service.IService1" />
     <endpoint address="mex" binding="mexHttpBinding" 
        contract="IMetadataExchange" />
            <host>
                <baseAddresses>
                    <add baseAddress="http://localhost/" />
                </baseAddresses>
            </host>
        </service>
    </services>         
</system.serviceModel>
Note: if the website is going to be hosted on a specific port in IIS, as in this example, we have hosted the website in IIS on port 83, http://localhost:83/UserNamePassService.svc, we don't need to change the port in the configuration file and leave the baseAddress as "http://localhost/".

Creating the site in IIS 7

Open IIS Manager. Right click Sites and Add Website. Name it as WebSite, set Application pool to DeafaultAppPool, and select the physical path and set port to 83. As shown below:

Set the DefaultAppPool Framework version to 4.0.


Publish Site to IIS

Right click the website project in Solution Explorer and publish it. Select Publish method as File system, and Target location as http://localhost:83, as shown in the figure below:

Browse the site. Open Internet Explorer and type http://localhost:83/UserNamePassService.svc. You will see the error that X.509 could not be found.

Installing the certificate

Download the Pluralsight SelfCert from the link given at the beginning of the article. Run the tool as Administrator; otherwise, it will crash.
Configure the settings to install the certificate; refer the screen below.


After making the required changes, click the Save button and then you will see the screen below:

After the installation of the certificate, browse the site again, but this time, you should see a different error as shown in the screen below:

This error means that the default application pool does not have access rights to the certificate's private key, so now, we have to give read access to the default application pool to do this.
Download WinHttpCertCfg.exe from the link given at the beginning of the article. This tool is a command line tool. After installing the tool, run the following command on the command prompt as Administrator.
C:\Program Files (x86)\Windows Resource Kits\Tools>winhttpcertcfg 
             -g -c LOCAL_MACHINE\My -s MyWebSite -a DefaultAppPool
After running the command, you will see the screen like this:


Now browse the site again. And verify the service, it should be up.

The final step is to create a client to consume the service

The client application is the desktop application, and just contains the address textbox and the button to get the server time.

Now add the service reference to the project:

Add the code to the Button_click event:
private void button1_Click(object sender, EventArgs e)
{
    string time = "";
    // Method 1: Create the client using the configuration file

    Service1Client c = new Service1Client();
    c.ClientCredentials.UserName.UserName = "fayaz";
    c.ClientCredentials.UserName.Password = "soomro";
    c.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = 
                        X509CertificateValidationMode.None;
    time = c.GetServertime();
    MessageBox.Show(time);

    // Method 2: Creating the client by creating endpoint and binding through coding
    var ServiceendPoint = new EndpointAddress(new Uri(txtServiceAddress.Text), 
                          EndpointIdentity.CreateDnsIdentity("MyWebSite"));
    var binding = new WSHttpBinding();
    binding.Security.Mode = SecurityMode.Message;
    binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

    var result = new Service1Client(binding, ServiceendPoint);
    result.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = 
                             X509CertificateValidationMode.None;            
    result.ClientCredentials.UserName.UserName = "fayaz";            
    result.ClientCredentials.UserName.Password = "soomro";
    time = result.GetServertime();
    MessageBox.Show(time);
}
Run the application:

Running the client from another PC to make sure everything works fine:

Conclusion

I 'm sure this project will be useful for developers who want to implement custom security. I tried my best to describe each step with a screenshot. I hope you've enjoyed this article. If you like this article, please let me know :). If you have any questions, please feel free to contact me at fayaziiui@gmail.com

Wednesday, December 26, 2012

deploy user controls and web parts in powershell

Deploy user control (it is deployed globally and not associated with any application)
In sharepoint project, make sure the first line in the user control aspx, <%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>,  has been replace with the real assembly name (<%@ Assembly Name="MapArea, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bf461b57440b5559" %>) in stead of a reference to the proj file.

uninstall-spsolution -identity MapArea.wsp    (remove folder in \14\template\controltemplates)
remove-spsolution -identity MapArea.wsp     (remove dll from gac)

gacutil /i MapArea.dll
copy \Maparea\map.aspx to C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\CONTROLTEMPLATES\MapArea (folder varies depending on what folder you want to deploy to)

add-spsolution -literalpath C:\Installs\webparts\Liheap\MapArea\bin\Debug\MapArea.wsp
Install-SPSolution -Identity MapArea.wsp -GACDeployment

Deploy a web part (this needs to be deployed to a particular web application)




http://yourwebapplication
stsadm -o addsolution -filename C:\Installs\IndividualZips\SectorPoint.Products.AdRotator.wsp
stsadm -o deploysolution -name SectorPoint.Products.AdRotator.wsp -allowCas -local -url http://yourwebapplication

use this command to get the solutions:

GET-SPSOLUTION


to retract a solution:

uninstall-spsolution -identity SectorPoint.Products.AdRotator.wsp -webapplication http://devwebsites.com.wa.lcl


to remove a solution from farm:

remove-spsolution -identity SectorPoint.Products.AdRotator.wsp


to add solution to the sharepoint solution store:
add-spsolution -literalpath C:\Installs\IndividualZips\SectorPoint.Products.AdRotator.wsp

To Deploy the solution.

Install-SPSolution -Identity SectorPoint.Products.AdRotator.wsp -WebApplication http://devwebsites.com.wa.lcl -CASPolicies
-------------------------------------------------------------------
uninstall-spsolution -identity CommerceTreeViewNavigation.wsp -webapplication http://yourwebapplication

remove-spsolution -identity CommerceTreeViewNavigation.wsp

add-spsolution -literalpath C:\Installs\IndividualZips\CommerceTreeViewNavigation.wsp

Install-SPSolution -Identity CommerceTreeViewNavigation.wsp -WebApplication http://yourwebapplicationt
--------------------------------------------------------------------------------------------



add-spsolution -literalpath C:\Installs\IndividualZips\SectorPoint.Products.AdRotator.wsp
http://yourwebapplicationt

Install-SPSolution -Identity CommerceTreeViewNavigation.wsp -WebApplication http://yourwebapplication -GACDeployment