SendEmailFromTemplate Message

ends an e-mail message using a template.



//# The following code example shows how to use the SendEmailFromTemplate message.

// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
// You can use enums.cs from the SDK\Helpers folder to get the enumeration for Active Directory authentication.
token.AuthenticationType = 0;
token.OrganizationName = "AdventureWorksCycle";

CrmService service = new CrmService();
service.Url = "http://:/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Create the 'From:' activity party for the e-mail.
activityparty fromParty = new activityparty();
fromParty.partyid = new Lookup();
fromParty.partyid.type = EntityName.systemuser.ToString();
fromParty.partyid.Value = new Guid("7E91958D-C8A1-404C-AC2C-9C474FB2427B");

// Create the 'To:' activity party for the e-mail.
activityparty toParty = new activityparty();
toParty.partyid = new Lookup();
toParty.partyid.type = EntityName.contact.ToString();
toParty.partyid.Value = new Guid("44E05740-607B-47AA-ABD6-13A007E2DD85");

// Create an e-mail message.
email email = new email();

// Set e-mail properties.
email.to = new activityparty[] { toParty };
email.from = new activityparty[] { fromParty };
email.subject = "SDK Sample email";
email.description = "SDK Sample for SendEmailFromTemplate Message.";

CrmBoolean direction = new CrmBoolean();
direction.Value = true;
email.directioncode = direction;

TargetSendFromTemplateEmail emailTemplateTarget = new TargetSendFromTemplateEmail();
emailTemplateTarget.Email = email;

SendEmailFromTemplateRequest emailRequest = new SendEmailFromTemplateRequest();
emailRequest.Target = emailTemplateTarget;

// The regarding ID is required and must be of the same type as the e-mail template.
emailRequest.RegardingId = new Guid("105BE43F-5911-DD11-9778-0003FFBDD2C7");
emailRequest.RegardingType = EntityName.contact.ToString();

// Use a built-in email template of type "contact".
emailRequest.TemplateId = new Guid("7816B01C-EFA8-4396-8BA5-0B6B72DA5C08");

SendEmailFromTemplateResponse emailResponse = (SendEmailFromTemplateResponse)service.Execute(emailRequest);





get/set lookup value in CRM 4

 
/* Jscript */


// get lookup
gLookupGetValue = function (objLookup){
/*
This function is used read a value from lookup field
This function requires the following parameters:
objLookup: reference to the lookup object e.g. crmForm.all.productid
Returns: Array
[0] = returns lookup GUID
[1] = returns lookup text value
[2] = returns lookup entity type name (e.g. account)
[3] =//returns lookup entity type code (e.g. 1=account), 2=contact, etc)
Example:
var name = gLookupGetValue(crmForm.all.accountid)[1]
Author: GP
*/

var lookupItem = new Array;
var arr = new Array();
arr[0] = ""; //returns lookup GUID
arr[1] = ""; //returns lookup text value
arr[2] = ""; //returns lookup entity type name (e.g. account)
arr[3] = ""; //returns lookup entity type code (e.g. 1=account), 2=contact, etc)
// Get a reference to the lookup control on the form.
lookupItem = objLookup.DataValue;

// If there is data in the field, show it in a series of alerts.
if (lookupItem != null){
// Return the GUID of the lookup.
arr[0] = lookupItem[0].id;
// Return the text value of the lookup.
arr[1] = lookupItem[0].name;

// Return the entity type name of the lookup.
arr[2] = lookupItem[0].typename;

// Return the entity type code of the lookup.
arr[3] = lookupItem[0].type;
}
return arr;
}
// set lookup
gLookupSetValue= function(objID, objText, objType){
/*
This function is used set a defaultvalue in a lookup field and requires the following parameters:
objID: ID of the record
objText: Text or Name of the record
objType: Entity code or Entity Name
Returns: lookup object
Designed by: Geron Profet
Example 1: retrieve based on entity type code
var defaultpricelevelname = 'Standard';
var defaultpricelevelid = gGetValue('pricelevelid','pricelevel','name',defaultpricelevelname)[2];
crmForm.all.pricelevelid.DataValue = gLookupSetValue(defaultpricelevelid, defaultpricelevelname, 1022);

Example 2: retrieve based on entity type name
crmForm.all.pricelevelid.DataValue = gLookupSetValue(defaultpricelevelid, defaultpricelevelname, 'pricelevel');
*/

// Create a lookupItem to store the values that you want to set to a target lookup control.
var lookupData = new Array();
var lookupItem= new Object();

//Set the id, name and typecode or typename properties to the object.
lookupItem.id = objID;
lookupItem.name = objText;

//if objType is not numeric, assume the entitytypename is passed
if (!isNaN(objType)){
lookupItem.type = objType;
} else {
lookupItem.typename = objType;
}

// Add the object to the array and return the lookupItem that you just created.
lookupData[0] = lookupItem;
return lookupData;
}


Application Development in Microsoft Dynamics CRM 4.0

Summary

  • ASP.NET applications on the Microsoft Dynamics CRM 4.0 server 
  • ASP.NET applications for Microsoft Dynamics CRM 4.0 for Microsoft Office Outlook with Offline Access 
  • Plug-ins 
  • Custom workflow activities 
  • Scripting 
  • Setup and deployment 
  • Application configuration

Applies To

Microsoft Dynamics CRM 4.0

Microsoft Visual Studio 2005

Introduction

Both Microsoft Visual Studio 2005 and Microsoft Visual Studio 2008 serve as excellent platforms for application development for Microsoft Dynamics CRM. It is easiest to use a single Visual Studio solution to contain the projects that you create during your development cycle. It's important to understand the four fundamental kinds of projects that you can create:

  • .NET applications that connect to Microsoft Dynamics CRM: These applications may be of any type as long as they can use SOAP Web services. Example types include Windows Forms, WPF Forms, console applications, Windows Services, and so on. You can use this kind of application for alternative UIs, tools, and application integration. 
  • ASP.NET applications that run 'inside' Microsoft Dynamics CRM: These Web applications run in the context of Microsoft Dynamics CRM itself. They must be coded, built, and deployed within specific boundaries. You can typically frame these applications within Microsoft Dynamics CRM as a pop-up window, IFRAME, or menu navigation. 
  • Plug-In/Workflow Assemblies: The classes in these DLLs are derived from Microsoft Dynamics CRM SDK classes or Microsoft Windows Workflow Foundation classes. The DLLs are then registered inside Microsoft Dynamics CRM to be executed at specific times. You can use these to run your complex business logic and to orchestrate complex integrations. 
  • Setup: You may want to create a setup project to deploy your projects to the Microsoft Dynamics CRM server and client computers.

Creating your Development Environment

When you set up your Microsoft Dynamics CRM development environment you have two choices to make: networked or stand-alone. If you use the networked approach you can set up a Microsoft Dynamics CRM server on your actual network by using physical or virtual computers. The stand-alone option is typically vertical using a "one-box" deployment.

For the networked approach you should follow the steps in the Microsoft Dynamics CRM 4.0 Implementation Guide. It's highly suggested that you configure the box for both regular Windows and Internet-facing deployment (IFD) authentication modes. Creating your own virtual one-box deployment might seem a bit difficult at first, but I assure you it is easy and doesn't take very long. This checklist will help you get started. Note that the order of doing this is important. You should read the Implementation Guide before you begin this process.

