Book Review : Pro Business Applications with Silverlight 4 by Chris Anderson

Pro Business Applications with Silverlight 4Pro Business Applications with Silverlight 4 by Chris Anderson
My rating: 5 of 5 stars

It is surely one of the best books on business application development with Silverlight.

It starts with basics of Silverlight and XAML.

Then it gradually covers the important topics like Navigation Framework, WCF RIA Services, MVVM, OOB Mode etc.

It covers almost every aspect of developing a business application.

I don’t think there is any other book that explains this topic in such great detail.

I will highly recommend this book.

View all my reviews

Using Deep Insert (creating multiple new records in the same operation) in Silverlight (CRM 2011)

Hi,

Sharing a basic example using which we can create Parent entity and the related entity records in the same operation\

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

Check out this helpful post

http://inogic.blogspot.com/2011/12/odata-properties-and-methods-explored.html


public MainPage()
 {
 InitializeComponent();
 }

GGContext context;

private void UserControl_Loaded(object sender, RoutedEventArgs e)
 {
 var orgServiceUrl = "http://servername/orgname/XRMServices/2011/OrganizationData.svc";

 // initialize the context
 context = new GGContext(new Uri(orgServiceUrl));

// using client http stack
 context.HttpStack = System.Data.Services.Client.HttpStack.ClientHttp;
 context.UseDefaultCredentials = false;
 context.Credentials = new NetworkCredential("administrator", "password", "domain");
 // create contact record
 Contact contact = new Contact();
 contact.LastName = "Rana";
 contact.FirstName = "Nisha";

 // create two tasks and one email activity
 var myTask1 = new Task();
 myTask1.Subject = "Task1 created at " + DateTime.Now.ToLongTimeString();
 var myTask2 = new Task();
 myTask2.Subject = "Task2 created at " + DateTime.Now.ToLongTimeString();
 var myEmail = new Email();
 myEmail.Subject = "Email created at " + DateTime.Now.ToLongTimeString();

// add the tasks and email to their respective set
 context.AddToTaskSet(myTask1);
 context.AddToTaskSet(myTask2);
 context.AddToEmailSet(myEmail);

// add contact to be created to the contact set
 context.AddToContactSet(contact);

// add the related records
 contact.Contact_Tasks.Add(myTask1);
 contact.Contact_Tasks.Add(myTask2);
 contact.Contact_Emails.Add(myEmail);

 // add the link
 // http://inogic.blogspot.com/2011/12/odata-properties-and-methods-explored.html
 context.AddLink(contact, "Contact_Tasks", myTask1);
 context.AddLink(contact, "Contact_Tasks", myTask2);
 context.AddLink(contact, "Contact_Emails", myEmail);

context.BeginSaveChanges(CreateContactHandler, contact);
 }
 private void CreateContactHandler(IAsyncResult result)
 {
 // in the call back method call the EndSaveChanges method
 // it returns DataServiceResponse object.
 // we can get the error information from this object in case an operation fails
 context.EndSaveChanges(result);
 // id of the created contact record
 Guid createdContactGuid = ((Contact)result.AsyncState).ContactId;
 }

Hope it helps

Create Retrieve Update and Delete using oData (Rest endpoint) in Silverlight (CRM 2011)

Hi,

Sharing a basic example that performs CRUD operation using Rest endpoint in Silverlight.

