William Ryan, W.G. Ryan, Bill Ryan, Kim Ryan, Search Engine Optimization, Online Reputation Management, Dynamics CRM 2011, Microsoft Dynamics, Windows Phone 7, Silverlight 4.0, Windows Communication Foundation, Workflow Foundation, R Programming, Python Programming, Python NLTK, Natural Language Processing
I’m not a particular fan of Democracy Now (while they’re good on civil rights and privacy, most of what they complain about is the natural outgrowth of policies they advocate) but find this discussion particularly convincing.
The reason I find it so compelling is the reasoning ascribed to the government, it’s quite typical from how they’ve handled things in the past. For instance, individuals don’t get warrants served on them individually. Rather, their ISP gets the warrant presented to it. HOWEVER the ISP is legally barred from informing you about it, so you never know it happened. If you don’t know it happened, and can’t accumulate evidence of it, then there’s not much you can do to assert your rights.
While I find this generally pretty credible, some of it is a little hard to believe. Accumulating essentially ‘all’ the email being sent domestically would be a insanely large undertaking. It would take some really hard to fathom storage mechanisms just to hold it. Holding the data isn’t of much use so it needs to be searchable. That makes things even more challenging. An undertaking of that size generally would have to involve a pretty large number of people and it seems there’d be a little more noise about it. Additionally, having dealt with the Secret Service and the FBI a few times, I have to admit, I was rather shocked by how *unsophisticated* they were in technical terms. The NSA is a different beast, but the level of competency required here doesn’t seem commensurate with my experience with other agencies. (I know, that doesn’t necessarily mean anything – but I’m throwing it out there anyway).
Whatever the case, this warrants (no pun intended) a lot more attention and if it turns out to be true, heads should roll. They won’t if it’s true, but they should.
KeyWords: William Binney, Jacob Applebaum, NSA Wiretapping, Democracy Now
Federal Judge Mark Bennett issued a rule which is not only terrible in terms of its privacy implications, it creates legal chaos by effectively having different laws in different parts of the country. Wired.com‘s ThreatLevel covers the story of Federal Judge Mark Bennett’s ruling on Law Enforcement’s use of GPS tracking.
U.S. District Judge Mark Bennett in Sioux City ruled last week (.pdf) that the GPS tracking evidence gathered by federal DEA agents last year against suspected drug trafficker Angel Amaya, prior to the Supreme Court ruling, can be submitted in court because the agents were acting in good faith at the time. The agents, the judge said, were relying on what was then a binding 8th U.S. Circuit Court of Appeals precedent that authorized the use of warrantless GPS trackers for surveillance in Iowa and six other states.
![]()
There was a time that complaints about the country’s march toward a police state were reserved to cookdom, but increasingly, denying that march is what crazies believe. Electronic Freedom Foundation’s Hanni Fakhoury calls the ruling for what it is:
[I]t is a bit of an end-run around for law enforcement. And it leads to disparate results because whether [GPS evidence] gets suppressed or not depends on what the law of the circuit was prior to Jones…If we’re going to apply the law one way in half the country and another way in the other half of the country, that’s a real problem
Even if you happen to agree with the Good Faith Exception argument, it’s hard to see how anyone can defend the actions of law enforcement in this. Outside of trespassing on Amaya’s property to plant the GPS originally, change the batteries and change the unit several times, law enforcement reportedly manufactured a police stop where they swapped the device out again. How is this acceptable behavior for law enforcement?
A GPS tracker was also placed on another vehicle Amaya was driving after agents learned from a court-authorized wiretap that he was planning a secret trip to Texas. This time, it appears that agents arranged for police to pull over the blue Nissan Murano, and then covertly attached the device [emphasis added].
Next thing you know we’ll be hearing about federal agents gun running to the cartels so that people get killed and they can justify increased gun control. Or federal agents using their positions to settle personal disputes.
Read the whole thing here and make sure to peruse the comments.
KeyWords: Federal Judge Mark Bennett, Electronic Freedom Foundation, Hanni Fakhoury, Angel Amaya, Good Faith Exception, Katie Pavlich, Erroll Southers, United States v. Jones, Antione Jones
I’ve already written a few posts about the CrmConnection class and how easy it is to use. While it’s a pretty simple object to work with, I’m surprised at how much interest there seems to be in it. Other than the name of a chronic pain in my a55, the terms CrmConnection and OrganizationService are the two most commonly searched and referred terms to this blog. Recently, I’ve been responsible for developer training for Dynamics CRM 2011 and started things off with showing people how to connect and use both the CrmConnection and IOrganizationService. To really drive the point home, I decided to use Telerik’s wonderful Just Decompile to disassemble the Microsoft.Xrm.Client.dll and the Microsoft.Xrm.Sdk.dll to show the inner workings of how many of the commonly used classes are built. With that in mind, let’s take a look under the hood at the CrmConnection object.
After loading the Microsoft.Xrm.Client.dll into Just Decompile, you’ll be presented with each of the classes available in the Microsoft.Xrm.Client namespace. Drilling down into the CrmConnection, you should see something roughly approximating this:
So 
So nothing too shocking here right. After all, we know the CrmConnection is just a wrapper, syntactical sugar as they sometimes refer to such things, for the items you need to authenticate to OrganizationService. You see the ClientCredentials property which should come as no surprise, the DeviceCredentials property which should come as no surprise if you’ve connected to Crm Online and the ServiceUri. You see the default constructor as well as each of the overloaded constructors, including one which takes a connectionString name and one that takes an actual connectionStringSettings item. Drilling down into the overload that takes in the connectionString name, you see the following definition:
public CrmConnection(string connectionStringName) : this(CrmConnection.GetConnectionStringSettings(connectionStringName)) { }
That leads one to naturally wonder what GetConnectionStringSettings looks like right?
private static ConnectionStringSettings GetConnectionStringSettings(string connectionStringName) { ConnectionStringSettings item = ConfigurationManager.ConnectionStrings[connectionStringName]; if (item != null) { return item; } else { object[] objArray = new object[1]; objArray[0] = connectionStringName; throw new ConfigurationErrorsException("Unable to find a connection string with the name '{0}'.".FormatWith(objArray)); } }
Nothing too surprising there, right? If you’re like me, you’re wondering where all the parsing happens. I mean, where do things like the DeviceId and DeviceCredentials get parsed out of the connectionString so they can be used in the call to the OrganizationService? One natural guess might be to take a look at the CrmConnection.Parse method (even though we don’t see an explicit call, you tend to think it’s being called somewhere along the lines). CrmConnection.Parse is particular unremarkable:
public static CrmConnection Parse(string connectionString) { return new CrmConnection(connectionString.ToDictionary()); }
Now is where things get a little interesting. Remember the public constructors? There was a default constructor which had no parameters, there was one that took in a string parameter (corresponding to the connectionString name) and one that took in a parameter of connectionStringSettings. None of them took in a Dictionary. Well, none of the public constructors do anyway. If you look carefully at the Just Compile output, you’ll see two other private constructors present. The first of them takes in a generic Dictionary. The second one basically takes in every other thing under the sun.
Looking at the constructor employing the Dictionary, things start to get very clear very quickly:
private CrmConnection(IDictionary<string, string> connection) { string[] strArrays = new string[4]; strArrays[0] = "ServiceUri"; strArrays[1] = "Service Uri"; strArrays[2] = "Url"; strArrays[3] = "Server"; string[] strArrays1 = new string[2]; strArrays1[0] = "HomeRealmUri"; strArrays1[1] = "Home Realm Uri"; string[] strArrays2 = new string[1]; strArrays2[0] = "Domain"; string[] strArrays3 = new string[4]; strArrays3[0] = "UserName"; strArrays3[1] = "User Name"; strArrays3[2] = "UserId"; strArrays3[3] = "User Id"; string[] strArrays4 = new string[1]; strArrays4[0] = "Password"; string[] strArrays5 = new string[4]; strArrays5[0] = "DeviceId"; strArrays5[1] = "Device Id"; strArrays5[2] = "DeviceUserName"; strArrays5[3] = "Device User Name"; string[] strArrays6 = new string[2]; strArrays6[0] = "DevicePassword"; strArrays6[1] = "Device Password"; string[] strArrays7 = new string[1]; strArrays7[0] = "Timeout"; string[] strArrays8 = new string[2]; strArrays8[0] = "ProxyTypesEnabled"; strArrays8[1] = "Proxy Types Enabled"; string[] strArrays9 = new string[2]; strArrays9[0] = "ProxyTypesAssembly"; strArrays9[1] = "Proxy Types Assembly"; string[] strArrays10 = new string[2]; strArrays10[0] = "CallerId"; strArrays10[1] = "Caller Id"; string[] strArrays11 = new string[2]; strArrays11[0] = "ServiceConfigurationInstanceMode"; strArrays11[1] = "Service Configuration Instance Mode"; string[] strArrays12 = new string[2]; strArrays12[0] = "UserTokenExpiryWindow"; strArrays12[1] = "User Token Expiry Window"; this(connection.FirstNotNullOrEmpty<string>(strArrays), connection.FirstNotNullOrEmpty<string>(strArrays1), connection.FirstNotNullOrEmpty<string>(strArrays2), connection.FirstNotNullOrEmpty<string>(strArrays3), connection.FirstNotNullOrEmpty<string>(strArrays4), connection.FirstNotNullOrEmpty<string>(strArrays5), connection.FirstNotNullOrEmpty<string>(strArrays6), connection.FirstNotNullOrEmpty<string>(strArrays7), connection.FirstNotNullOrEmpty<string>(strArrays8), connection.FirstNotNullOrEmpty<string>(strArrays9), connection.FirstNotNullOrEmpty<string>(strArrays10), connection.FirstNotNullOrEmpty<string>(strArrays11), connection.FirstNotNullOrEmpty<string>(strArrays12)); }
You might have to read the code a time or two before it makes sense, but what you see is basically a placeholder for each of the values that comprise a CrmConnection ConnectionString and a means by which you can pass in a literal name or a friendly name and still get to the same place. The second ‘everything under the sun ‘ constructor is much more, well, what I would have expected to see. Why? Because as you look through it, it looks pretty much exactly like the code we used to connect to the CrmService with did before we had the luxury of using the CrmConnecti0n. Admittedly it’s rather long, but if you look at it carefully, it makes perfect sense and is quite easy to follow:
private CrmConnection(string serviceUri, string homeRealmUri, string domain, string userName, string password, string deviceId, string devicePassword, string timeout, string proxyTypesEnabled, string proxyTypesAssembly, string callerId, string serviceConfigurationInstanceMode, string userTokenExpiryWindow) { bool flag; object uri; object obj; TimeSpan? nullable; TimeSpan? nullable1; object obj1; ServiceConfigurationInstanceMode @enum; CrmConnection crmConnection = this; if (!string.IsNullOrWhiteSpace(serviceUri)) { uri = new Uri(serviceUri); } else { uri = null; } crmConnection.ServiceUri = (Uri)uri; CrmConnection crmConnection1 = this; if (!string.IsNullOrWhiteSpace(homeRealmUri)) { obj = new Uri(homeRealmUri); } else { obj = null; } crmConnection1.HomeRealmUri = (Uri)obj; if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password)) { if (!string.IsNullOrWhiteSpace(userName) || !string.IsNullOrWhiteSpace(password)) { throw new ConfigurationErrorsException("The specified user credentials are invalid."); } } else { ClientCredentials clientCredential = new ClientCredentials(); if (string.IsNullOrWhiteSpace(domain)) { clientCredential.UserName.UserName = userName; clientCredential.UserName.Password = password; } else { clientCredential.Windows.ClientCredential = new NetworkCredential(userName, password, domain); } this.ClientCredentials = clientCredential; } if (string.IsNullOrWhiteSpace(deviceId) || string.IsNullOrWhiteSpace(devicePassword)) { if (!string.IsNullOrWhiteSpace(deviceId) || !string.IsNullOrWhiteSpace(devicePassword)) { throw new ConfigurationErrorsException("The specified device credentials are invalid."); } } else { ClientCredentials clientCredential1 = new ClientCredentials(); clientCredential1.UserName.UserName = deviceId; clientCredential1.UserName.Password = devicePassword; this.DeviceCredentials = clientCredential1; } CrmConnection crmConnection2 = this; if (!string.IsNullOrWhiteSpace(timeout)) { nullable = new TimeSpan?(TimeSpan.Parse(timeout)); } else { TimeSpan? nullable2 = null; nullable = nullable2; } crmConnection2.Timeout = nullable; CrmConnection crmConnection3 = this; if (!string.IsNullOrWhiteSpace(userTokenExpiryWindow)) { nullable1 = new TimeSpan?(TimeSpan.Parse(userTokenExpiryWindow)); } else { TimeSpan? nullable3 = null; nullable1 = nullable3; } crmConnection3.UserTokenExpiryWindow = nullable1; if (!bool.TryParse(proxyTypesEnabled, ref flag)) { flag = CrmConnection._defaultProxyTypesEnabled; } this.ProxyTypesEnabled = flag; CrmConnection crmConnection4 = this; if (!string.IsNullOrWhiteSpace(proxyTypesAssembly)) { obj1 = Assembly.Load(proxyTypesAssembly); } else { obj1 = null; } crmConnection4.ProxyTypesAssembly = (Assembly)obj1; if (!string.IsNullOrWhiteSpace(callerId)) { this.CallerId = new Guid?(new Guid(callerId)); } CrmConnection crmConnection5 = this; if (!string.IsNullOrWhiteSpace(serviceConfigurationInstanceMode)) { @enum = serviceConfigurationInstanceMode.ToEnum<ServiceConfigurationInstanceMode>(); } else { @enum = CrmConnection._defaultServiceConfigurationInstanceMode; } crmConnection5.ServiceConfigurationInstanceMode = @enum; }
So yes, this may be a little anti-climactic, after all what we ultimately showed is pretty much what you’d expect to see in the first place. But there are a few takeaways I’d pay attention to. First, it shows that with a little thought, you can abstract away a lot of code which becomes essentially unnecessary. Comparing the one line it takes to instantiate a CrmConnection with the multiple lines it takes to get to the same place without it, it’s clear that one approach will be a lot easier for people to learn, understand, use and maintain.
The other takeaway is with respect to building your own Microsoft Dynamics CRM 2011 development libraries. Although I haven’t actually tried to confirm it, I’ve heard from many people that the CrmConnection concept, as well as the OrganizationServiceContext (and the whole Entity Framework style approach to CRM development) were both created by the very talented folks at AdxStudio. Their product was so compelling that Microsoft either purchased or licensed it from AdxStudio so they could include it in the CRM 2011 SDK. (While I certainly don’t advocate rumor mongering, I’m pretty sure this rumor is true and since it’s a pretty flattering rumor in any case, I figured it’d be ok to mention, at least until I can confirm it). In any case, with a little thought and empathy for the developer, Shan and the guys at AdxStudio took something that was inelegant and generally considered a pain in the butt, and made it absolutely painless. I’m willing to bet that there are quite a few other brilliant and convenient ideas out there just waiting to be implemented by someone who’s frustrated by doing the same thing over and over. Think about using the same philosophy coupled with Extension methods. Do you think there’s some elegancy and simplicity possible if you coupled those two ideas together? B/c the CRM API has been maturing so quickly, a lot of things have yet to catch up – tooling being one clear example. There’s still a lot that’s quite cumbersome and error prone to write. Such things cause endless delays on CRM deployments and frustrate new CRM developers to no end.
I bet if you were to dig around the SDK libraries using Just Decompile (or your disassembler of choice) you’d find quite a few other interesting tidbits and probably at least a handful of opportunities to greatly simplify your future CRM 2011 development. Sure, Microsoft gave us several useful classes in their SDK, but no one says those have to be the ones you use. There’s nothing stopping you from creating YourCompany.Xrm.Client.dll or the YourCompany.Xrm.Client namespace. And if you have some ideas but don’t have the time to implement them, please feel free to post them below or write me privately – I can’t promise you I’ll have time to create them, but I’ll seriously consider anything sent my way and if time permits, I’ll be glad to take a stab at implementation and share the credit – heck this might be a good time to start a CodePlex project with just such a goal in mind.
Leave any questions in the Comments section, or write me directly: bil…@williamgryan.mobi – /b/ill
William Ryan, MBA, MVP, MCTS
————————————————————–
KeyWords: CrmConnection, Microsoft.Xrm.Client.CrmConnection, CrmConnection Class, Microsoft.Xrm.Sdk.Entity,Microsoft Dynamics CRM 2011, Crm 2011, Dynamics CRM 2011, William Ryan , Bill Ryan, CrmConnection.Parse, Crm 2011 CrmConnection, OrganizationService, OrganizationServiceContext, Just Decompile, AdxStudio, CodePlex, Microsoft.Xrm.Client.dll, Microsoft.Xrm.Sdk.dll
Just a quick announcement to any SharePoint afficianados in the audience, the lovely and talented Mrs Kim Ryan is now blogging about SharePoint Administration at http://www.sharepoint-hen.com . The site was just launched but there should be content coming very soon so make sure to check back frequently.
Leave any questions in the Comments section, or write me directly: bil…@williamgryan.mobi /b/ill
William Ryan, MBA, MVP, MCTS
————————————————————–
KeyWords: Kimberly Ryan, Kim Ryan, SharePoint Hen, Sharepoint-hen.com William Ryan , Bill Ryan, Microsoft SharePoint 2010, MOSS 2010, MOSS 2007, SharePoint Server Content Management, SharePoint Workflows
Although the OrganizationServiceContext is the primary object we’ll be demonstrating, there are others that directly relate to it. Throughout my code samples, I reference three items that I use throughout:
B/c all interaction with the CRM API involves using a reference to the OrganizationService web service, these three objects (well, a combination of 2 of them) are necessary for most of the classes you’ll build when doing Crm 2011 development (the notable exception is with Plugins or Workflows b/c you already have a live reference to the OrganizationService). Depending on the overall requirements, I’ll typically build an interface named ICrmConsumer or a base class called CrmConsumerBase. My code samples throughout the site assume the classes either implement the ICrmConsumer interface or inherit from the CrmConsumerBase class:
public interface ICrmConsumer { #region properties CrmConnection ConnectionInstance { get; set; } OrganizationService OrgServiceInstance { get; set; } OrganizationServiceContext OrgServiceContextInstance { get; set; } #endregion }
When using a class that implements this interface, simply make sure to instantiate each of the objects in the constructor. Assuming a class called DemoCrmService, here’s what the implementation would look like:
public class DemoCrmService : ICrmConsumer { #region constructor public DemoCrmService() { ConnectionInstance = new CrmConnection("CrmMain"); OrgServiceInstance = new OrganizationService(ConnectionInstance); OrgServiceContextInstance = new OrganizationServiceContext(OrgServiceContextInstance); } #endregion #region properties public CrmConnection ConnectionInstance { get; set; } public OrganizationService OrgServiceInstance { get; set; } public OrganizationServiceContext OrgServiceContextInstance { get; set; } #endregion }
You can basically do the same thing with a base class. The important thing in either case is instantiating the correct objects in the constructor of before they’re used. The decision to use a base class or an interface is something that can be debated at length so I’m not really going to get into it here. This however is one case where the base class would serve the purpose really well. In any case, assume that these are defined when looking at any of my samples.
Leave any questions in the Comments section, or write me directly: bil…@williamgryan.mobi – /b/ill
William Ryan, MBA, MVP, MCTS
————————————————————–
KeyWords: Microsoft.Xrm.Sdk.Entity, Crm 2011, Dynamics CRM 2011, William Ryan , Bill Ryan, RelatedEntities, LinkEntity, LinkEntities, CrmConnection, OrganizationService, OrganizationServiceContext
The OrganizationServiceContext is one of the 4 primary ways you have to query data in Microsoft Dynamics CRM 2011. In the Microsoft.Xrm.Sdk.Query.QueryExpression in Depth Part II, I walked through using the QueryExpression class and how to convert to and from FetchXml. One key to getting things working is the CrmConnection class which I’ve discussed in depth in several different posts.
The OrganizationServiceContext is the Microsoft Dynamics Crm equivalent of the Entity Framework and provides a very elegant way of interacting with the CRM Api. While many would argue that using the Early Bound approach (and with Crm, Early Bound and Late Bound aren’t true Early and Late binding but appear to superficially) is really necessary to get the benefits from using the OrganizationServiceContext , you can use the Late Bound methodology and still greatly simplify development semantics. Keep in mind however that there are many vocal advocates of using FetchXml (which has all the downside of late binding , doesn’t provide intellisense support and doesn’t provide type checking) so opinions vary greatly on what constitutes the ‘best’ way of interacting with Crm data.
The first step to using OrganizationServiceContext is creating a reference to a valid CrmConnection. Once you have that reference you can instantiate an instance of the OrganizationService. Once you have a reference to the OrganizationService, you can easily instantiate a new OrganizationServiceContext by simply passing in the OrganizationService instance to the constructor.
CrmConnection ConnectionInstance = new CrmConnection("CrmMain"); OrganizationService OrgServiceInstance = new OrganizationService(ConnectionInstance); OrganizationServiceContext OrgContext = new OrganizationServiceContext(OrgServiceInstance);
Now, if you use the Early Bound method and generate a context from the CrmSvcUtil, you’ll have a specific OrganizationServiceContext named (whatever you name it
) like CrmOrganizationServiceContext.
Once you have the OrganizationServiceContext you use the CreateQuery method, passing in a String corresponding to the name of the entity (or if you have the proxies set up, you can use the actual entity name itself. Below are two examples showing how to create simple queries using the OrganizationServiceContext
CrmConnection ConnectionInstance = new CrmConnection("CrmMain"); OrganizationService OrgServiceInstance = new OrganizationService(ConnectionInstance); var OrgContext = new OrganizationServiceContext(OrgServiceInstance); OrganizationServiceContext Matches = OrgContext.CreateQuery("contact").First(contact => contact["firstname"].ToString() == "william" && contact["lastname"].ToString() == "ryan");
CrmConnection ConnectionInstance = new CrmConnection("CrmMain"); OrganizationService OrgServiceInstance = new OrganizationService(ConnectionInstance); var OrgContext = new OrganizationServiceContext(OrgServiceInstance); Decimal AverageAge = OrgContext.CreateQuery("contact").Average(age => Convert.ToDecimal(DateTime.Now - Convert.ToDateTime(age["dateofbirth"])));
So the key is to use the CreateQuery method which takes in either an Entity type name or a String representing the entity logical name. Since this focuses on using the Late Bound methodology, more times then now you’ll be using the String option. It’s worth noting that while all of my examples illustrate queries, if you wanted to create an entity or update an entity, you’d just need to make sure it belonged to the context and then you’d just call the SaveChanges method.
Regarding queries though, you have the full functionality of LINQ when writing queries. Remember back in the QueryExpression article you could join Entities using the LinkEntity class? Well, you use the Join method if you’re using LINQ. Below, going back to the Incident entity and Seminar entity, we’re going to do a join and create two new types, Incident and Seminar:
var Seminars = from inc in OrgContext.CreateQuery("incident") join sem in OrgContext.CreateQuery("seminar") on inc["incidentid"] equals sem["incidentid"] where Convert.ToString(inc["casename"]) == "Advance Dynamics CRM 2011" && inc["sponsor"].ToString() == "William Ryan" where (Convert.ToDateTime(sem["startdate"]) == DateTime.Parse("03/20/2012")) select new { Incident = new{ Casename = inc["casename"], Sponsor = inc["sponsor"], Topic = inc["topic"] }, Seminar = new{ BeginDate = sem["startdate"], EndDate = sem["enddate"], Instructor = sem["instructor"], Cost = sem["cost"] } }; foreach (var seminar in Seminars) { Console.WriteLine("------------------Incident Info-------------"); Console.WriteLine("CaseName: {0}", seminar.Incident.Casename); Console.WriteLine("------------------Seminar Info-------------"); Console.WriteLine("CaseName: {0}", seminar.Seminar.BeginDate); Console.WriteLine("CaseName: {0}", seminar.Seminar.EndDate); Console.WriteLine("CaseName: {0}", seminar.Seminar.Instructor); Console.WriteLine("CaseName: {0}", seminar.Seminar.Cost); }
A screen capture of the fully execute code sample is shown below:
As far as I know, there’s no conversion method to convert a OrganizationServiceContext query to a QueryExpression or FetchXml query. However I think one has to exist. That’s b/c all queries go through the API ultimately so I’m pretty sure somewhere along the lines there’s a conversion going on. I haven’t found the conversion yet but I’ll be digging. I’d highly recommend that you turn on Sql Server Profiler (assuming you’re using Crm 2011 OnPremises and have database access) and see what’s going on underneath the hood. One frequent criticism of the Entity Framework that many dev and dba’s level is that the queries aren’t optimal. I’ve found that to be marginally correct, but b/c the queries go through the API, it’s instructional to see.

Currently, I’m working on some more advanced queries and I’ll post as I get them done. /b/ill
William Ryan, MBA, MVP, MCTS
————————————————————–
KeyWords: Microsoft.Xrm.Sdk.Entity, Crm 2011, Dynamics CRM 2011, William Ryan , Bill Ryan, RelatedEntities, LinkEntity, LinkEntities, CrmConnection, OrganizationService, FilterExpression, QueryExpression,OrganizationServiceContext , LINQ
On a recent project, we were using the OrganizationService, CrmConnection and the Late Bound methodology to build several WCF Services to interact with Microsoft Dynamics CRM 2011.
We experienced some really bizarre behavior which at first, seemed a little hard to understand. We had the following ConnectionString defined for the CrmConnection (I’m obfuscating the client specific values):
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <clear/> <add name="Main" connectionString="Url=https://***.crminstance/OrgName; Username=***; password=***; /> </connectionStrings> </configuration>
For the first day, I was the only one running the application so nothing seemed out of place. The next day, we had two more developers running the application and all the methods worked as well. We had several more developers start the day after that and two of them had problems. The key point is that everyone was making calls to the services deployed to the Test Environment which used the same connectionString. A few of us were out to lunch and one of the developers, being new to Crm development, assumed that the problem was that he wasn’t a Crm User. This was totally reasonable b/c after each call failed, he attempted to look in Crm to see if he could figure out what went wrong and received and error message indicating he wasn’t a user. After each of the newest devs were added to Crm, their calls started working.
When I got back and heard about the problems, another developer and I started to take a look at things. The other developer noted that each of the records created were created by the person running the code. That seemed really strange. At the same time, I noticed that the password we used for the account was outdated.
Now this was strange- how could this code be running at all? After all the password being used was clearly wrong. The code worked, the Unit Tests passed so we had bigger fish to fry that day although it was something we definitely wanted to circle back around to as soon as we had a few minutes.
All afternoon it bugged me – how could this be working at all? And why weren’t the records being created with the correct owner? I started looking around and decided to change a few things. Originally, the code instantiating the CrmConnection was defined using one of the overloaded constructors:
CrmConnection PrimaryConnection = new CrmConnection("Main");
We changed the code to use the static Parse method of the CrmConnection:
CrmConnection PrimaryConnection = CrmConnection.Parse("Url=https://***.dynamics.com; Username=***; password=***;");
Not surprisingly, this didn’t change anything (proving only that the overloaded constructor and the Parse method both worked as advertised). I decided to start from scratch and changed the connectionString as follows:
<connectionStrings> <clear/> <add name="Main" connectionString="Url=https://***.dynamics.com; Username=***; password=***; Domain="DomainName"/> </connectionStrings>
Then it all became clear. And of course, this corrected the problem. Can you see what it was? Well, here’s what happened (keep in mind that the initial connectionString had a bad password). When the attempt is made to instantiate the connectionString, it’s parsed and the credentials are used. Since the connectionString had an invalid password, things didn’t work. Once the password was fixed, it was missing the Domain name. So in both cases, the cached user credentials for the user running the code was used. Once the domain was added and the password was corrected, the parse operation ran successfully and a valid user and password was found on the domain, so the specified user credentials were passed in.
One other thing worth throwing in. Securing your connectionStrings is an important security consideration and there are built in mechanism for securing your connectionString information. Frequently however companies will chose to use an existing Cryptography library to Encrypt and Decrypt their data. Assume then, that you were using a custom library that had a Static Decrypt method. You can use it in conjunction with the Parse method (b/c the overloaded constructors use the Name of the connectionString or a ConnectionStringSetting object):
String DecryptedConnectionString
= CryptoLibrary.Decrypt(ConfigurationManager.ConnectionStrings["CrmMain"].ConnectionString;
var connection = CrmConnection.Parse(DecryptedConnectionString);
And once you have a valid CrmConnection, creating an OrganizationService or
CrmOrganizationServiceContext is as easy as passing it into the respective object's constructor:
String DecryptedConnectionString = CryptoLibrary.Decrypt(ConfigurationManager.ConnectionStrings["CrmMain"].ConnectionString; var ConnectionInstance = CrmConnection.Parse(DecryptedConnectionString); // Declare and Instantiate OrganizationService var ServiceInstance = new OrganizationService(ConnectionInstance); // OR???
// Declare and Instantiate CrmOrganizationServiceContext
String DecryptedConnectionString = CryptoLibrary.Decrypt(ConfigurationManager.ConnectionStrings["CrmMain"].ConnectionString; var ConnectionInstance = CrmConnection.Parse(DecryptedConnectionString); var ContextInstance = new CrmOrganizationServiceContext(ConnectionInstance);
KeyWords: Microsoft.Xrm.Sdk.Entity, Crm 2011, Dynamics CRM 2011, William Ryan , Bill Ryan, RelatedEntities, CrmConnection, Microsoft.Xrm.Client, CrmOrganizationServiceContext , OrganizationService, CrmConnection.Parse, CrmConnection.Parse
SEO or Search Engine Optimization is the subject of a lot of discussion these days. That’s b/c significant placement on a prominent search engine can result in a tremendous amount of money. Most of the techniques you’ll read about focus on Google, but Bing, Yahoo and various others are really important too.
Before going too much further, let me point out a few things (some of these things are pretty ridiculous to point out, but when you have to deal with some ridiculous people reading your blog, you have to say ridiculous things).
For now though, we’ll focus on the Surface Web. What sorts of things matter? Well, no discussion of SEO would be complete without discussing Page Rank but it’s discussed in so many places, I’m going to assume you’re familiar with it. While theory matters quite a bit, most people want a list of steps they can walk through to try to maximize the impact of their page. So for now, let’s do that:
1-Incoming links are critical. But not all incoming links are equal. Sites deemed as SPAM don’t contribute much to your ranking (and can have a negative impact). Links coming from Educational domains have the highest Mojo (.edu). That’s why you’ll see spammers try to hard to target .edu domains. Businesses, sites that hvae been around a long time, sites with a solid reputation etc are next in the list.
2-The title of the page matters. Ideally, you want a title that includes the Search Word(s) that you want to emphasize – ideally you want these words at the beginning of the page title.
3-You want the Target words to appear in the first paragraph.
4-You want to use Header tags as much as possible (<H1>, <H2>, <H3> etc)
5-Images help elevate the ranking, and the ALT text is the main way images are identified. This is why pretty much every commercial site you can think of has images (often reused, annoying stock images) on every single post.
6-Meta tags used to be the holy grail of SEO. They are still important but need to accurately match the content in the post. If you have a Meta tag that doesn’t appear in the content, it won’t matter much. On the other hand, if the word in the meta tag appears 15 times in your post, and has three images with it in the ALT text, it’ll have a much greater bearing.
7-Long run on sentences riddled with 5 dollar words reduce the Flesch Reading Ease score. This makes a page harder to read generally. And the harder to read, the harder it is for programs and bots using Natural Language Processing to process them. As someone who has written hundreds of bots (in fact there are 5 actively watching this site as I type or you read this), trust me when I say that even small deviations in writing style add a LOT of complexity to readability from a programming POV.
8- The Page Title and the Meta description should be used (Page Title has a limit of 70 Characters, 155 for Meta tags for Google) to the largest extent possible. If they are shorter, then the search engines will typically fill them in with other items (such as Date). Items longer than the limits are truncated – so make sure you put your most important words first if you’re going over the limit).
9-Well formed markup helps readability by bots tremendously.
10-Make sure you use a SiteMap.xml if possible and make sure you’re not disallowing Robots from crawling your site.
11-Linking to other sites, particular ones that have relevant content is generally considered a net positive.
12-The more incoming links you have, the better, particularly from highly regarded sights
13-Keeping your site clear of SPAM links, Pr0n links, hate site links and other undesirable links is a very good idea (for reasons not just related to SEO).
14-You want to use your keywords liberally through your content, but don’t overdo it. There’s a point at which it starts looking like you’re gaming the system which backfires. Similarly, you want to use Heading tags as mentioned earlier, as well as the <Strong> or <B> tag on your keywords, but don’t use it on every word. Typically, using it around the first and/or second (at most) appearances is plenty.
15-Make sure you change the anchor text on tags – you can have the same pattern in general, but not the exact same text repeated.
16-Content is king. So many people overthink the internet. How many companies do you know nowadays that have a Facebook page? (I’ve recently seen a one man shop landscaping guy with his facebook page url on his truck. Really?). Nothing , NOTHING is a substitute for good content. Ultimately, this is a situation of “get it right and the rest will follow”. Additionally, keep in mind that having a #1 position on Google or Yahoo doesn’t automatically mean people will buy your stuff. Sure, it’ll help a lot when it comes to Advertising revenue, but that alone isn’t going to pay the bills unless you really have a lot of it. Personally, at the high point, I was bringing in about 2k a month of ad revenue – nothing to sneeze at but certainly not enough to pay the bills.
17- Frequent and legitimate updates greatly enhance ranking. A dead sight might still have some high ranks, but dead sights don’t tend to get crawled that frequently. Having new content appear, and appear on a regular basis can greatly contribute to rank.
18-Make sure outbound links are working. It’s impossible to ensure all outbound links are working all the time if you write much, but test them regularly and update them as frequently as you can.
19-Make sure that the vast majority of your pages have outbound links (and hopefully inbound ones although you don’t have much control over that directly) but that there’s more to it than links. Link sites are considered the sign of spammers (b/c that’s what spammers do frequently). S0 make sure that 90% of more of the pages have < 100 links on each page. If you aren’t trying to spam or game the system you won’t have any problem here.
20- Keep spam off of your pages. I get deluged with Spam, on this site, close to 100 links a day. Spam causes two problems. First, there are some real morons in this world and can’t tell the difference between a blog post and a blog comment. Even though you can PROVE you didn’t post something, even if it is clearly a spam post, that won’t stop histrionic nutjobs intent of making problems for you from claiming you , directly or indirectly, posted the stuff.
21- Try to ensure that each of your pages has a valid Author <meta> tag.
22-Use a Title tag for your hyperlinks about 50% of the time. I don’t have specifics on this, but apparently having a Title for every tag is considered a bad sign as spammers have traditionally done this to try to game the rankings (just like they did with Meta tags back in the day). You want to use it as much as possible though without crossing the line. 50% is assumed to be a pretty safe number from what I’ve read and from personal experience.
23-Make sure your site has at least 5 pages of real , relevant content. This should be pretty easy if you’re even remotely trying to run a legit sight.
24-This should go without saying, but minimize server downtime. If you have 7 hours of consistent downtime, you’re going to be penalized. The less the better, and not just b/c of SEO either.
25- I left this for last as it’s one of the most important aspects, probably the most important. SEO isn’t something you just hit a button and perform. It’s an ongoing process. The Search Engines are constantly refining their processes. They are constantly detecting cheaters and working to minimize their impact (and punish them). Be very careful who you do business with if you’re farming out your SEO (you can spend years building a brand and one bad engagement with an unethical SEO consultant can destroy you). And keep in mind that it’s something that needs baked into the process, it needs to be done and adjusted regularly. Set aside time to make sure it’s done and done right. Like I mentioned above, check outgoing links on a regular basis to remove dead links. Bots pick up every single link you have – and they know immediately if it’s dead or not. You probably wont’ be as effective as they are, but you can do it regularly enough that your site is kept up to date.
————————-
That concludes my first pass at SEO techniques. There are literally hundreds more and they are more developing all the time. I’ll have a weekly update on this with at least 5 new techniques each week. And shortly, when I start the Bot Series, I’ll go into the Deep Web and what you can do to get recognized on it.
Leave any questions in the Comments section, or write me directly: bill@williamgryan.nospam.mobi (leave out the obvious part) – /b/ill
William Ryan, MBA, MVP, MCTS
————————————————————–
KeyWords: Bing, Google, Yahoo, William Ryan , Bill Ryan, SEO, Search Engine Optimization, Page Rank, Bot, Spider, Reputation Defender sucks, Reputation Defender is a scam
According to the Microsoft Dynamics CRM 2011 SDK Documentation, the purpose of the AssignRequest is:
Contains the data needed to assign the specified record to a new owner (user or team), changing the OwnerId attribute of the record.
It’s something you’ll find yourself doing pretty frequently on most development projects. Why? B/c you’ll often use a single CrmConnection to perform all of the operations the service provides. When you do this the Owner for each record will default to the User specified in the CrmConnection.
Since this scenario is something I have to do frequently, I decided to make use of C#’s Extension Methods to save myself a little coding hassle.
To use an AssignRequest and AssignResponse you need two things: First you simply need to know the Entity who’s owner you want to re-assign. Second you’ll need the Id of the SystemUser you’re changing the ownership to. When you’ve put all that in place, you just need to call the Execute method of the OrganizationService you are using. Hopefully the reference to the OrganizationSerivce should be simple to set up. If not, search for CrmConnection on this site for plenty of examples.
public static AssignResponse ChangeEntityOwner(this Entity entity, Guid newOwnerId) { � AssignResponse ChangeOwnerResponse = null; AssignRequest ChangeOwnerRequest = new AssignRequest { Assignee = new EntityReference(SystemUser.EntityLogicalName, newOwnerId), Target = new EntityReference(entity.LogicalName, entity.Id) }; ChangeOwnerResponse = OrgServiceInstance.Execute(ChangeOwnerRequest) as AssignResponse; return ChangeOwnerResponse; }
You almost always want to have exception handling and logging in place when working with the OrganizationService. Extension methods like this will typically be part of an API. Hence, it’s usually best to handle the exceptions in the caller.
Once the Extension method is defined, each time you type Entity (Microsoft.Xrm.Sdk.Entity) you’ll see the method available via intellisense.
Let’s illustrate it with a simple example. First, I’ll declare and instantiate a simple contact entity. Then, I’ll set a few properties. Next I’ll call the Create method of the OrganizationService instance. Finally, I’ll call the ChangeEntityOwner method passing in the Guid of the SystemUser you want to grant ownership to:
public static void CreateAndChangeOwner() { Entity NewContact = new Entity("contact"); NewContact["firstname"] = "Evil"; NewContact["middlename"] = "Devil"; NewContact["lastname"] = "Cuckoo"; NewContact["accountid"] = new Guid("901D63BA-9F08-4bb2-BCF9-128CBE5705D3"); Guid AssignedSystemUser = new Guid("A98A51CD-1J91-3ac2-BCF9-235FAZ6707F8"); // Call Create on OrganizationService to create new Contact Guid NewContactId = OrgServiceInstance.Create(NewContact); // Change Owner by using Extension Method AssignResponse ChangeOwner = NewContact.ChangeEntityOwner(AssignedSystemUser); }
Notice the important part is called out in Bold and Italic – to truly get the feel for it I’m attaching a screen shot which shows the Intellisense support , something that makes the Extension method approach all the more useful:

Leave any questions in the Comments section, or write me directly: bill@williamgryan.nospam.mobi (leave out the obvious part) – /b/ill
William Ryan, MBA, MVP, MCTS
————————————————————–
KeyWords: Microsoft.Xrm.Sdk.Entity, Crm 2011, Dynamics CRM 2011, William Ryan , Bill Ryan, RelatedEntities, CrmConnection, Microsoft.Xrm.Client, OrganizationServiceContext , AssignResponse, AssignRequest, C#, Extension Method, EntityReference, SystemUser
There’s been quite a bit of discussion lately about meteors predicted to hit earth. This latest one, DA14 (which isn’t all that big but predicted to hit really soon, isn’t all that terrifying, but I guess terrifying depends a lot on where it’s going to hit.
According to the article:
To avert a possible catastrophe – this time set for February 2013 – scientists suggest confronting asteroid 2012 DA14 with either paint or big guns. The stickler is that time has long run out to build a spaceship to carry out the operation.
NASA’s data shows the 60-meter asteroid, spotted by Spanish stargazers in February, will whistle by Earth in 11 months. Its trajectory will bring it within a hair’s breadth of our planet, raising fears of a possible collision.
The asteroid, known as DA14, will pass by our planet in February 2013 at a distance of under 27,000 km (16,700 miles). This is closer than the geosynchronous orbit of some satellites.
I like the idea of blasting the hell out of it, but that’s out of the question at the moment. One of the more creative ideas however is painting it. Seriously, painting DA14:
“We could paint it,” says NASA expert David Dunham.
Paint would affect the asteroid’s ability to reflect sunlight, changing its temperature and altering its spin. The asteroid would stalk off its current course, but this could also make the boulder even more dangerous when it comes back in 2056, Aleksandr Devaytkin, the head of the observatory in Russia’s Pulkovo, told Izvestia.
Make sure to read the comments, they shed a lot of information on the proposed solutions.
Leave any questions in the Comments section, or write me directly: bill@williamgryan.nospam.mobi (leave out the obvious part) – /b/ill
William Ryan, MBA, MVP, MCTS
————————————————————–
KeyWords: William Ryan , Bill Ryan, Asteroids, Meteors, DA14, 2012 DA14

Categories
Tag Cloud
Blog RSS
Comments RSS
Last 50 Posts
Back
Back
Void « Default
Life
Earth
Wind
Water
Fire
Light 