Creating a one-box deployment

  • Hardware. At the moment, I use a Windows Vista Enterprise 64-bit on a Lenovo T60P with 4 GB of RAM. Some of my colleagues have also had success using USB sticks for ReadyBoost to increase the RAM. I put the VHD on the laptop's SATA drive. If you do use external drives, make sure that they are faster than the internal drive. 
  • I use Virtual PC for virtualization. Virtual Server is also a good option. 
  • The next step is to build out Windows Server Virtual Machine. Try to avoid pre-built VPCs as they tend to be loaded up with extraneous components. 
  • Do not join this computer to your domain. For now, keep it connected to a Workgroup.
  • Hook your computer up to the Internet and run Windows Update. 
  • Now configure the VPC to use the Loopback Adapter. You might first have to install the Loopback Adapter on the host operating system (for example, Vista). Here is a screencast on how to do this: Configuring the Loopback Adapter
  • Change the IP address of the server to 192.168.1.1. 
  • Change the IP address of the host operating system to 192.168.1.2. Use 192.168.1.1 as the DNS Server. 
  • Next, make sure that the server is connected to this private loopback network. Now nothing from the outside except the host operating system can reach the server. This is a safety precaution
  • Install Active Directory® on the server. For those who haven't done this in a while: type dcpromo at the command prompt. Make sure to remember the restore password. 
  • Now install Internet Information Services (IIS). 
  • Microsoft SQL Server® is next. Use Remote Desktop to connect to the server (at 192.168.1.1). You might want to use the IP instead of the server name because you may get netbios conflicts if your host server is also connected to another network. Install SQL Server and make sure that you install SQL Server Reporting Services. For your development computer, I also suggest you use mixed-mode SQL authentication. However, you should always avoid this in a production environment (for the usual reasons). 
  • Now install Visual Studio on the server. You may want it later for debugging. 
  • You may want to create a config file to make your server run in IFD mode. For more information, see the Microsoft Dynamics CRM 4.0 Implementation Guide.

· <CRMSetup>

· <Server>

· <ifdsettings enabled="true">

· <internalnetworkaddress>192.168.1.1-255.255.255.255</internalnetworkaddress>

· <rootdomainscheme>http</rootdomainscheme>

· <sdkrootdomain>crm.philiprichardson.org</sdkrootdomain>

· <webapplicationrootdomain>crm.philiprichardson.org</webapplicationrootdomain>

· </ifdsettings>

· </Server>

· </CRMSetup>

  • Copy all the Microsoft Dynamics CRM files to the server. The DVD is a good option here as it contains all the prerequisites (such as Microsoft Visual C++®). 
  • To start the installer, open the command prompt and navigate to the server folder. Assuming that your config file is called ifd.xml, you can type the following:

· setupserver.exe /config ifd.xml

  • Here is a screencast showing the installation experience: Installing CRM
  • Now Microsoft Dynamics CRM is ready to use. Restart the computer and make sure everything is working. 
  • Create some user accounts in the Active Directory of the server.
  • Shut down the VPC and make the VHD file read-only. This is now your "base image."
  • Now create a new Virtual Hard Drive with the type set to "Differencing". Parent this to the base image. This might sound a bit confusing at first. Try it out and read the VPC help files if you are unsure. 
  • Note that to access Microsoft Dynamics CRM by using IFD from the host operating system, you also have to add the IFD URL to your hosts file (C:\windows\system32\drivers\…). Map 192.168.1.1 to orgname.crm.philiprichardson.org, substituting the name of your deployment. Also note that you need the orgname in this mapping. Each time you create a new organization you need to add this to the host operating system's hosts file. 
  • Undo disks are also a good option on the Differencing VPC. Then, you can revert changes without creating a new VHD. 
  • Back up everything.

Now you have your environment ready to go and you can easily rebuild it if necessary.

Switching Between IFD and Windows

If you configured your development environment as described previously, you will notice that if you log on to the server using the IP address (192.168.1.1) or the Host file configured URL (such as http://contoso.crm.philiprichardson.org), you will be prompted for Windows Credentials.

I use a registry key on the Microsoft Dynamics CRM Server to change the internal subnet of the IFD setting. Microsoft Dynamics CRM looks at the IP address of the incoming request and, if this is in the internal range of the registry key, it gives you a "Windows experience." If the IP address is external, it gives you an "IFD experience."

For example, if the client is configured with an IP address of 192.168.1.2 (Subnet: 255.255.255.0):

  • When the internal range is 192.168.1.1-255.255.255.0 you will get a Windows experience. This is the value that you provided in the config.xml file when you installed Microsoft Dynamics CRM.
  • When the internal range is 192.168.1.1-255.255.255.255 you will get an IFD experience. This is because the client on the host operating system has an IP of 192.168.1.2 (Subnet: 255.255.255.0), which is outside the internal range.

Here are the two registry key modifications. Note that this is supported. For more information, see the Implementation Guide.

IFD Experience:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM]

"IfdInternalNetworkAddress"="192.168.1.1-255.255.255.255"

Windows Experience:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM]

"IfdInternalNetworkAddress"="192.168.1.1-255.255.255.0"

If you have your own network configuration, you will have to determine the network addresses and subnet masks on your own. I strongly suggest you read the Implementation Guide and the IFD Setup documentation. If your environment is located on your network, you may want to contact your network administrator to figure out the correct IP ranges.

Applications that Connect to Microsoft Dynamics CRM

Connecting to Microsoft Dynamics CRM 4.0 uses one of two methods: SQL and Web services. Both are valid techniques but they do not provide the same functionality.

SQL

This approach involves making a regular SQL connection (with a technology like ADO.NET, for example) and executing SQL statements. Microsoft Dynamics CRM 4.0 has a set of special SQL views that we call the Filtered Views. Each entity in Microsoft Dynamics CRM has a corresponding filtered view. For example, the Contact entity has a view called FilteredContact. These views join together all the information for this entity and they also link to the security tables that contain the row level security information. This means that if a user has access to, for example, only 15432 contacts out of 3 million in the database, when that user does a SELECT * FROM dbo.FilteredContact they will only see 15432 rows. The filtered views can only be used for retrieving data. You should never change the database data or schema by using SQL with Microsoft Dynamics CRM. The Microsoft Dynamics CRM middle tier must handle all data and schema transactions. Never make changes directly to the database. Reporting is the main scenario for using filtered views. You can use these views to generate most of your analysis and reporting for Microsoft Dynamics CRM 4.0. You might also use them with ADO.NET (or similar technologies) when you write applications. Please be aware that the views can be locked down by system administrators. My advice: only use the filtered views for analytical applications.

Web Services

Using Web services is the standard way to connect to Microsoft Dynamics CRM and manipulate the data and schema of the system. Many assumptions you might have made with Microsoft Dynamics CRM 3.0, which is single tenant, must be reconsidered. Our Web service is a SOAP service, which we feel is a great fit for a complex business system such as Microsoft Dynamics CRM. There are three Web services that you should consider in your application architecture:

CrmDiscoveryService: You can use this service to "discover" information about tenants (organizations) on a server (deployment). In some modes it will also issue security tickets.

CrmService: This is the "main" Web service. It handles the manipulation of an organization's transactional data.

MetadataService: This service handles the manipulation of an organization's metadata (schema).

Authentication

Understanding authentication plays a role in how you connect to Microsoft Dynamics CRM. There are four ways to perform authentication and not all are available to every deployment.

Integrated Authentication

Use integrated authentication within your firewall, where Integrated Windows Authentication works best.

Connect to the Discovery Service and get the organization details by using System.Net.CredentialCache.DefaultCredentials.