namespace odataSilverlight
{
 public partial class MainPage : UserControl
 {
 public MainPage()
 {
 InitializeComponent();
 }

GGContext context;
 private void UserControl_Loaded(object sender, RoutedEventArgs e)
 {
 var orgServiceUrl = "http://r78-7-amscrm/GG/XRMServices/2011/OrganizationData.svc";

 // initialize the context
 context = new GGContext(new Uri(orgServiceUrl));

// using client http stack
 context.HttpStack = System.Data.Services.Client.HttpStack.ClientHttp;
 context.UseDefaultCredentials = false;
 context.Credentials = new NetworkCredential("administrator", "Secure*8", "AMS");
 // create contact record
 Contact contact = new Contact();
 contact.LastName = "Rana";
 contact.FirstName = "Akshaj";

// add the new contact to the contact set
 context.AddToContactSet(contact);
 // call BeginSaveChanges method and specify the callback method and the contact object
 context.BeginSaveChanges(CreateContactHandler, contact);

}
 private void CreateContactHandler(IAsyncResult result)
 {
 // in the call back method call the EndSaveChanges method
 // it returns DataServiceResponse object.
 // we can get the error information from this object in case an operation fails
 context.EndSaveChanges(result);
 // id of the created contact record
 Guid createdContactGuid = ((Contact)result.AsyncState).ContactId;

// Retrieve the created contact record
 DataServiceQuery<Contact> queryContact = (DataServiceQuery<Contact>)
 context.ContactSet.
 AddQueryOption("$filter", "ContactId eq guid'" + createdContactGuid + "'");
 queryContact.BeginExecute(RetrieveContactHandler, queryContact);

}

private void RetrieveContactHandler(IAsyncResult result)
 {
 DataServiceQuery<Contact> contacts = result.AsyncState as DataServiceQuery<Contact>;
 Contact retrievedContact = new DataServiceCollection<Contact>(contacts.EndExecute(result)).First<Contact>();

// Update the retrieved contact record's first name
 retrievedContact.FirstName = "Mickey";

context.UpdateObject(retrievedContact);
 context.BeginSaveChanges(UpdateContactHandler, retrievedContact);

}

private void UpdateContactHandler(IAsyncResult result)
 {
 context.EndSaveChanges(result);
 Contact contact = (Contact)result.AsyncState;

// Delete the updated contact record
 context.DeleteObject(contact);
 context.BeginSaveChanges(DeleteContactHandler, contact);
 }
 private void DeleteContactHandler(IAsyncResult result)
 {
 context.EndSaveChanges(result);
 }
 }
}

Hope it helps

Using AddQueryOption to write oData query in Silverlight (CRM 2011)

Hi,

The easiest way to write oData query is to make use of this wonderful tool developed by Rhett Clinton:-

http://crm2011odatatool.codeplex.com/

The query generated by tool can be used in Jscript. They can also be used to write DataServiceQuery in Silverlight project using AddQueryOption.

Here are few examples: –

  • The query to get the subject and city of all the lead records

http://servername/orgName/xrmservices/2011/OrganizationData.svc/LeadSet?

$select=Address1_City,Subject

Now while writing DataServiceQuery simple set the first parameter of AddQueryOption as $select and the value part of it as the second parameter.

var queryLead = context.LeadSet.AddQueryOption("$select", "Address1_City,Subject") as DataServiceQuery<Lead>;


  • The query to get the subject and city of all the lead records where subject contains string ‘test’

http://sname/orgname/xrmservices/2011/OrganizationData.svc/LeadSet?

$select=Address1_City,FullName&$filter=substringof(‘test’,Subject)

Here we will add two query option one for select and other for filter criteria

var queryLead = context.LeadSet
.AddQueryOption("$select", "Address1_City,Subject")
.AddQueryOption("$filter", "substringof('test',Subject)")
as DataServiceQuery<Lead>;


  • The query to get the subject of all the lead records along with owner’s Business Unit Name (i.e. related entity)

http://sname/orgname/xrmservices/2011/OrganizationData.svc/LeadSet?

$select=Subject,lead_owning_user/BusinessUnitId&$expand=lead_owning_user

Here we are making use of expand to get the data from the related entity

var queryLead = context.LeadSet
.AddQueryOption("$select", "Subject,lead_owning_user/BusinessUnitId")
.AddQueryOption("$expand", "lead_owning_user")
as DataServiceQuery<Lead>;

To run the query and loop through the records returned we can make use of following code:-

DataServiceCollection<Lead> leads = new DataServiceCollection<Lead>();
leads.LoadCompleted += (s, ea) =>
{

foreach (Lead lead in leads)
{
MessageBox.Show(lead.Subject);
MessageBox.Show(lead.lead_owning_user.BusinessUnitId.Name);
}

};

leads.LoadAsync(queryLead);

Hope this helps.

Using Client HTTP Stack with oData in Silverlight (CRM 2011)

Hi,

Just sharing a simple example that uses Client HTTP Stack while developing Silverlight web resource.

The good thing with this is that we don’t have to upload and publish the web resource for every change. However if the Siliverlight component is running in the context of the form and interacting with it then in that case we will have to upload and publish it.

Steps : –

Create a Silverlight application and add service reference to the oData service of CRM 2011.

Go to Settings |Customizations | Developer Resources

Get the url of the OrganizationData service

Add Service Reference to the URL

The context would be named as OrganizationNameContext.

