Tuesday, December 29, 2015
Saturday, December 12, 2015
Clone Record
http://thinkingincrm.blogspot.com/2013/07/clone-record-via-javascript-crm-2011.html
Clone an entity record via JavaScript (CRM 2011)
We have had the need to clone a record with client-side Scripting, responding to a click on a button in the entity's Ribbon.
Conceptually the operation is easy and is based on the retrieving of all the record information using the Organization web service, then build an object identical to the first and use the web service to create a new record with this object.
Few things are important to take in mind:
1. In the building of the object the record ID must be "skipped" because, obviously, we can't create a record with an existing Guid
2. Date fields are returned in a format like: "Date("date_string") that it is not accepted in record creation from the Organization web service: depending of the need of every field, we decided to "skip it" or "reformat it". In the sample code we show both of these cases.
3. StateCode and StatusCode should be skipped (or managed) because, natively, Organization web service doesn't allow the creation of a record in a closed state.
Conceptually the operation is easy and is based on the retrieving of all the record information using the Organization web service, then build an object identical to the first and use the web service to create a new record with this object.
Few things are important to take in mind:
1. In the building of the object the record ID must be "skipped" because, obviously, we can't create a record with an existing Guid
2. Date fields are returned in a format like: "Date("date_string") that it is not accepted in record creation from the Organization web service: depending of the need of every field, we decided to "skip it" or "reformat it". In the sample code we show both of these cases.
3. StateCode and StatusCode should be skipped (or managed) because, natively, Organization web service doesn't allow the creation of a record in a closed state.
function cloneRecord(serverUrl, originRecordType, originRecordGuid) {
var cloneData = {};
var activityId;
var serverUrl = document.location.protocol + "//" + document.location.host
+ "/" + Xrm.Page.context.getOrgUniqueName();
var oDataUri = serverUrl + "/xrmservices/2011/OrganizationData.svc/" +
originRecordType + "Set?$select=*&$filter=<EntityId> eq guid'"
+ originRecordGuid + "'";
+ originRecordGuid + "'";
jQuery.support.cors = true;
jQuery.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: oDataUri,
async: false, //Synchronous operation
beforeSend: function (XMLHttpRequest) {
//Specifying this header ensures that the results
will be returned as JSON.
XMLHttpRequest.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, XmlHttpRequest) {
if (data && data.d && data.d.results) {
cloneData = data.d.results[0];
//Here insert the code to skip/transform fields such as
Record Id, Date fields, etc..
Record Id, Date fields, etc..
replacer = function (key, value) {
if (key == "ModifiedOn" || key == originRecordType + "Id" ||
key == "CreatedOn" || key == "StateCode" ||
key == "StatusCode") {
return undefined;
} else if (key == "ActualStart" || key == "ActualEnd") {
if (value) {
var date =
eval('new ' +
value.replace("/", "").replace("/", ""));
value.replace("/", "").replace("/", ""));
return date.format('yyyy-MM-dd'); //Format the date
}
}
else return value;
}
//Create new Activity
var oDataUri = serverUrl +
"/xrmservices/2011/OrganizationData.svc/" +
originRecordType + "Set";
jQuery.support.cors = true;
jQuery.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: oDataUri,
async: false, //Synchronous operation
data: JSON.stringify(cloneData, replacer),
beforeSend: function (XMLHttpRequest) {
//Specifying this header ensures that the results will be
returned as JSON.
XMLHttpRequest.setRequestHeader("Accept",
"application/json");
},
success: function (data, textStatus, XmlHttpRequest) {
if (data && data.d) {
activityId = data.d.ActivityId;
}
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
alert("Error : has occured during creation of
the activity " + originRecordType.text + ": " +
the activity " + originRecordType.text + ": " +
XmlHttpRequest.responseText);
}
});
} else {
//No data returned
}
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
alert("Error : has occured during retrieving of the activity "
+ originRecordType.text + ": " +
XmlHttpRequest.responseText);
}
});
return activityId;
}
Thursday, October 22, 2015
CRM 2011–Cannot publish customizations after import
Problem:
If you ever run into a situation that you imported your solution successfully and not able to publish it, the reason is because either the size of the solution might be too large or the SQL is not fast enough.
We ran into this problem earlier this week. We have a slow SQL server and the size of our solution is big, we can’t publish it and we don’t know what was the reason behind it since CRM didn’t provide any helpful error messages.
Cause:
After hours of troubleshooting, we finally figured out that CRM has a default timeout value of 300 seconds = 5 minutes. If any process takes more than 5 minutes, it’ll stop.
Detail solution is given below -
http://blogs.msdn.com/b/darrenliu/archive/2011/07/08/crm-2011-cannot-publish-customizations-after-import.aspx
If you ever run into a situation that you imported your solution successfully and not able to publish it, the reason is because either the size of the solution might be too large or the SQL is not fast enough.
We ran into this problem earlier this week. We have a slow SQL server and the size of our solution is big, we can’t publish it and we don’t know what was the reason behind it since CRM didn’t provide any helpful error messages.
Cause:
After hours of troubleshooting, we finally figured out that CRM has a default timeout value of 300 seconds = 5 minutes. If any process takes more than 5 minutes, it’ll stop.
Detail solution is given below -
http://blogs.msdn.com/b/darrenliu/archive/2011/07/08/crm-2011-cannot-publish-customizations-after-import.aspx
Sunday, September 13, 2015
Twitter Integration with CRM 2013 and .NET applications
Microsoft has launched the Microsoft Dynamics CRM Sample Social Care Application together with some new entities that they are purposely created for the Social Live and Connection, during the launching of the Microsoft Dynamics CRM Springwave ‘14 Updates. I tried integrating twitter with CRM using below blogs but faced many issues.
http://www.microsoft.com/en-us/download/details.aspx?id=43122
http://missdynamicscrm.blogspot.sg/2014/07/run-social-care-application-crm-2013.html.
I got error while executing the app( Value was either too large or too small for an Int32)
Solution i found in below blogs.
http://stackoverflow.com/questions/21138289/tweetsharp-getaccesstoken-method-returns-null-but-only-sometimes
http://www.nuget.org/packages/TweetSharp-Unofficial/
Thorough of understanding the integration between .NET and twitter. is as below
https://github.com/danielcrenna/tweetsharp
Also i tried integrating using tweetizzer.
https://github.com/detroitpro/Twitterizer/tree/master/Twitterizer.OAuth
Below application is .NET integration with twitter without any wrapper.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Security.Cryptography;
using System.IO;
namespace TwitterOAuth
{
class Program
{
static void Main(string[] args)
{
// oauth application keys
var oauth_token = "xxxxxxxxx";
var oauth_token_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var oauth_consumer_key = "xxxxxxxxxxxxxxxx";
var oauth_consumer_secret = "xxxxxxxxxxxxxxxxxxxxxxxx";
// oauth implementation details
var oauth_version = "1.0";
var oauth_signature_method = "HMAC-SHA1";
// unique request details
var oauth_nonce = Convert.ToBase64String(
new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
var timeSpan = DateTime.UtcNow
- new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
// message api details
var status = "Updating status via REST API if this works again";
var resource_url = "https://api.twitter.com/1.1/statuses/update.json";
// create oauth signature
var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&status={6}";
var baseString = string.Format(baseFormat,
oauth_consumer_key,
oauth_nonce,
oauth_signature_method,
oauth_timestamp,
oauth_token,
oauth_version,
Uri.EscapeDataString(status)
);
baseString = string.Concat("POST&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));
var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
"&", Uri.EscapeDataString(oauth_token_secret));
string oauth_signature;
using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
{
oauth_signature = Convert.ToBase64String(
hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
}
// create the request header
var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
"oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
"oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
"oauth_version=\"{6}\"";
var authHeader = string.Format(headerFormat,
Uri.EscapeDataString(oauth_nonce),
Uri.EscapeDataString(oauth_signature_method),
Uri.EscapeDataString(oauth_timestamp),
Uri.EscapeDataString(oauth_consumer_key),
Uri.EscapeDataString(oauth_token),
Uri.EscapeDataString(oauth_signature),
Uri.EscapeDataString(oauth_version)
);
// make the request
var postBody = "status=" + Uri.EscapeDataString(status);
ServicePointManager.Expect100Continue = false;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);
request.Headers.Add("Authorization", authHeader);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (Stream stream = request.GetRequestStream())
{
byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody);
stream.Write(content, 0, content.Length);
}
WebResponse response = request.GetResponse();
}
}
}
Twittter Developer reference is below-
https://dev.twitter.com/oauth/overview/single-user
Also we have samples to explain integration using tweetsharp as below-
http://www.codeproject.com/Articles/584666/Twitter-Client-Login-to-Csharp-application-using-t
also we need to check whether our sample is referring to
https://api.twitter.com/1.1/ - new
or
https://api.twitter.com/1/- old
http://www.microsoft.com/en-us/download/details.aspx?id=43122
http://missdynamicscrm.blogspot.sg/2014/07/run-social-care-application-crm-2013.html.
I got error while executing the app( Value was either too large or too small for an Int32)
Solution i found in below blogs.
http://stackoverflow.com/questions/21138289/tweetsharp-getaccesstoken-method-returns-null-but-only-sometimes
http://www.nuget.org/packages/TweetSharp-Unofficial/
Thorough of understanding the integration between .NET and twitter. is as below
https://github.com/danielcrenna/tweetsharp
Also i tried integrating using tweetizzer.
https://github.com/detroitpro/Twitterizer/tree/master/Twitterizer.OAuth
Below application is .NET integration with twitter without any wrapper.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Security.Cryptography;
using System.IO;
namespace TwitterOAuth
{
class Program
{
static void Main(string[] args)
{
// oauth application keys
var oauth_token = "xxxxxxxxx";
var oauth_token_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var oauth_consumer_key = "xxxxxxxxxxxxxxxx";
var oauth_consumer_secret = "xxxxxxxxxxxxxxxxxxxxxxxx";
// oauth implementation details
var oauth_version = "1.0";
var oauth_signature_method = "HMAC-SHA1";
// unique request details
var oauth_nonce = Convert.ToBase64String(
new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
var timeSpan = DateTime.UtcNow
- new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
// message api details
var status = "Updating status via REST API if this works again";
var resource_url = "https://api.twitter.com/1.1/statuses/update.json";
// create oauth signature
var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&status={6}";
var baseString = string.Format(baseFormat,
oauth_consumer_key,
oauth_nonce,
oauth_signature_method,
oauth_timestamp,
oauth_token,
oauth_version,
Uri.EscapeDataString(status)
);
baseString = string.Concat("POST&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));
var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
"&", Uri.EscapeDataString(oauth_token_secret));
string oauth_signature;
using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
{
oauth_signature = Convert.ToBase64String(
hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
}
// create the request header
var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
"oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
"oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
"oauth_version=\"{6}\"";
var authHeader = string.Format(headerFormat,
Uri.EscapeDataString(oauth_nonce),
Uri.EscapeDataString(oauth_signature_method),
Uri.EscapeDataString(oauth_timestamp),
Uri.EscapeDataString(oauth_consumer_key),
Uri.EscapeDataString(oauth_token),
Uri.EscapeDataString(oauth_signature),
Uri.EscapeDataString(oauth_version)
);
// make the request
var postBody = "status=" + Uri.EscapeDataString(status);
ServicePointManager.Expect100Continue = false;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);
request.Headers.Add("Authorization", authHeader);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (Stream stream = request.GetRequestStream())
{
byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody);
stream.Write(content, 0, content.Length);
}
WebResponse response = request.GetResponse();
}
}
}
Twittter Developer reference is below-
https://dev.twitter.com/oauth/overview/single-user
Also we have samples to explain integration using tweetsharp as below-
http://www.codeproject.com/Articles/584666/Twitter-Client-Login-to-Csharp-application-using-t
also we need to check whether our sample is referring to
https://api.twitter.com/1.1/ - new
or
https://api.twitter.com/1/- old
Thursday, August 27, 2015
Tuesday, August 25, 2015
Check the due date for all open Cases once a day and set ‘Exceeding SLA’ indication if due date has passed
In this post i will describe some of the scenarios and solutions-
- Check the due date for all open Cases once a day and set ‘Exceeding SLA’ indication if due date has passed
- Send monthly news letter automatically to target customers
- Update MSCRM Users details from Active Directory once a day
- Once a month, disqualify all leads with no open activities
Below is the link to above scenarios
https://mscrm2015asynchronousbatchprocess.codeplex.com/
- Check the due date for all open Cases once a day and set ‘Exceeding SLA’ indication if due date has passed
- Send monthly news letter automatically to target customers
- Update MSCRM Users details from Active Directory once a day
- Once a month, disqualify all leads with no open activities
Below is the link to above scenarios
https://mscrm2015asynchronousbatchprocess.codeplex.com/
Monday, August 3, 2015
An item with same key has already been added.
Entity avproductionstatistic = new Entity("mer_avproductionstatistic");
avproductionstatistic.Id = Guid.Empty;
if (avproductionstatistic.Contains("mer_avproductionstatisticid"))
avproductionstatistic.Attributes.Remove("mer_avproductionstatisticid");
Sunday, July 26, 2015
Call external web service from CRM 2011 using jquery
<!DOCTYPE html><html xmlns:s><head>
<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
//Called this method on any button click event for Testing
$(document).ready(function(){
$("button").click(function(){
jQuery.support.cors = true;
var soapData = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">' + '<s:Body><GetData xmlns="http://tempuri.org/"><value>500</value></GetData></s:Body></s:Envelope>';
$.ajax({
type: "POST",
contentType: "text/xml; charset=utf-8",
dataType: "xml",
url: "http://localhost:61373/Service1.svc",
data: soapData,
beforeSend: function (xhr) {
xhr.setRequestHeader("SOAPAction", "http://tempuri.org/IService1/GetData");
},
success: RetrieveCallbackSuccess,
error: RetrieveCallbackError
});
});
function RetrieveCallbackSuccess(response) { alert("Yey! :) --> " + response.text); }
function RetrieveCallbackError(err) { alert("Onoz! :( --> " + err.statusText); }
});
</script>
</head><body>
<button>tset</button>
</body></html>
WCF Service
<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
//Called this method on any button click event for Testing
$(document).ready(function(){
$("button").click(function(){
jQuery.support.cors = true;
var soapData = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">' + '<s:Body><GetData xmlns="http://tempuri.org/"><value>500</value></GetData></s:Body></s:Envelope>';
$.ajax({
type: "POST",
contentType: "text/xml; charset=utf-8",
dataType: "xml",
url: "http://localhost:61373/Service1.svc",
data: soapData,
beforeSend: function (xhr) {
xhr.setRequestHeader("SOAPAction", "http://tempuri.org/IService1/GetData");
},
success: RetrieveCallbackSuccess,
error: RetrieveCallbackError
});
});
function RetrieveCallbackSuccess(response) { alert("Yey! :) --> " + response.text); }
function RetrieveCallbackError(err) { alert("Onoz! :( --> " + err.statusText); }
});
</script>
</head><body>
<button>tset</button>
</body></html>
WCF Service
Call external service from CRM webpage in CRM 2011
<!DOCTYPE html><html xmlns:soap><head>
<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
//Called this method on any button click event for Testing
$(document).ready(function(){
$("button").click(function(){
var soapRequest="<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap="+
"\"http://schemas.xmlsoap.org/soap/envelope/\" "+
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "+
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<soap:Body>"+
"<GetData xmlns=\'http://tempuri.org/\'>"+
"<value>500</value>"+
"</GetData>"+
" </soap:Body>"+
"</soap:Envelope>";
var xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
xmlHttp.open("post","http://localhost:61373/Service1.svc", false);
xmlHttp.setRequestHeader("Content-Type","text/xml; charset=utf-8");
xmlHttp.setRequestHeader("Content-Length", soapRequest.length);
xmlHttp.setRequestHeader("SOAPAction","http://tempuri.org/IService1/GetData ");
xmlHttp.send(soapRequest);
var responseXML=xmlHttp.responseXML;
alert(responseXML.text);
});
});
</script>
</head><body>
<button>test</button>
</body></html>
WCF SERVICE
<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
//Called this method on any button click event for Testing
$(document).ready(function(){
$("button").click(function(){
var soapRequest="<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap="+
"\"http://schemas.xmlsoap.org/soap/envelope/\" "+
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "+
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<soap:Body>"+
"<GetData xmlns=\'http://tempuri.org/\'>"+
"<value>500</value>"+
"</GetData>"+
" </soap:Body>"+
"</soap:Envelope>";
var xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
xmlHttp.open("post","http://localhost:61373/Service1.svc", false);
xmlHttp.setRequestHeader("Content-Type","text/xml; charset=utf-8");
xmlHttp.setRequestHeader("Content-Length", soapRequest.length);
xmlHttp.setRequestHeader("SOAPAction","http://tempuri.org/IService1/GetData ");
xmlHttp.send(soapRequest);
var responseXML=xmlHttp.responseXML;
alert(responseXML.text);
});
});
</script>
</head><body>
<button>test</button>
</body></html>
WCF SERVICE
Retrieve Record Asynchronously using Soap in CRM 2011/2013
// <snippetSDK.RetrieveData.js>
if (typeof (SDK) == "undefined")
{
SDK = { __namespace: true };
}
// Namespace container for functions in this library.
SDK.RetrieveData =
{
_Context: function () {
var errorMessage = "Context is not available.";
if (typeof GetGlobalContext != "undefined") {
return GetGlobalContext();
}
else {
if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else {
return new Error(errorMessage);
}
}
},
_ServerUrl: function () {///<summary>
/// Private function used to establish the path to the SOAP endpoint based on context
/// provided by the Xrm.Page object or the context object returned by the GlobalContext object.
///</summary>
var ServerUrl = this._Context().getServerUrl();
if (ServerUrl.match(/\/$/)) {
ServerUrl = ServerUrl.substring(0, ServerUrl.length - 1);
}
return ServerUrl + "/XRMServices/2011/Organization.svc/web";
},
RetrieveRequestAsync: function (entityLogicalName, Id, columnSet, successCallBack, errorCallBack) {
// debugger;
var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
request += "<request i:type=\"a:RetrieveRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
request += "<a:KeyValuePairOfstringanyType>";
request += "<b:key>Target</b:key>";
request += "<b:value i:type=\"a:EntityReference\">";
request += "<a:Id>" + Id + "</a:Id>";
request += "<a:LogicalName>" + entityLogicalName + "</a:LogicalName>";
request += "<a:Name i:nil=\"true\" />";
request += "</b:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "<a:KeyValuePairOfstringanyType>";
request += "<b:key>ColumnSet</b:key>";
request += "<b:value i:type=\"a:ColumnSet\">";
if (columnSet != null && columnSet.length > 0) {
request += "<a:AllColumns>false</a:AllColumns>";
}
else {
request += "<a:AllColumns>true</a:AllColumns>";
}
request += "<a:Columns xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
if (columnSet != null && columnSet.length > 0) {
for (var i = 0; i < columnSet.length; i++) {
request += "<c:string>" + columnSet[i] + "</c:string>";
}
}
request += "</a:Columns>";
request += "</b:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "</a:Parameters>";
request += "<a:RequestId i:nil=\"true\" />";
request += "<a:RequestName>Retrieve</a:RequestName>";
request += "</request>";
request += "</Execute>";
request = this._getSOAPWrapper(request);
var req = new XMLHttpRequest();
req.open("POST", this._ServerUrl(), true);
req.setRequestHeader("Accept", "application/xml, text/xml, */*");
req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
req.setRequestHeader("SOAPAction", this._Action.Execute);
req.onreadystatechange = function () { SDK.RetrieveData._returnRetrieveRequest(req, successCallBack, errorCallBack) };
req.send(request);
},
_returnRetrieveRequest: function (resp, successCallBack, errorCallBack) {
if (resp.readyState == 4 /* complete */) {
if (resp.status == 200) {
//Success
// var entityAttributesNodes = resp.responseXML.selectNodes("//a:Attributes/a:KeyValuePairOfstringanyType");
// var attributeCollection = new Array();
// for (var i = 0; i < entityAttributesNodes.length; i++) {
// var attribute = this._getAttributeData(entityAttributesNodes[i]);
// attributeCollection.push(attribute);
// }
var attributeCollection = new Array();
var xmlDoc = $.parseXML(resp.responseText);
$xml = $(xmlDoc);
//$xml.find("c\\:OptionMetadata, OptionMetadata")
$xml.find('a\\:Attributes, Attributes').find('a\\:KeyValuePairOfstringanyType, KeyValuePairOfstringanyType').each(function () {
//attr
var attributeType = $(this).find("b\\:value, value")[0].attributes["i:type"].value; //KeyValuePairOfstringanyType.selectSingleNode("b:value").attributes.getNamedItem("i:type").text;
var attributeName = $(this).find("b\\:key, key").text(); //KeyValuePairOfstringanyType.selectSingleNode("b:key").text; //b:key
var attributeValue;
switch (attributeType) {
case "c:int":
case "c:string":
case "c:guid":
attributeValue = $(this).find("b\\:value, value").text(); //KeyValuePairOfstringanyType.selectSingleNode("b:value").text;
break;
case "a:Money":
case "a:OptionSetValue":
case "c:dateTime":
case "c:double":
case "c:decimal":
case "c:boolean":
//attributeValue = KeyValuePairOfstringanyType.parentNode.parentNode.selectNodes("a:FormattedValues/a:KeyValuePairOfstringstring[b:key='" + attributeName + "']/b:value")[0].text;
var temp = $($(this)[0].parentNode.parentNode).find("a\\:FormattedValues, FormattedValues").find("a\\:KeyValuePairOfstringstring, KeyValuePairOfstringstring").filter(function () {
return $(this).find("b\\:key, key").text() === attributeName;
});
attributeValue = $(temp).find("b\\:value, value").text();
//$($(temp)[0].parentNode).find("b\\:value").text();
break;
case "a:EntityReference":
//a:Name
attributeValue = $(this).find("b\\:value, value").find("a\\:Name, Name").text()//KeyValuePairOfstringanyType.selectSingleNode("b:value/a:Name").text;
break;
default:
attributeValue = $(this).find("b\\:value, value").text(); // KeyValuePairOfstringanyType.selectSingleNode("b:value").text;
}
var attribute = new Object();
attribute.attributeName = attributeName;
attribute.attributeValue = attributeValue;
attribute.displayName = "";
attributeCollection.push(attribute);
});
successCallBack(attributeCollection);
}
else {
errorCallBack(this._getError(resp));
}
}
},
_getAttributeData: function (KeyValuePairOfstringanyType) {
var attributeType = KeyValuePairOfstringanyType.selectSingleNode("b:value").attributes.getNamedItem("i:type").text;
var attributeName = KeyValuePairOfstringanyType.selectSingleNode("b:key").text; //b:key
var attributeValue;
switch (attributeType) {
case "c:int":
case "c:string":
case "c:guid":
attributeValue = KeyValuePairOfstringanyType.selectSingleNode("b:value").text;
break;
case "a:Money":
case "a:OptionSetValue":
case "c:dateTime":
case "c:double":
case "c:decimal":
case "c:boolean":
attributeValue = KeyValuePairOfstringanyType.parentNode.parentNode.selectNodes("a:FormattedValues/a:KeyValuePairOfstringstring[b:key='" + attributeName + "']/b:value")[0].text
break;
case "a:EntityReference":
//a:Name
attributeValue = KeyValuePairOfstringanyType.selectSingleNode("b:value/a:Name").text;
break;
default:
attributeValue = KeyValuePairOfstringanyType.selectSingleNode("b:value").text;
}
var attribute = new Object();
attribute.attributeName = attributeName;
attribute.attributeValue = attributeValue;
attribute.displayName = "";
return attribute;
},
_Action: {
Execute: "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute"
},
_getSOAPWrapper: function (request) {
///<summary>
/// Private function that wraps a soap envelope around a request.
///</summary>
var SOAP = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>";
SOAP += request;
SOAP += "</soapenv:Body></soapenv:Envelope>";
return SOAP;
},
_getError: function (resp) {
///<summary>
/// Private function that attempts to parse errors related to connectivity or WCF faults.
///</summary>
///<param name="resp" type="XMLHttpRequest">
/// The XMLHttpRequest representing failed response.
///</param>
//Error descriptions come from http://support.microsoft.com/kb/193625
if (resp.status == 12029)
{ return new Error("The attempt to connect to the server failed."); }
if (resp.status == 12007)
{ return new Error("The server name could not be resolved."); }
var faultXml = resp.responseXML;
var errorMessage = "Unknown (unable to parse the fault)";
if (typeof faultXml == "object") {
var bodyNode = faultXml.firstChild.firstChild;
//Retrieve the fault node
for (var i = 0; i < bodyNode.childNodes.length; i++) {
var node = bodyNode.childNodes[i];
//NOTE: This comparison does not handle the case where the XML namespace changes
if ("s:Fault" == node.nodeName) {
for (var j = 0; j < node.childNodes.length; j++) {
var faultStringNode = node.childNodes[j];
if ("faultstring" == faultStringNode.nodeName) {
errorMessage = faultStringNode.text;
break;
}
}
break;
}
}
}
return new Error(errorMessage);
},
__namespace: true
};
// </snippetSDK.RetrieveData.js>
if (typeof (SDK) == "undefined")
{
SDK = { __namespace: true };
}
// Namespace container for functions in this library.
SDK.RetrieveData =
{
_Context: function () {
var errorMessage = "Context is not available.";
if (typeof GetGlobalContext != "undefined") {
return GetGlobalContext();
}
else {
if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else {
return new Error(errorMessage);
}
}
},
_ServerUrl: function () {///<summary>
/// Private function used to establish the path to the SOAP endpoint based on context
/// provided by the Xrm.Page object or the context object returned by the GlobalContext object.
///</summary>
var ServerUrl = this._Context().getServerUrl();
if (ServerUrl.match(/\/$/)) {
ServerUrl = ServerUrl.substring(0, ServerUrl.length - 1);
}
return ServerUrl + "/XRMServices/2011/Organization.svc/web";
},
RetrieveRequestAsync: function (entityLogicalName, Id, columnSet, successCallBack, errorCallBack) {
// debugger;
var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
request += "<request i:type=\"a:RetrieveRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
request += "<a:KeyValuePairOfstringanyType>";
request += "<b:key>Target</b:key>";
request += "<b:value i:type=\"a:EntityReference\">";
request += "<a:Id>" + Id + "</a:Id>";
request += "<a:LogicalName>" + entityLogicalName + "</a:LogicalName>";
request += "<a:Name i:nil=\"true\" />";
request += "</b:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "<a:KeyValuePairOfstringanyType>";
request += "<b:key>ColumnSet</b:key>";
request += "<b:value i:type=\"a:ColumnSet\">";
if (columnSet != null && columnSet.length > 0) {
request += "<a:AllColumns>false</a:AllColumns>";
}
else {
request += "<a:AllColumns>true</a:AllColumns>";
}
request += "<a:Columns xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
if (columnSet != null && columnSet.length > 0) {
for (var i = 0; i < columnSet.length; i++) {
request += "<c:string>" + columnSet[i] + "</c:string>";
}
}
request += "</a:Columns>";
request += "</b:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "</a:Parameters>";
request += "<a:RequestId i:nil=\"true\" />";
request += "<a:RequestName>Retrieve</a:RequestName>";
request += "</request>";
request += "</Execute>";
request = this._getSOAPWrapper(request);
var req = new XMLHttpRequest();
req.open("POST", this._ServerUrl(), true);
req.setRequestHeader("Accept", "application/xml, text/xml, */*");
req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
req.setRequestHeader("SOAPAction", this._Action.Execute);
req.onreadystatechange = function () { SDK.RetrieveData._returnRetrieveRequest(req, successCallBack, errorCallBack) };
req.send(request);
},
_returnRetrieveRequest: function (resp, successCallBack, errorCallBack) {
if (resp.readyState == 4 /* complete */) {
if (resp.status == 200) {
//Success
// var entityAttributesNodes = resp.responseXML.selectNodes("//a:Attributes/a:KeyValuePairOfstringanyType");
// var attributeCollection = new Array();
// for (var i = 0; i < entityAttributesNodes.length; i++) {
// var attribute = this._getAttributeData(entityAttributesNodes[i]);
// attributeCollection.push(attribute);
// }
var attributeCollection = new Array();
var xmlDoc = $.parseXML(resp.responseText);
$xml = $(xmlDoc);
//$xml.find("c\\:OptionMetadata, OptionMetadata")
$xml.find('a\\:Attributes, Attributes').find('a\\:KeyValuePairOfstringanyType, KeyValuePairOfstringanyType').each(function () {
//attr
var attributeType = $(this).find("b\\:value, value")[0].attributes["i:type"].value; //KeyValuePairOfstringanyType.selectSingleNode("b:value").attributes.getNamedItem("i:type").text;
var attributeName = $(this).find("b\\:key, key").text(); //KeyValuePairOfstringanyType.selectSingleNode("b:key").text; //b:key
var attributeValue;
switch (attributeType) {
case "c:int":
case "c:string":
case "c:guid":
attributeValue = $(this).find("b\\:value, value").text(); //KeyValuePairOfstringanyType.selectSingleNode("b:value").text;
break;
case "a:Money":
case "a:OptionSetValue":
case "c:dateTime":
case "c:double":
case "c:decimal":
case "c:boolean":
//attributeValue = KeyValuePairOfstringanyType.parentNode.parentNode.selectNodes("a:FormattedValues/a:KeyValuePairOfstringstring[b:key='" + attributeName + "']/b:value")[0].text;
var temp = $($(this)[0].parentNode.parentNode).find("a\\:FormattedValues, FormattedValues").find("a\\:KeyValuePairOfstringstring, KeyValuePairOfstringstring").filter(function () {
return $(this).find("b\\:key, key").text() === attributeName;
});
attributeValue = $(temp).find("b\\:value, value").text();
//$($(temp)[0].parentNode).find("b\\:value").text();
break;
case "a:EntityReference":
//a:Name
attributeValue = $(this).find("b\\:value, value").find("a\\:Name, Name").text()//KeyValuePairOfstringanyType.selectSingleNode("b:value/a:Name").text;
break;
default:
attributeValue = $(this).find("b\\:value, value").text(); // KeyValuePairOfstringanyType.selectSingleNode("b:value").text;
}
var attribute = new Object();
attribute.attributeName = attributeName;
attribute.attributeValue = attributeValue;
attribute.displayName = "";
attributeCollection.push(attribute);
});
successCallBack(attributeCollection);
}
else {
errorCallBack(this._getError(resp));
}
}
},
_getAttributeData: function (KeyValuePairOfstringanyType) {
var attributeType = KeyValuePairOfstringanyType.selectSingleNode("b:value").attributes.getNamedItem("i:type").text;
var attributeName = KeyValuePairOfstringanyType.selectSingleNode("b:key").text; //b:key
var attributeValue;
switch (attributeType) {
case "c:int":
case "c:string":
case "c:guid":
attributeValue = KeyValuePairOfstringanyType.selectSingleNode("b:value").text;
break;
case "a:Money":
case "a:OptionSetValue":
case "c:dateTime":
case "c:double":
case "c:decimal":
case "c:boolean":
attributeValue = KeyValuePairOfstringanyType.parentNode.parentNode.selectNodes("a:FormattedValues/a:KeyValuePairOfstringstring[b:key='" + attributeName + "']/b:value")[0].text
break;
case "a:EntityReference":
//a:Name
attributeValue = KeyValuePairOfstringanyType.selectSingleNode("b:value/a:Name").text;
break;
default:
attributeValue = KeyValuePairOfstringanyType.selectSingleNode("b:value").text;
}
var attribute = new Object();
attribute.attributeName = attributeName;
attribute.attributeValue = attributeValue;
attribute.displayName = "";
return attribute;
},
_Action: {
Execute: "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute"
},
_getSOAPWrapper: function (request) {
///<summary>
/// Private function that wraps a soap envelope around a request.
///</summary>
var SOAP = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>";
SOAP += request;
SOAP += "</soapenv:Body></soapenv:Envelope>";
return SOAP;
},
_getError: function (resp) {
///<summary>
/// Private function that attempts to parse errors related to connectivity or WCF faults.
///</summary>
///<param name="resp" type="XMLHttpRequest">
/// The XMLHttpRequest representing failed response.
///</param>
//Error descriptions come from http://support.microsoft.com/kb/193625
if (resp.status == 12029)
{ return new Error("The attempt to connect to the server failed."); }
if (resp.status == 12007)
{ return new Error("The server name could not be resolved."); }
var faultXml = resp.responseXML;
var errorMessage = "Unknown (unable to parse the fault)";
if (typeof faultXml == "object") {
var bodyNode = faultXml.firstChild.firstChild;
//Retrieve the fault node
for (var i = 0; i < bodyNode.childNodes.length; i++) {
var node = bodyNode.childNodes[i];
//NOTE: This comparison does not handle the case where the XML namespace changes
if ("s:Fault" == node.nodeName) {
for (var j = 0; j < node.childNodes.length; j++) {
var faultStringNode = node.childNodes[j];
if ("faultstring" == faultStringNode.nodeName) {
errorMessage = faultStringNode.text;
break;
}
}
break;
}
}
}
return new Error(errorMessage);
},
__namespace: true
};
// </snippetSDK.RetrieveData.js>
Create dynamic HTML and populate with CRM data
//LookupPreviewScript.js
///<reference path="XrmPage-vsdoc.js"/>
var XrmPage;
var popWindow;
var _VerticalLayout = "V";
var _HorizontalLayout = "H";
var _ZLayout = "Z";
var _NLayout = "N";
function LoadLookPreviewDelayed(webResourceId, lookupAttributeId, columnList, layout)
{
myFn = function(){LoadLookPreview(webResourceId, lookupAttributeId, columnList, layout);}
setTimeout(myFn, 2000);
Xrm.Page.getAttribute(lookupAttributeId.toLowerCase()).addOnChange(myFn);
}
function FormHTMLTable(divTag, controlSet, layout)
{
var str = "";
if(layout == _VerticalLayout)
{
str = "<table><tbody>";
for(var k=0; k < controlSet.length; k++){
str += "<tr>";
str += "<td class='headerCss'>" + controlSet[k].attributeDisplayName + "</td>";
str += "<td>" + controlSet[k].attributeValue + "</td>";
str += "</tr>";
}
str += "</tbody></table>";
}
else if(layout == _ZLayout)
{
str = '<table>';
str += '<tbody>';
for (var j = 0; j < controlSet.length; j++) {
var index = j + 1;
str += "<tr>"
str += "<td class='headerCss'>" + controlSet[j].attributeDisplayName + "</td>";
str += "<td>" + controlSet[j].attributeValue + "</td>";
str += "<td class='seperator'></td>";
if(index < controlSet.length)
{
str += "<td class='headerCss'>" + controlSet[index].attributeDisplayName + "</td>";
str += "<td>" + controlSet[index].attributeValue + "</td>";
}
str += "</tr>"
j++;
}
str += '</tbody>'
str += '</table>';
}
else if(layout == _NLayout)
{
str = '<table>';
str += '<tbody>';
var half = Math.round(controlSet.length / 2)
for (var j = 0; j < controlSet.length; j++) {
var index = j + half;
if (j < half) {
str += "<tr>"
str += "<td class='headerCss'>" + controlSet[j].attributeDisplayName + "</td>";
str += "<td>" + controlSet[j].attributeValue + "</td>";
str += "<td class='seperator'></td>";
if (index < controlSet.length) {
str += "<td class='headerCss'>" + controlSet[index].attributeDisplayName + "</td>";
str += "<td>" + controlSet[index].attributeValue + "</td>";
}
str += "</tr>"
}
}
str += '</tbody>'
str += '</table>';
}
else
{
str = "<table><thead><tr>";
for(var k=0; k < controlSet.length; k++){
str += "<th>" + controlSet[k].attributeDisplayName + "</th>";
}
str += "</tr></thead><tbody><tr>";
for (var i = 0; i < controlSet.length; i++){
str += "<td>" + controlSet[i].attributeValue + "</td>";
}
str += "</tr></tbody></table>";
}
divTag.innerHTML = str;
$(divTag).slideDown(1000);
}
function LoadLookPreview(webResourceId, lookupAttributeId, columnList, layout)
{
var divTag;
var webResource = Xrm.Page.getControl(webResourceId);
var columnSet = new Array();
var columnHeaders = new Array();
var controlSet = new Array();
successCallBack = function (attributeCollection) {
for(var k=0; k < controlSet.length; k++)
{
for (var i = 0; i < attributeCollection.length; i++)
{
if(attributeCollection[i].attributeName == controlSet[k].attributeLogicalName)
{
controlSet[k].attributeValue = attributeCollection[i].attributeValue;
break;
}
}
}
FormHTMLTable(divTag, controlSet, layout);
};
errorCallBack = function (error) {
divTag.innerHTML = "<span class='error'>" + error.message + "</span>";
$(divTag).slideDown(500);
};
if(webResource == null)
{
alert('No WebResource found with Id = ' + webResourceId);
}
else
{
divTag = document.getElementById(webResourceId).contentWindow.document.getElementById('lookupDIV');
if(divTag != null)
{
divTag.display = "none";
var columns = columnList.split('|');
for(var i = 0 ; i < columns.length; i++)
{
var s = columns[i].split('#');
var _control = new Object();
_control.attributeDisplayName = s[0];
_control.attributeLogicalName = s[1].toLowerCase().replace(/^\s+|\s+$/g, '')
_control.attributeValue = '';
controlSet.push(_control);
columnSet.push(s[1].toLowerCase().replace(/^\s+|\s+$/g, ''));
}
if(Xrm.Page.getAttribute(lookupAttributeId.toLowerCase()) != null && Xrm.Page.getAttribute(lookupAttributeId.toLowerCase()).getValue() != null)
{
var id = Xrm.Page.getAttribute(lookupAttributeId).getValue()[0].id;
var entityName = Xrm.Page.getAttribute(lookupAttributeId).getValue()[0].entityType;
SDK.RetrieveData.RetrieveRequestAsync(entityName, id, columnSet, successCallBack, errorCallBack);
}
else
{
FormHTMLTable(divTag, controlSet, layout);
}
}
else
{
alert("Error in Loading Web Resource (DIV is NULL)")
}
}
}
Thursday, July 16, 2015
Tuesday, June 30, 2015
Monday, June 8, 2015
Displaying Iframe in CRM 2013
function Form_onload() {
//var EntityId = Xrm.Page.getAttribute("projectid").getValue();
//alert (EntityId);
if (Xrm.Page.data.entity.getId() != "") {
var oId = Xrm.Page.data.entity.getId();
var oType = 10014;
var security = "852023";
Xrm.Page.getControl("IFRAME_HistoryFrame").setSrc("userdefined/areas.aspx?oId=" + oId + "&oType=" + oType + "&pagemode=iframe&security=" + security + "&tabSet=areaActivityHistory&rof=false&inlineEdit=1");
Xrm.Page.getControl("IFRAME_ActivitiesFrame").setSrc("userdefined/areas.aspx?oId=" + oId + "&oType=" + oType + "&pagemode=iframe&security=" + security + "&tabSet=areaActivities&rof=false&inlineEdit=1");
}
else {
Xrm.Page.getControl("IFRAME_HistoryFrame").setSrc("about:blank");
Xrm.Page.getControl("IFRAME_ActivitiesFrame").setSrc("about:blank");
}
}
Tuesday, April 28, 2015
Monday, April 6, 2015
Thursday, February 19, 2015
C# Delegates, Actions, Funcs, Lambdas–Keeping it super simple
C# Delegates, Actions, Funcs, Lambdas–Keeping it super simple
RATE THIS
2 Mar 2012 4:46 PM
Syntactic Sugar? Maybe.
[ Updated to reflect a reader’s observation – missing Func<> coverage. Now included ]
I was speaking with a colleague of mine today, Bret Stateham (http://bretstateham.com) and I was explaining my ignorance to some well established C# language constructs. I’ve always avoided language constructs that translate into “less typing.” What I mean is, delegates, actions, and lambdas can be totally avoided and you can still build the most sophisticated software. The compiler steps in at compile time and generates the IL for you (intermediate language), that language that gets translated into CPU-specific machine language at runtime by the CLR (Common language runtime).
Conceptually, and for the most part, it looks like Figure 1 below. The “Regular C# code” is probably skipped, meaning the fancy C# code ends up directly as IL. Anders Hejlsberg, the creator of C# (and the former creator of Borland’s Turbo Pascal) has spoken in detail about the inter-workings of the C# compiler in the past.
Figure 1
[ BTW, one day I’ll talk about what an amazing human being Anders is. He is the most humble, approachable, computer science genius I’ve ever met ].
Anders Hejlsberg Interview | http://www.microsoft.com/downloads/details.aspx?FamilyID=B202A125-DC9C-495A-8A5A-7BF98BECACE2&displaylang=e&displaylang=en |
Let’s start with a simple delegate example
A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate.
Code is the best teacher.
Part 1 | Helps the compiler with type safety |
Part 2 | One of the methods associated with the delegate |
Part 3 | The other method associated with the delegate |
Part 4 | Our object used to demo delegates with |
Part 5 | Declare a delegate and attach a method from the demo object |
Part 6 | Declare a delegate and attach the other method from the demo object |
Part 7 | Exercise the first delegate. In other words, use it to do work. |
Part 8 | Exercise the second delegate. In other words, use it to do work. |
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ModernLanguageConstructs { class Program { // Part 1 - Explicit declaration of a delegate (helps a compiler ensure type safety) public delegate double delegateConvertTemperature(double sourceTemp); // A sample class to play with class TemperatureConverterImp { // Part 2 - Will be attached to a delegate later in the code public double ConvertToFahrenheit(double celsius) { return (celsius * 9.0/5.0) + 32.0; } // Part 3 - Will be attached to a delegate later in the code public double ConvertToCelsius(double fahrenheit) { return (fahrenheit - 32.0) * 5.0 / 9.0; } } static void Main(string[] args) { // Part 4 - Instantiate the main object TemperatureConverterImp obj = new TemperatureConverterImp(); // Part 5 - Intantiate delegate #1 delegateConvertTemperature delConvertToFahrenheit = new delegateConvertTemperature(obj.ConvertToFahrenheit); // Part 6 - Intantiate delegate #2 delegateConvertTemperature delConvertToCelsius = new delegateConvertTemperature(obj.ConvertToCelsius); // Use delegates to accomplish work // Part 7 - delegate #1 double celsius = 0.0; double fahrenheit = delConvertToFahrenheit(celsius); string msg1 = string.Format("Celsius = {0}, Fahrenheit = {1}", celsius, fahrenheit); Console.WriteLine(msg1); // Part 8 - delegate #2 fahrenheit = 212.0; celsius = delConvertToCelsius(fahrenheit); string msg2 = string.Format("Celsius = {0}, Fahrenheit = {1}", celsius, fahrenheit); Console.WriteLine(msg2); } } } |
C# Actions – More sugar, please
You can use the Action(Of T) delegate to pass a method as a parameter without explicitly declaring a custom delegate. The sugar here is you don’t have to declare a delegate. The compiler is smart enough to figure out the proper types.
But you pay a price in terms of a limitation. The corresponding method action must not return a value. (In C#, the method must return void.)
Part 1 | The Action syntax avoids the use of a declared delegate. Everything is inline. |
Part 2 | The Action syntax avoids the use of a declared delegate. Everything is inline. |
Part 3 | Execute the corresponding Action code |
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ModernLanguageConstructs { class Program { static void Main(string[] args) { // Part 1 - First action that takes an int and converts it to hex Action<int> displayHex = delegate(int intValue) { Console.WriteLine(intValue.ToString("X")); }; // Part 2 - Second action that takes a hex string and // converts it to an int Action<string> displayInteger = delegate(string hexValue) { Console.WriteLine(int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber)); }; // Part 3 - exercise Action methods displayHex(16); displayInteger("10"); } } } |
Func<> Delegates
This differs from Action<> in the sense that it supports parameters AND return values.
You can use this delegate to represent a method that can be passed as a parameter without explicitly declaring a custom delegate. The encapsulated method must correspond to the method signature that is defined by this delegate.
This means that the encapsulated method must have one parameter that is passed to it by value, and that it must return a value.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ModernLanguageConstructs { class Program { static void Main(string[] args) { // Part 1 - First Func<> that takes an int and returns a string Func<int, string> displayHex = delegate(int intValue) { return (intValue.ToString("X")); }; // Part 2 - Second Func<> that takes a hex string and // returns an int Func<string, int> displayInteger = delegate(string hexValue) { return (int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber)); }; // Part 3 - exercise Func<> delegates Console.WriteLine(displayHex(16)); Console.WriteLine(displayInteger("10")); } } } |
Lambdas – Syntactic Sugar Squared
I’ve been staring at Lambdas for years and for whatever reason they don’t come natural to me. Maybe I need to spend more time in a functional language like F# to make them a natural construct.
A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.
All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block.
The lambda expression x => x * x is read "x goes to x times x."
Part 1 | Declare 2 lambda expressions |
Part 2 | Run them. |
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ModernLanguageConstructs { class Program { static void Main(string[] args) { // Part 1 - An action and a lambda Action<int> displayHex = intValue => { Console.WriteLine(intValue.ToString("X")); }; Action<string> displayInteger = hexValue => { Console.WriteLine(int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber)); }; // Part 2 - Use the lambda expressions displayHex(16); displayInteger("10"); } } } |
Lambdas and Queries
Lambda expressions can also be used to simplify queries.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ModernLanguageConstructs { class Program { static void Main(string[] args) { // Part 1 - ordinary list object List<string> listPets = new List<string>(); // Part 2 - Queryable list object IQueryable<string> queryPets = listPets.AsQueryable(); listPets.Add("dog"); listPets.Add("cat"); listPets.Add("iguana"); // Part 3 - Lambda Expression (does not use curly braces) string result1 = listPets.First(x => x.StartsWith("d")); Console.WriteLine(result1); // Prints "dog" // Part 4 - Lambda expressions using iQueryable interface string result2 = queryPets.First(x => x.StartsWith("ig")); Console.WriteLine(result2); // Prints "iguana" // Part 5 - Lambda Statement (uses curly braces) // Supports the return statement result1 = listPets.First(x => { return x.EndsWith("a"); }); Console.WriteLine(result1); // Prints "iguana" // Part 6 - Does not compile // A lambda expression with a statement body // cannot be converted to an expression tree // result2 = queryPets.First(x => { return x.EndsWith("e"); }); // Part 7 - Does compile using the Func<T> syntax // You can pass in a lambda expression and it // will be compiled to an Expression(Of TDelegate). string result3 = queryPets.First((Func<string, bool>) (x => { return x.EndsWith("g"); })); Console.WriteLine(result3); // Prints "dog" // Part 8 - Convert to IQueryable IEnumerable<string> result4 = listPets.AsQueryable().Where(pet => pet.Length == 3); foreach (string pet in result4) Console.WriteLine(pet); // Prints "dog" then "cat" } } } |
Want to help?
If you’ve got some super simple examples to demonstrate advance language features, please forward them tobterkaly@microsoft.com.
The next dragon I want to slay is Dependency Injection and Inversion of Control. I want to explain these two concepts in as little code as possible. Hope you got some value out of this post.
Subscribe to:
Posts (Atom)