Create a CrmService by using the information from the organization details.

Conduct transactions through the CrmService using System.Net.CredentialCache.DefaultCredentials.

Internet-Facing Deployment

Internet-facing deployment (IFD) uses Active Directory at the back end but the credentials are collected using a Forms Authentication approach. Microsoft Dynamics CRM 4.0 (the on-premise version) uses Active Directory as the Identity store. Microsoft Dynamics CRM Online uses Windows Live ID.

Make an anonymous request to the Discovery Service to obtain the Microsoft Dynamics CRM Online Windows Live ID Policy.

Connect to Windows Live ID and supply the Policy, Windows Live ID UserName/Password. It will give you back a Windows Live ID Ticket.

Connect to the Discovery Service and get the organization details by using the Windows Live ID Ticket.

Create a CRM Ticket by using the Discovery Service and the Windows Live ID Ticket. A CRM Ticket is organization-specific.

Create a CrmService by using the CRM Ticket and organization details.

Conduct transactions by using the CrmService. The CRM Ticket will be passed in the SOAP header. It will authenticate you for a period of time (tickets do time out) against a specific organization.

The Microsoft Dynamics CRM SDK contains samples for each authentication pattern. To create applications that connect to Microsoft Dynamics CRM you need to understand the following concepts:

Where do I find the deployment? This really means: What is the URL for the Discovery service? There is only one Discovery service URL for Microsoft Dynamics CRM Online.

What organization do I want to connect to? Some applications always know this. Other applications may want to query the Discovery service for a list of all organizations that a user has access to, and then have the user select which organization to connect to. You have to create the UI for this.

What type of Authentication is being used? Integrated, Windows, IFD, or Windows Live ID. Maybe your applications will support some of these authentication types. If so, remember that you are responsible for the UI, so help out your users when connecting. Our Microsoft Dynamics CRM for Microsoft Office Outlook application is a good example of one these kinds of applications. It's worth looking at how we solved these UI problems and see what works or doesn't work in your application.

You have a choice of using our compiled type proxy or the Web Services Description Language (WSDL) when connecting to Microsoft Dynamics CRM. Note that there is not a type proxy for the Discovery service. However, the WSDL is the same for Windows, IFD, and Windows Live ID.

ASP.NET Applications on the Microsoft Dynamics CRM Server

In Microsoft Dynamics CRM 3.0, if you wanted to run an ASP.NET application on the same server as Microsoft Dynamics CRM you needed to use your own application pool. This application would then connect to Microsoft Dynamics CRM like an external application if it needed to read and write data in Microsoft Dynamics CRM. For credentials, these applications would simply use Integrated Windows Authentication because a majority of customers used this configuration.

With the introduction of Internet-facing deployment (IFD), which uses Forms Authentication for Active Directory credentials, you cannot rely on Integrated Windows Authentication for your application. It's important to recognize that all partner-hosted customers will use IFD and most on-premise customers will configure their systems to use IFD plus Windows Authentication. Developers should always consider IFD as a primary usage pattern for their applications.

Because IFD uses a Forms Authentication technology to collect Active Directory credentials, your own applications are faced with a problem. You can't use Integrated Windows Authentication because your application might be running outside the firewall where this authentication type becomes very "fragile," and you don't want to have to prompt the user for credentials. For this situation we have provided a special class in the Microsoft.Crm.Sdk.dll called CrmImpersonator. This class enables an application, which runs inside our context, to use the credentials of the logged on user.

The following ASP.NET code example shows how to create a new lead and display the GUID of the record it created. The aspx and aspx.cs files should be placed on the Microsoft Dynamics CRM server in a folder that is named ISV. The Microsoft.Crm.Sdk and Microsoft.Crm.SdkTypeProxy namespaces derive from two DLLs of the same name. These DLLs are always present with Microsoft Dynamics CRM so that you don't have to package them with your solution. However, you may want to reference them in your project. You can find the DLLs in the \Server\GAC folder of your installation files or in the SDK download.



using System;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Net;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Retrieve the organization name from the query string.
string orgname = Request.QueryString["orgname"].ToString();

//Wrap the CRM Web Service Code in a using block.
using (new CrmImpersonator())
{
//Create a token with the static method. ExtractCrmAuthenticationToken
//The 'Context' used here is the Page.Context.
CrmAuthenticationToken token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(Context, orgname);

CrmService service = new CrmService();
service.CrmAuthenticationTokenValue = token;
service.Credentials = CredentialCache.DefaultCredentials;

//Create the lead object as usual.
lead lead = new lead();
lead.subject = "Lorem";
lead.firstname = "John";
lead.lastname = "Smith";
lead.companyname = "Ipsum";

//Assign the owner as the caller ID from the token.
//If you don't do this, the owner will be SYSTEM.
lead.ownerid = new Owner();
lead.ownerid.type = EntityName.systemuser;
lead.ownerid.Value = token.CallerId;

//Create the lead on Skype.
Guid leadid = service.Create(lead);
}

//Display the GUID.
Response.Write(leadid.ToString());
}
}




Let's examine the anatomy of this code pattern:


  • You need to possess some prerequisites such as Page.Context, organization name, and if you are using the Metadata Service, the MetadataService URL.
  • The CrmAuthenticationToken was created using the static ExtractCrmAuthenticationToken method of the CrmAuthenticationToken class. 
  • You do not have to use the Discovery Service. This code can only access the Microsoft Dynamics CRM Server that the code is running on.
  • You must manually set the owner of new records using the CallerId property of CrmAuthenticationToken. (See the previous code sample.)

ASP.NET Applications on the Microsoft Dynamics CRM Offline Client

Microsoft Dynamics CRM 4.0 enables you to write an ASP.NET application and put it on the offline client's Web server. This application can call the offline Web service platform to perform operations against Microsoft Dynamics CRM. These files are deployed in the [Program Files]\Microsoft Dynamics CRM\Client\res\Web\ISV\[Company Name]\[Application Name]. Typically you can use Windows Installer to distribute these files to clients.

When you execute your code offline there are several things that you need to know:

The organization name. You get this from the Registry.

The port number used by the local Web server. Typically, this is 2525.However, you should always check the registry in case there is an abnormal installation.

The service URLs. You can construct these by concatenating http://localhost + Port Number + the service path.

You always use Integrated Windows Authentication to access the offline Web services, regardless of the authentication type on the server (including Microsoft Dynamics CRM Online). You also don't have to wrap your code with a CrmImpersonator block. However if you do so, there is no harm. If you write symmetrical code for online/offline, make sure that you don't create the token using the ExtractCrmAuthenticationToken method because this is not available offline. You may want to check to see if the code is executing offline. One way to do this is to see if the Request.Url.Host is 127.0.0.1.

The following sample shows how this can easily be achieved.

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Win32;
using System.Text;
using System.Net;

public partial class Hello : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Retrieve the port and orgname from the Registry.
RegistryKey regkey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\MSCRMClient");
string orgname = regkey.GetValue("ClientAuthOrganizationName").ToString();
string portnumber = regkey.GetValue("CassiniPort").ToString();
//Construct the URLs.
StringBuilder urlbuilder = new StringBuilder();
urlbuilder.Append("http://localhost:");
urlbuilder.Append(portnumber);
urlbuilder.Append("/mscrmservices/2007/");
string crmserviceurl = urlbuilder.ToString() + "crmservice.asmx";

//Create your token as usual.
//Offline always uses Integrated Windows Authentication regardless of the Authentication on the server.
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.OrganizationName = orgname;
token.AuthenticationType = 0;