Now in the MainPage.xaml set the url of the OrganizationData and Set up the context in the following manner.

 public partial class MainPage : UserControl
 {

private GGContext context;
 private String orgDataServerUrl;

public MainPage()
 {
 InitializeComponent();

// set the server url
 orgDataServerUrl = "http://server:port/GG/XRMServices/2011/OrganizationData.svc";

// set the context
 context = new GGContext(new Uri(orgDataServerUrl));

// set up the Client Http Stack
 context.HttpStack = System.Data.Services.Client.HttpStack.ClientHttp;
 context.UseDefaultCredentials = false;
 context.Credentials = new NetworkCredential("administrator", "password", "domain");
 }
 . . . .

Put the following clientaccesspolicy.xml in the following location

“..\Program Files\Microsoft Dynamics CRM\CRMWeb”

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
 <cross-domain-access>
 <policy>
 <allow-from http-request-headers="*">
 <domain uri="*"/>
 </allow-from>
 <grant-to>
 <resource path="/" include-subpaths="true"/>
 </grant-to>
 </policy>
 </cross-domain-access>
</access-policy>

Once we are done with development we can set up the context in the following manner

 public partial class MainPage : UserControl
 {

private GGContext context;
 private String orgDataServerUrl;

public MainPage()
 {
 InitializeComponent();

// get the Server Url
 orgDataServerUrl = this.GetServerUrlFromContext();

// setup Context
 context = new GGContext(
 new Uri(String.Format("{0}/xrmservices/2011/organizationdata.svc/",
 orgDataServerUrl), UriKind.Absolute));

//This is important because if the entity has new
 //attributes added the code will fail.
 context.IgnoreMissingProperties = true;

}

private string GetServerUrlFromContext()
 {
 try
 {
 // If the Silverlight is in a form, this will get the server url.
 ScriptObject xrm = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
 ScriptObject page = (ScriptObject)xrm.GetProperty("Page");
 ScriptObject pageContext = (ScriptObject)page.GetProperty("context");

String serverUrl = (String)pageContext.Invoke("getServerUrl");

// The trailing forward slash character from CRM Online needs to be
 // removed.
 if (serverUrl.EndsWith("/"))
 {
 serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);
 }

return serverUrl;
 }
 catch
 {
 return String.Empty;
 }
 }
 }

Hope this helps.

HTML Bridge in Silverlight

Hi,

Just sharing simple example.

Suppose we have the following HTML page having a Silverlight control (blue background) in it.

When we click on “Pass to Silverlight” button we want to pass the values specified in the textboxes in our HTML page to the text boxes in the Silverlight control.

To do this we can create a function inside our Silverlight page (MainPage.xaml.cs) and decorate it with ScriptableMember attribute and also use RegisterScriptableObject method.

 [System.Windows.Browser.ScriptableMember]
 public void SetLabelFromHtml(string firstName, string lastName)
 {
 txtFirstName.Text = firstName;
 txtLastName.Text = lastName;
 }
 
public MainPage()</pre>
 {
 InitializeComponent();
 // RegisterScriptableObject Method
 // Registers a managed object for scriptable access by JavaScript code
 System.Windows.Browser.HtmlPage.RegisterScriptableObject("myMethod", this);
 }
<pre> 

To call this function from our html page, we can make use of following JavaScript.

function btnPass_onclick() {

// id of the silverlight control in object tag
var silverlightPlugin = document.getElementById("mySilverLightControl");
// get the values from the text boxes in the html page
var firstName = document.getElementById("txtFirstName").value;
var lastName = document.getElementById("txtLastName").value;

silverlightPlugin.content.myMethod.SetLabelFromHtml(firstName, lastName);

}

Similarly if we want to pass the values for the text boxes from Silverlight page to our HTML page, we need to do the following.

First create a JavaScript function in out HTML page

function SetValueFromSilverlight(firstName, lastName) {

document.getElementById("txtFirstName").value = firstName;
 document.getElementById("txtLastName").value = lastName;

}

To call this JavaScript function from our Silverlight page we can make use of following line of code

HtmlPage.Window.CreateInstance("SetValueFromSilverlight",new string[] { txtFirstName.Text,txtLastName.Text});

Apart from calling the JavaScript function inside our html, we can directly access the fields through DOM and set their values in Silverlight

HtmlDocument document = HtmlPage.Document;

// get the text boxes
HtmlElement firstName = document.GetElementById("txtFirstName");
HtmlElement lastName = document.GetElementById("txtLastName");

// get the value in html text boxes
MessageBox.Show("First Name is " + firstName.GetProperty("value").ToString());
MessageBox.Show("Last Name is " + lastName.GetProperty("value").ToString());

// set the html text boxes
firstName.SetProperty("value", txtFirstName.Text);
lastName.SetProperty("value", txtLastName.Text);

Bye.