CrmService service = new CrmService();
service.CrmAuthenticationTokenValue = token;
service.Credentials = CredentialCache.DefaultCredentials;
service.Url = crmserviceurl;

WhoAmIRequest request = new WhoAmIRequest();
WhoAmIResponse response = (WhoAmIResponse)service.Execute(request);

Response.Write(response.UserId.ToString());
}
}





Reschedule Message

Reschedules an appointment.



//# The following code example shows how to use the Reschedule message.

// Set up the CRM service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
// You can use enums.cs from the SDK\Helpers folder to get the enumeration for Active Directory authentication.
token.AuthenticationType = 0;
token.OrganizationName = "AdventureWorksCycle";

CrmService service = new CrmService();
service.Url = "http://:/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Create the target.
TargetScheduleAppointment target = new TargetScheduleAppointment();
target.Appointment = retrieved;

// Create the request object.
RescheduleRequest reschedule = new RescheduleRequest();

// Set the properties of the request object.
reschedule.Target = target;

// Execute the request.
RescheduleResponse rescheduled = (RescheduleResponse)service.Execute(reschedule);




WCF: Introduction to WCF


Introduction to WCF
Windows Communication Foundation (Code named Indigo) is a programming platform and runtime system for building, configuring and deploying network-distributed services. It is the latest service oriented technology; Interoperability is the fundamental characteristics of WCF. It is unified programming model provided in .Net Framework 3.0. WCF is a combined features of Web Service, Remoting, MSMQ and COM+. WCF provides a common platform for all .NET communication.
Below figures shows the different technology combined to form WCF.
Advantage
  1. WCF is interoperable with other services when compared to .Net Remoting,where the client and service have to be .Net.
  2. WCF services provide better reliability and security in compared to ASMX web services.
  3. In WCF, there is no need to make much change in code for implementing the security model and changing the binding. Small changes in the configuration will make your requirements.
  4. WCF has integrated logging mechanism, changing the configuration file settings will provide this functionality. In other technology developer has to write the code.

Development Tools

WCF application can be developed by the Microsoft Visual Studio. Visual studio is available at different edition. You can use Visual Studio 2008 Expression edition for the development.
Visual Studio 2008 SDK 1.1

Microsoft Visual Studio 2008

Microsoft Visual studio 2008 provides new features for WCF compared to Visual Studio 2005. These are the new features added to VS 2008.

1.     Multi-targeting

You can create application in different framework like Framework 2.0, 3.0 and 3.5

2.     Default template is available for WCF

3.     WCF - Test Client tools for testing the WCF service.

Microsoft provides inbuilt application to test the WCF application. This can be done by opening the Visual Studio command prompt and type the wcfClient Serviceurl shows below. This will help the developer to test the service before creating the client application.
4.      WCF services can be debugged now in Visual Studio 2008. Wcfsvchost.exe will do it for you because service will be self hosted when you start debugging.

Difference between WCF and Web service

Web service is a part of WCF. WCF offers much more flexibility and portability to develop a service when comparing to web service. Still we are having more advantages over Web service, following table provides detailed difference between them.
Features
Web Service
WCF
Hosting
It can be hosted in IIS
It can be hosted in IIS, windows activation service, Self-hosting, Windows service
Programming
[WebService] attribute has to be added to the class
[ServiceContraact] attribute has to be added to the class
Model
[WebMethod] attribute represents the method exposed to client
[OperationContract] attribute represents the method exposed to client
Operation
One-way, Request- Response are the different operations supported in web service
One-Way, Request-Response, Duplex are different type of operations supported in WCF
XML
System.Xml.serialization name space is used for serialization
System.Runtime.Serialization namespace is used for serialization
Encoding
XML 1.0, MTOM(Message Transmission Optimization Mechanism), DIME, Custom
XML 1.0, MTOM, Binary, Custom
Transports
Can be accessed through HTTP, TCP, Custom
Can be accessed through HTTP, TCP, Named pipes, MSMQ,P2P, Custom
Protocols
Security
Security, Reliable messaging, Transactions

SetRelated Message

Creates a relationship between two entity instances as defined by the target classes listed below. For example, an account can be related to a lead.


//#The following code example shows how to use the SetRelated message.

// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
// You can use enums.cs from the SDK\Helpers folder to get the enumeration for Active Directory authentication.
token.AuthenticationType = 0;
token.OrganizationName = "AdventureWorksCycle";

CrmService service = new CrmService();
service.Url = "http://:/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Create the target object for the request.
TargetRelatedLeadToAccount target = new TargetRelatedLeadToAccount();

// AccountId is the GUID of the account to be related to the lead.
target.AccountId = new Guid("D3652E9C-D328-4CA1-B284-1215C441AD94");

// LeadId is the GUID of the lead to be related to the account.
target.LeadId = new Guid("9DAEE309-A3D6-470C-80E2-DDC657BAFC16");

// Create the request object.
SetRelatedRequest setRelated = new SetRelatedRequest();

// Set the properties of the request object.
setRelated.Target = target;

// Execute the request.
SetRelatedResponse related = (SetRelatedResponse)service.Execute(setRelated);




Downloading and playing of a video

import appuifw, e32 
# import urllib import urllib  print "press options"  
# function that handles the fetching and the playing of the video def fetching():     
# define the url where the video file is located on the server     
url = "http://www.leninsgodson.com/courses/pys60/resources/vid001.3gp"     
# define the loction on the phone where the fetched video file shall be stored     
tempfile = "e:\\video01.3gp"     
try:         
print "Retrieving information..."         
# fetch down the video and store it to you hard drive         
urllib.urlretrieve(url, tempfile)         
# create an active object before playin the video         
lock=e32.Ao_lock()         
# a content handler handles the playing of the video         
# load the content handler and tell to release the active object after the video has finnished playing (lock.signal)         content_handler = appuifw.Content_handler(lock.signal)         
# open the video via the content handler. It will start playing automatically         
content_handler.open(tempfile)         
# Wait for the user to exit the image viewer.         
lock.wait()         
print "Video viewing finished."     
except:         
print "Problems."   
def quit():     
app_lock.signal()  
# define the application menu with one choice "get video" and call the fetching video 
appuifw.app.menu = [(u"get video", fetching)]  
appuifw.app.title = u"Get video"  
appuifw.app.exit_key_handler = quit 
app_lock = e32.Ao_lock() 
app_lock.wait() 

Bluetooth: Background scanning

# install first the following files to your phone # (they will install automatically the needed libraries for the script below): # aosocket-series60_v20.sis, pdis.sis # found at: http://pdis.hiit.fi/pdis/download/pdis/  # this script was found from forum.nokia.com  import e32 import appuifw import aosocketnativenew from pdis.lib.logging import * import httplib, urllib  init_logging(FileLogger("c:\\bt_probing.txt"))  def tell(string):     logwrite(string)     if e32.is_ui_thread():         print string         e32.ao_yield()  # ---------------------------------- from aosocket.symbian.bt_device_discoverer import * from socket import * # for obex file send  def discovered(error, devices, cb_param):     if error == 0:        #tell("devices: " + str(devices))         tell(" ")         for address, name in devices:                   tell("Found: " + address + " | " + name)                for address, name in devices:                 tell(" ")                 try:                     address2, services = bt_discover(address)	#find services and port number                                         tell("Probing: " + address + " | " + name)                     tell("RFCOMM Services: ")                     tell(services)                     tell(services.values()[0]) # port number of first RFCOMM service found                     tell(" ")                 except:                     pass                     #tell("ooooops with " + name)                     #log_exception()                              for address, name in devices:                 try:                     address3, services2 = bt_obex_discover(address)	#find obex service port number                                   tell("Probing: " + address + " | " + name)                     tell("OBEX SERVICES: ")                     tell(services2)                     tell(services2.values()[0]) # port number of first OBEX service found                     tell(" ")                 except:                     pass                          else:         tell("device discovery failure: error %d" % error)     _discoverer.close()       # -----------------------------------------------------------------------------   while(1):     try:         _discoverer = BtDeviceLister()         _discoverer.discover_all(discovered, None)         tell("discovering")         e32.ao_sleep(30)         print "scanning again"     except:         tell("init failure")         appuifw.note(u"Fatal error.", "error")

Bluetooth: OBEX (Client)


# this file lets 2 phones exchange a file via OBEX
# this file is the client side
# the corresponding server side file is called obex_server.py

from socket import *
import appuifw
import e32

# JL: you don't need a socket for this!
## create socket
#s=socket(AF_BT,SOCK_STREAM)

# scan for other phones offering OBEX service
addr,services=bt_obex_discover()
print "Discovered: %s, %s"%(addr,services)
if len(services)>0:
choices=services.keys()
choices.sort()
choice=appuifw.popup_menu([unicode(services[x])+": "+x
for x in choices],u'Choose port:')
port=services[choices[choice]]
else:
port=services[services.keys()[0]]
address=(addr,port)

# create file to be sent
send_path = u"c:\\test.txt"
f=open(send_path, 'w')
f.write("hello")
f.close() # NOTE: parens were missing here before!

# send file via OBEX
print "Sending file %s to host %s port %s"%(send_path, address[0], address[1])
bt_obex_send_file(address[0], address[1], send_path)
print "File sent."

Bluetooth: OBEX (Server)

# This script lets 2 phones exchange a file via OBEX. # This is the server, the corresponding client is obex_client.py from socket import * import appuifw  # Create a bluetooth socket in waiting state to be connected to s = socket(AF_BT, SOCK_STREAM) port = bt_rfcomm_get_available_server_channel(s) print "Binding service to port %s"%port s.bind(("", port)) print "Service bound."  # Advertise the OBEX service, so it can be seen by other phones service_name=u"Test OBEX service"  print "Advertising service as %s"%repr(service_name) bt_advertise_service(service_name, s, True, OBEX)  try:      print "Setting security to AUTH."     set_security(s, AUTH)      receive_path = u"c:\\obex.txt"     print "Receiving file."     bt_obex_receive(s, receive_path)     print "File received."      import e32     e32.ao_sleep(1) finally:     print "Stopping service advertising."     bt_advertise_service(service_name, s, False, OBEX)  print "Closing socket." s.close() print "Socket closed." print "Finished."

Bluetooth: RFCOMM (Client)

# this file lets 2 phones exchange data via RFCOMM # this file is the client side # the corresponding server side file is called rfcomm_server.py  import socket import appuifw import e32  class BTReader:     def connect(self):         self.sock=socket.socket(socket.AF_BT,socket.SOCK_STREAM)         addr,services=socket.bt_discover()         print "Discovered: %s, %s"%(addr,services)         if len(services)>0:             import appuifw             choices=services.keys()             choices.sort()             choice=appuifw.popup_menu([unicode(services[x])+": "+x                                        for x in choices],u'Choose port:')             port=services[choices[choice]]         else:             port=services[services.keys()[0]]         address=(addr,port)         print "Connecting to "+str(address)+"...",         self.sock.connect(address)         print "OK."      def readline(self):         line=[]         while 1:             ch=self.sock.recv(1)             if(ch=='\n'):                 break             line.append(ch)         return ''.join(line)     def close(self):         self.sock.close()  bt=BTReader() bt.connect() print "Received: "+bt.readline() bt.close() 

Bluetooth: RFCOMM (Server)

# this file lets 2 phones exchange data via RFCOMM # this file is the server side # the corresponding client side file is called rfcomm_client.py  from socket import * import appuifw  server_socket = socket(AF_BT, SOCK_STREAM) p = bt_rfcomm_get_available_server_channel(server_socket) server_socket.bind(("", p)) print "bind done" server_socket.listen(1) bt_advertise_service( u"jurgen", server_socket, True, RFCOMM) set_security(server_socket, AUTH) print "I am listening"  # Note: Don't call .send or .recv on the server_socket! # Use the sock object returned by server_socket.accept(). (sock,peer_addr) = server_socket.accept() print "Connection from %s"%peer_addr test = appuifw.query(u"Type words", "text", u"") sock.send(test+'\n') print "sending done" import e32 # Allow time for data to be sent to work around a bug in the socket # module. e32.ao_sleep(1) sock.close()
 
 

Mobile to PC Bluetooth Connection

# script that connects to the serial port of the PC # and lets you send characters to the PC  import appuifw # import the module socket import socket import e32  # function that handles the bluetooth connection: def bt_connect():     global sock     # create a bluetooth socket     sock=socket.socket(socket.AF_BT,socket.SOCK_STREAM)     target=''# here you can give the bt address of the other mobile if you know it     if not target:         # scan for bluetooth devices         address,services=socket.bt_discover()         print "Discovered: %s, %s"%(address,services)         if len(services)>1:             choices=services.keys()             choices.sort()             # bring up a popup menu and show the available bt devices for selection             choice=appuifw.popup_menu([unicode(services[x])+": "+x                                         for x in choices],u'Choose port:')             target=(address,services[choices[choice]])         else:             target=(address,services.values()[0])     print "Connecting to "+str(target)     # connect to the serial port of the PC     sock.connect(target)     print "OK."      # call the text input field function        bt_typetext()          # define the textinput function def bt_typetext():     global sock     # create the text input field     test = appuifw.query(u"Type words", "text", u"")     # if cancel has been pressed, then quit the application otherwise send the character over bluetooth     if test == None:         exit_key_handler()     else:         # send the typed in characters over bluetooth to the PC         sock.send(test)         # call again the textinput field function to show the text input again         bt_typetext()  def exit_key_handler():     script_lock.signal()     appuifw.app.set_exit()  appuifw.app.title = u"bt mob to PC"  script_lock = e32.Ao_lock()  appuifw.app.exit_key_handler = exit_key_handler()  # call the function that handles the bluetooth connection bt_connect()  script_lock.wait()

Playing Midi

# playing Midi    import appuifw import e32 import audio   def playsound1():     S = audio.Sound.open("E:\\sound1.mid")     S.play()     menu()      def playsound2():     S = audio.Sound.open("E:\\sound2.mid")     S.play()     menu()   def exit_key_handler():     appuifw.app.set_exit()      def quit():     appuifw.app.set_exit()  L = [u"sound 1", u"sound 2", u"exit"]  def menu():     index = appuifw.popup_menu(L,u'select')     if index == 0:         playsound1()     if index == 1:         playsound2()     if index == 2:         quit()          appuifw.app.title = u"Midi player"  appuifw.app.exit_key_handler = exit_key_handler menu()

Recording & Playing wave

# Sound recording / playing script   import appuifw, e32 # import the audio module import audio   # define a name of the file to be the sound file, incl. its full path filename = 'e:\\boo.wav'  # define the recording part: def recording():     global S     # open the sound file to be ready for recording and set an instance (S) of it     S=audio.Sound.open(filename)     # do the recording (has to be stopped by closing() function below)     S.record()     print "Recording on! To end it, select stop from menu!"  # define the playing part: def playing():     global S     try:         # open the sound file to be ready for playing by setting an instance (S) of it         S=audio.Sound.open(filename)         # play the sound file         S.play()         print "Playing"     except:         print "Record first a sound!"  # stopping of recording / playing and closing of the sound file def closing():     global S     S.stop()     S.close()     print "Stopped"  def quit():     script_lock.signal()     appuifw.app.set_exit()  # define the application menu appuifw.app.menu = [(u"play", playing),                     (u"record", recording),                     (u"stop", closing)]  appuifw.app.title = u"Sound recorder"  appuifw.app.exit_key_handler = quit script_lock = e32.Ao_lock() script_lock.wait()  

S60 Application tabs

# This script creates tabs that let you switch between different applications # listbox app, listbox app and canvas app   import appuifw import e32 from graphics import *   # define application 1: listobx app  # create your icons for the listbox content   icon1 = appuifw.Icon(u"z:\\system\\data\\avkon.mbm", 28, 29) icon2 = appuifw.Icon(u"z:\\system\\data\\avkon.mbm", 40, 41) icon3 = appuifw.Icon(u"z:\\system\\data\\avkon.mbm", 30, 31) icon4 = appuifw.Icon(u"z:\\system\\data\\avkon.mbm", 32, 33) icon5 = appuifw.Icon(u"z:\\system\\data\\avkon.mbm", 34, 35) icon6 = appuifw.Icon(u"z:\\system\\data\\avkon.mbm", 36, 37) icon7 = appuifw.Icon(u"z:\\system\\data\\avkon.mbm", 38, 39)  # create your content list of your listbox including the icons to be used for each entry entries = [(u"Signal", icon1),            (u"Battery", icon2),            (u"Sirene", icon3),            (u"Waste", icon4),            (u"Helicopter", icon5),            (u"Train", icon6),            (u"Auto", icon7)]  # create the listbox callback handler def handler():     print "done"      # create an instance of appuifw.Listbox(), include the content list "entries" and the callback function "handler" app1 = appuifw.Listbox(entries,handler)    # define application 2: listbox app  # define the list of items as pop-up menu content L2 = [u"Stefan", u"Holger", u"Emil", u"Ludger"]  # create the listbox callback handler def handler_L2():     print "ola"  # create the pop-up menu  app2 = appuifw.Listbox(L2, handler_L2)     # define application 3: canvas application  def app_3():     global canvas     img=Image.new((176,208))     img.line((20,20,20,120),0xff00ee)     img.rectangle((40,60,50,80),0xff0000)     img.point((50.,150.),0xff0000,width=40)     img.ellipse((100,150,150,180),0x0000ff)     img.text((100,80), u'hello')          # define your redraw function (still belonging to app 3)      def handle_redraw(rect):     #global canvas         canvas.blit(img)     # define the canvas, include the redraw callback function     canvas =appuifw.Canvas(event_callback=None, redraw_callback=handle_redraw)     appuifw.app.body = canvas        def exit_key_handler():     app_lock.signal()  # create a tab handler that switches the application based on what tab is selected def handle_tab(index):     global lb     if index == 0:         appuifw.app.body = app1 # switch to application 1     if index == 1:         appuifw.app.body = app2 # switch to application 2     if index == 2:         app_3() # switch to application 3       # create an Active Object app_lock = e32.Ao_lock()  # create the tabs with its names in unicode as a list, include the tab handler appuifw.app.set_tabs([u"One", u"Two", u"Three"],handle_tab)  # set the title of the script appuifw.app.title = u'Tabs advanced'  # set app.body to app1 (for start of script) appuifw.app.body = app1   appuifw.app.exit_key_handler = exit_key_handler app_lock.wait()

S60 Application Menu

# this script lets you create a simple application menu  # NOTE: # press the options key in order to open the applicaion menu # when running the script!  # imort appuifw and the e32 modules import appuifw, e32  # create the "callback functions" for the application menu def item1():     appuifw.note(u"Foo", "info")  def item2():     appuifw.note(u"Outch", "info")      # define an exit handler function def quit():     app_lock.signal()  # create the application menu include the selectable options (one, two) # and the related callback functions (item1, item2)  appuifw.app.menu = [(u"one", item1),                     (u"two", item2)]  appuifw.app.exit_key_handler = quit  # create an active object app_lock = e32.Ao_lock()  # start a scheduler app_lock.wait()

S60 Application Skeleton (with MainLoop)

# Application skeleton with main loop (while loop)   import appuifw import e32   appuifw.app.screen='large'   # create your application logic ...   running=1  def quit():     global running     running=0      app.exit_key_handler=quit  appuifw.app.title = u"drawing"  appuifw.app.body= ...   while running:     # handle_redraw(())     e32.ao_sleep(0.5)      """ description:  # 1. import all modules needed import appuifw import e32  # 2. set the screen size to large appuifw.app.screen='large'    # 3. create your application logic ... # e.g. create all your definitions (functions) or classes and build instances of them or call them etc. # ...... application logic ....  running=1    # 4. no application menu here neccessary  # 5. create and set an exit key handler: when exit ley is pressed, the main loop stops going (because the variable running will be put to 0= def quit():     global running     running=0      app.exit_key_handler=quit  # 6. set the application title appuifw.app.title = u"drawing"  # 7. no active objects needed  # 8. set the application body  appuifw.app.body= ...  # 9. create a main loop (e.g. redraw the the screen again and again) while running:     # #put here things that need to be run through again and again     # #e.g. redraw the screen:     # handle_redraw(())     # yield needs to be here e.g. in order that key pressings can be noticed     e32.ao_yield()   """ 

S60 Application Skeleton

# Application skeleton (no main loop)  import appuifw import e32  appuifw.app.screen='large'    # create your application logic ...   def item1():     print "hello"  def subitem1():     print "aha"  def subitem2():     print "good"  appuifw.app.menu = [(u"item 1", item1),                     (u"Submenu 1", ((u"sub item 1", subitem1),                                     (u"sub item 2", subitem2)))]      def exit_key_handler():     app_lock.signal()  appuifw.app.title = u"drawing"       app_lock = e32.Ao_lock()  appuifw.app.body = ...   appuifw.app.exit_key_handler = exit_key_handler app_lock.wait()     """ description:   # 1. import all modules needed import appuifw import e32  # 2. set the screen size to large appuifw.app.screen='large'     # 3. create your application logic ... # e.g. create all your definitions (functions) or classes and build instances of them or call them etc. # ...... application logic ....     # 4. create the application menu including submenus # create the callback functions for the application menu and its submenus def item1():     print ""     round.set(u'item one was selected')  def item1():     print "hello"  def subitem1():     print "aha"  def subitem2():     print "good"  appuifw.app.menu = [(u"item 1", item1),                     (u"Submenu 1", ((u"sub item 1", subitem1),                                     (u"sub item 2", subitem2)))]        # 5. create and set an exit key handler def exit_key_handler():     app_lock.signal()  # 6. set the application title appuifw.app.title = u"drawing"      # 7. crate an active objects  app_lock = e32.Ao_lock()  # 8. set the application body  appuifw.app.body = ...   # no main loop  appuifw.app.exit_key_handler = exit_key_handler app_lock.wait()  """

Application Canvas Drawing

# This script draws different shapes and text to the canvas   import appuifw from appuifw import * import e32 # import graphics from graphics import *    # create an exit handler def quit():     global running     running=0     appuifw.app.set_exit()  # set the screen size to large appuifw.app.screen='large'  # define an initial image (white) img=Image.new((176,208))  # add different shapes and text to the image # coord. sequence x1,x2,y1,y2 img.line((20,20,20,120),0xff00ee) img.rectangle((40,60,50,80),0xff0000) img.point((50.,150.),0xff0000,width=40) img.ellipse((100,150,150,180),0x0000ff) img.text((100,80), u'hello')   # define your redraw function (that redraws the picture on and on) # in this case we redraw the image named img using the blit function def handle_redraw(rect):     canvas.blit(img)  running=1  # define the canvas, include the redraw callback function canvas=appuifw.Canvas(event_callback=None, redraw_callback=handle_redraw)  # set the app.body to canvas appuifw.app.body=canvas  app.exit_key_handler=quit   # create a loop to redraw the the screen again and again until the exit button is pressed while running:     # redraw the screen     handle_redraw(())     # yield needs to be here in order that key pressings can be noticed     e32.ao_yield()  

Application body Text

import appuifw import e32  def exit_key_handler():     app_lock.signal()  # create an instance of appuifw.Text() round = appuifw.Text() # change the style of the text round.style = appuifw.STYLE_UNDERLINE # set the text to 'hello' round.set(u'hello')  # put the screen size to full screen appuifw.app.screen='full'   # create an Active Object app_lock = e32.Ao_lock()  # set the application body to Text # by handing over "round" which is an instance of appuifw.Text() as definded above appuifw.app.body = round  appuifw.app.exit_key_handler = exit_key_handler app_lock.wait()

Application body Listbox

import appuifw import e32  def exit_key_handler():     app_lock.signal()  # define a callback function def shout():     index = lb.current()     print index     print entries[index]  # create your content list of your listbox including the icons to be used for each entry entries = [u"Signal",u"Battery"] lb = appuifw.Listbox(entries,shout)  # create an Active Object app_lock = e32.Ao_lock()  # create an instance of appuifw.Listbox(), include the content list "entries" and the callback function "shout" # and set the instance of Listbox now as the application body appuifw.app.body = lb   appuifw.app.exit_key_handler = exit_key_handler app_lock.wait()

Application Menu

import appuifw import e32  def exit_key_handler():     app_lock.signal()    # create the callback functions for the application menu and its submenus def item1():     print ""     round.set(u'item one was selected')  def subitem1():     print ""     round.set(u'subitem one was selected')  def subitem2():     round.set(u'subitem two was selected')   app_lock = e32.Ao_lock() round = appuifw.Text() round.set(u'press options') appuifw.app.screen='large' appuifw.app.body = round  # create the application menu including submenus appuifw.app.menu = [(u"item 1", item1),                     (u"Submenu 1", ((u"sub item 1", subitem1),                                     (u"sub item 2", subitem2)))]   appuifw.app.exit_key_handler = exit_key_handler app_lock.wait()

Application Screen

import appuifw import e32  def exit_key_handler():     app_lock.signal()   round = appuifw.Text() round.set(u'hello')  # put the application screen size to full screen appuifw.app.screen='full' #(a full screen)  # other options: #appuifw.app.screen='normal' #(a normal screen with title pane and softkeys) #appuifw.app.screen='large' #(only softkeys visible)    app_lock = e32.Ao_lock()  appuifw.app.body = round  appuifw.app.exit_key_handler = exit_key_handler app_lock.wait()

Defining a function

# defining a simple function   import appuifw  # a function is definded with: def nameoffunction(): # be aware of the indentation! (4 x spacebar)  def afunction():     data = appuifw.query(u"Type a word:", "text")     appuifw.note(u"The typed word was: " +data, "info")   # a function is called with its name and brackets behind it afunction()           

SMS to speech

# This script waits for an incoming sms, reads its 
# content and shows it inside a pop-up note 
# NOTE: PyS60 version 1.3.14 or higher is needed to run this script.  
import inbox 
import e32 
import audio  
#create a function that does the reading of the content of the sms  
def read_sms(id):     
e32.ao_sleep(0.1)     
# read the content out of the message that has just arrived     
sms_text = i.content(id)     
# the phone speaks out the text that just arrived by sms (you can hear it through the loudspeakers of your phone)     
audio.say(sms_text)  
# create an instance of the inbox() class      
i=inbox.Inbox() 
print "send now sms to this phone" 
# put the phone into waiting stage to wait for an incoming message 
i.bind(read_sms) 

Text to speech

# This script performs a query with a single-field dialog (text input field) # and lets the phone speak out the text (text to speech) that the users have typed in  # NOTE: this script runs only with Python S60 version 3.1.14 or above # NOTE: this script doesn't work on all S60 phones neccessarily. Check your phone model if it has text to speech capability at all   # import the module called audio import appuifw import audio  # trigger a text input-field to let the user type a word text = appuifw.query(u"Type few words:", "text") # the phone speaks out the text that you have just typed (you can hear it through the loudspeakers of your phone) audio.say(text)

Sending MMS

# this script lets you send an mms to another phone including text and an image  import appuifw import messaging  # create text input field data = appuifw.query(u"Type your name:", "text")  # define the mobile number here where to send the MMS nbr = "123456" # change the mobile number here  # define the text that the sms shall contain txt = u"Greetings from:" +data   # image attachment: You must have an picture already available with the name picture1.jpg # inside the folder called Images on your memory card. ('e:\\Images\\picture1.jpg')  # otherwise the script won't work. (use video or sound file instead of image)  # send out the mms; include the mobile number, the text and the attachement to be sent messaging.mms_send(nbr, txt, attachment='e:\\Images\\picture1.jpg')  # confirm with a pop-up note that the sms has been sent out appuifw.note(u"MMS sent", "info")

Receiving SMS

# This script waits for an incoming sms, reads its # content and shows it inside a pop-up note # NOTE: PyS60 version 1.3.1 or higher is needed to run this script.  import inbox, appuifw, e32  def message_received(msg_id):         box = inbox.Inbox()         sms_text = box.content(msg_id)          appuifw.note(u"sms content: " + sms_text , "info")         app_lock.signal()  box = inbox.Inbox() box.bind(message_received)  print "Waiting for new SMS messages.." app_lock = e32.Ao_lock() app_lock.wait() print "Message handled!"

Pop-up Notes

# This script performs notes (pop-up notes) of different types: info, error, conf # It uses the .note() function of the appuifw module # appuifw.note(label, type)  # import the application user interface framework module import appuifw  # info: appuifw.note(u"Hello", "info")  # error: appuifw.note(u"file not found", "error")  # conf: appuifw.note(u"upload done", "conf")

Query with Single Field Dialog

# This script performs a query with a single-field dialog, each with a # different input type. # It uses the .query() function of the appuifw module   # import the application user interface framework module import appuifw   # text: # create a single-field dialog (text input field):  appuifw.query(label, type) data = appuifw.query(u"Type a word:", "text") print data  # number: # create a single-field dialog (number input field):  appuifw.query(label, type) data = appuifw.query(u"Type a number:", "number") print data  # date: # create a single-field dialog (date input field):  appuifw.query(label, type) data = appuifw.query(u"Type a date:", "date") print data  # time: # create a single-field dialog (time input field):  appuifw.query(label, type) data = appuifw.query(u"Type a time:", "time") print data  # code: # create a single-field dialog (code input field):  appuifw.query(label, type) data = appuifw.query(u"Type a code:", "code") print data  # query: # create a single-field dialog (question):  appuifw.query(label, type) if appuifw.query(u"Are you ok:", "query") == True:     print "you pressed ok" else:     print "you pressed cancel" 

Tent Input Example

# This script performs a query with a single-field dialog (text input field) # and displays the users input as a pop-up note    # 1. import the application user interface framework module import appuifw  # 2. , 3. create a text input field:  appuifw.query(label, type) and variable data = appuifw.query(u"Type a word:", "text")  # 4. create a pop-up note: appuifw.note(label, type) appuifw.note(u"The typed word was: " + data, "info")    """ detailed description:  1. we import the "appuifw" module to handle UI widgets like text input fields and    pop-up notes etc. 2. we create a single-field dialog (text input field) using the .query() function    of the appuifw module.    we include in the brackets 2 parameters:    - label: as label we put the text u"Type a word:" (the u must be there because             the phone understands only text declared as unicode, the high commas             must be there because label must be given as a string)    - type: as type we put "text". It declares the input field as text type            (other possible types: "number", "date", "time", "query", "code")    -> separate the the two parameters with a comma. 3. We create a variable called data, and by putting data = appui... we write    the result of the text input field into this variable    (after user has typed something when he/she runs the script)  4. We create a pop-up note using the .note() function of the appuifw module.      we include in the brackets the 2 parameters:    - label: as label we put the text u"The typed word was: " + data              This is the text that will appear in the pop-up note. Again the text             must be given as a string in highcommas.             But our pop-up note shall also inculde the result that the user             has typed in, therefore we add the content of our variable data to our label             string by writing + data (adding the content of a variable to a string)                - type: as type we put "info". It declares the pop-up note as info. This puts            an exclamationmark in the pop-up note (other possible types: "error","conf")    -> again, separate the the two parameters with a comma.  """

Send SMS 2 users (description)

# this script lets you send an sms to 2 users at the same time.   # import the messaging module import appuifw import messaging  # create text input field data = appuifw.query(u"Type your name:", "text")  # define the mobile numbers here nbr1 = "123456"  nbr2 = "234567"  # define the text that the sms shall contain txt = u"Greetings from:" +data  # create a query with type: "query" -> appuifw.query(label, type) # by using an if statement one can check whether the user has pressed "ok" -> True or "cancel" -> False if appuifw.query(u"Send message to your 2 friends","query") == True:     # send out the sms; include the mobile number and the text to be sent     messaging.sms_send(nbr1, txt)     messaging.sms_send(nbr2, txt)          # confirm with a pop-up note that the sms has been sent out     appuifw.note(u"Messages sent", "info") else:     # in case the user had pressed "cancel", send a pop-up note that the messages have not been sent out     appuifw.note(u"Well, your Messages are not sent then", "info")

RemoveRelated Message

Removes the relationship between two entity instances as defined by the target classes listed below. For example, remove the relationship between an invoice and a contact.

Remarks

To use this message, pass an instance of the RemoveRelatedRequest class as the request parameter in the Execute method.

To perform this action, the caller must have access rights on the entity instance specified in the request class. For a list of required privileges, see RemoveRelated Privileges.

The RemoveRelated and SetRelated messages support all types of relationships, including one-to-many and many-to-many.RemoveRelated and SetRelated can also be used with custom entities.



//# The following code example shows how to use the RemoveRelated message.

// Set up the CRM service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
// You can use enums.cs from the SDK\Helpers folder to get the enumeration for Active Directory authentication.
token.AuthenticationType = 0;
token.OrganizationName = "AdventureWorksCycle";

CrmService service = new CrmService();
service.Url = "http://:/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Create the target object for the request.
TargetRelatedLeadToAccount target = new TargetRelatedLeadToAccount();

// AccountId is the GUID of the account to be related to the lead.
target.AccountId = new Guid("D3652E9C-D328-4CA1-B284-1215C441AD94");

// LeadId is the GUID of the lead to be related to the account.
target.LeadId = new Guid("9DAEE309-A3D6-470C-80E2-DDC657BAFC16");

// Create the request object.
RemoveRelatedRequest remove = new RemoveRelatedRequest();

// Set the properties of the request object.
remove.Target = target;

// Execute the request.
RemoveRelatedResponse related = (RemoveRelatedResponse)service.Execute(remove);




Convert a Dynamic Entity to a System Entity

//# Convert a Dynamic Entity to a System Entity
using System;
using System.Reflection;

using CrmSdk;
using Microsoft.Crm.Sdk.Utility;

namespace Microsoft.Crm.Sdk.HowTo
{
public class ConvertDynamicToCore
{
static void Main(string[] args)
{
// TODO: Change the server URL and organization to match your Microsoft
// Dynamics CRM Server and Microsoft Dynamics CRM organization.
ConvertDynamicToCore.Run("http://localhost:5555", "CRM_SDK");
}

public static bool Run(string crmServerUrl, string orgName)
{
// Create an account dynamic entity.
DynamicEntity accountDynamicEntity = new DynamicEntity();

//Set a few account properties.
StringProperty name = new StringProperty();
name.Name = "name";
name.Value = "Fabrikam Inc.";

StringProperty accountnumber = new StringProperty();
accountnumber.Name = "accountnumber";
accountnumber.Value = "AZ1200";

Picklist plist = new Picklist();
plist.name = "UPS";
plist.Value = 2;

PicklistProperty shippingmethodcode = new PicklistProperty();
shippingmethodcode.Name = "address1_shippingmethodcode";
shippingmethodcode.Value = plist;

accountDynamicEntity.Properties = new Property[] { name, accountnumber, shippingmethodcode };
accountDynamicEntity.Name = EntityName.account.ToString();

//Create a strongly typed account entity to copy the dynamic entity into.
account coreAccount = new account();

//Convert the dynamic entity to a strongly typed business entity.
coreAccount = (account)Convert(accountDynamicEntity);

Console.WriteLine("\n|Core Account Attributes\n|=======================");
Console.WriteLine("|name: {0}", coreAccount.name);
Console.WriteLine("|accountnumber: {0}", coreAccount.accountnumber);
Console.WriteLine("|address1_shipmethodcode: {0}", coreAccount.address1_shippingmethodcode.Value);

return true;
}

///
/// Convert a dynamic entity into a strongly typed business entity.
///

public static BusinessEntity Convert(DynamicEntity entity)
{
string coreEntityName = entity.Name;

Type entType = (new account()).GetType();
ConstructorInfo init = entType.GetConstructor(new Type[] { });
object ent = init.Invoke(new object[] { });

foreach (Property p in entity.Properties)
{
PropertyInfo entProp = entType.GetProperty(p.Name);
if (null == entProp)
{
Console.WriteLine("Could not find attribute {0} on entity {1}.", p.Name, coreEntityName);
}
else
{
entProp.SetValue(ent, GetAttribute(entity, p.Name), null);
}
}
return (BusinessEntity)ent;
}

///
/// This method returns the value of a dynamic entity attribute.
///

public static object GetAttribute(BusinessEntity entity, string attribute)
{
if (entity.GetType() == typeof(DynamicEntity))
{
DynamicEntity de = (DynamicEntity)entity;
foreach (Property prop in de.Properties)
{
if (prop.Name == attribute)
{
PropertyInfo propInfo = prop.GetType().GetProperty("Value");
return propInfo.GetValue(prop, null);
}
}
return null;
}
else
{
PropertyInfo propInfo = entity.GetType().GetProperty(attribute);
return propInfo.GetValue(entity, null);
}
}
}
}