MS CRM Dynamics in latest bound - how to discover all entities? - crm

I am building a connector to CRM Dynamics.
I would like to get (discover) all the entities with their fields.
There for, I am using the IOrganizationService interface with RetrieveAllEntitiesRequest.
I do get all the entities names BUT I don't know how to get all fields (columns) of any entity.
please help...
hagai

It sounds like your almost there. This it taken from the MSDN sample: Dump Attribute Metadata to a File.
RetrieveAllEntitiesRequest request = new RetrieveAllEntitiesRequest()
{
EntityFilters = EntityFilters.Attributes,
RetrieveAsIfPublished = true
};
// Retrieve the MetaData.
RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)_serviceProxy.Execute(request);
foreach (EntityMetadata currentEntity in response.EntityMetadata)
{
foreach (AttributeMetadata currentAttribute in currentEntity.Attributes)
{
Console.WriteLine("LogicalName: " + currentAttribute.LogicalName);
}
}

We need to create RetrieveAllEntitiesRequest first
RetrieveAllEntitiesRequest entityRequest = new RetrieveAllEntitiesRequest();
Then call the service.execute() to retrieve results
there is a blog post which explains really well.

Related

Relational Query - 2 degrees away

I have three models:
Timesheets
Employee
Manager
I am looking for all timesheets that need to be approved by a manager (many timesheets per employee, one manager per employee).
I have tried creating datasources and prefetching both Employee and Employee.Manager, but I so far no success as of yet.
Is there a trick to this? Do I need to load the query and then do another load? Or create an intermediary datasource that holds both the Timesheet and Employee data or something else?
You can do it by applying a query filter to the datasource onDataLoad event or another event. For example, you could bind the value of a dropdown with Managers to:
#datasource.query.filters.Employee.Manager._equals
- assuming that the datasource of the widget is set to Timesheets.
If you are linking to the page from another page, you could also call a script instead of using a preset action. On the link click, invoke the script below, passing it the desired manager object from the linking page.
function loadPageTimesheets(manager){
app.showPage(app.pages.Timesheets);
app.pages.Timesheets.datasource.query.filters.Employee.Manager._equals = manager;
app.pages.Timesheets.datasource.load();
}
I would recommend to redesign your app a little bit to use full power of App Maker. You can go with Directory Model (Manager -> Employees) plus one table with data (Timesheets). In this case your timesheets query can look similar to this:
// Server side script
function getTimesheets(query) {
var managerEmail = query.parameters.ManagerEmail;
var dirQuery = app.models.Directory.newQuery();
dirQuery.filters.PrimaryEmail._equals = managerEmail;
dirQuery.prefetch.DirectReports._add();
var people = dirQuery.run();
if (people.length === 0) {
return [];
}
var manager = people[0];
// Subordinates lookup can look fancier if you need recursively
// include everybody down the hierarchy chart. In this case
// it also will make sense to update prefetch above to include
// reports of reports of reports...
var subortinatesEmails = manager.DirectReports.map(function(employee) {
return employee.PrimaryEmail;
});
var tsQuery = app.models.Timesheet.newQuery();
tsQuery.filters.EmployeeEmail._in = subortinatesEmails;
return tsQuery.run();
}

Dynamics CRM Entity Data update from a custom Aspx Page

I have found many sample to create data in dynamics crm from a custom aspx page, but i need to update entity data.
any sample will be helpful.
Thanks
It's quite simple, when you create a record normally you use the following code:
Entity newContact = new Entity("contact");
contact["firstname"] = "John";
contact["lastname"] = "Smith";
service.Create(newContact);
If you need to update a record, you need to retrieve it first (using a Retrieve if you have the Guid, or a RetrieveMultiple if you need to find it using a query), after just update the fields.
Entity retrievedContact = service.Retrieve("contact", GuidOfTheRecord, ColumnsYouWantToRetrieve);
retrievedContact["firstname"] = "My New First Name";
retrievedContact["lastname"] = "My New Last Name";
service.Update(retrievedContact);

Retrieving a list of Tridion 2009 components with a specific value and schema without using search

I would like to create a .NET page residing on the CMS server that shows all components that are based on a specific Schema(tcm:3-3-8) and from a specific Publication(tcm:0-3-1) including BluePrinted and Localized items, but only if they have the value "http://www.google.com" for the field "URL" in that Schema.
Is this possible, without using the search service as this is rather slow and unreliable?
Your search might be slow because of not indexing the search collection.
You should do indexing the search collection on regular intervals for better and fast results.
That's an expensive operation to do because of the cost of opening each individual component to check the value of a field, but certainly do-able.
Get the schema object
Get a list of components that use this schema (WhereUsed on the schema with filter on ItemType = component)
Open each component and check the value for the field(s), add to a List<Component> if it matches
Display list (possibly using a ASP.NET GridView)
I have not had any chance to test it, but something like this
Common common = new Common();
TDSE tdse = new TDSE();
ListRowFilter ComponentFilter = tdse.CreateListRowFilter();
Schema schema = (Schema)common.getObject("tcm:126-238630-8", ItemType.ItemTypeSchema);
ComponentFilter.SetCondition("ItemType", ItemType.ItemTypeComponent);
ComponentFilter.SetCondition("Recursive", true);
XDocument doc = common.ReadXML(schema.Info.GetListUsingItems(ListColumnFilter.XMLListID, ComponentFilter));
List<Component> MatchedComponents = new List<Component>();
XmlNamespaceManager NS = new XmlNamespaceManager(new NameTable());
NS.AddNamespace("tcm", "http://www.tridion.com/ContentManager/5.0");
NS.AddNamespace("Content", "uuid:4432F3C3-9F3E-45E4-AE31-408C5C46E2BF");
foreach (XElement component in doc.XPathSelectElements("/tcm:ListUsingItems/tcm:Item", NS))
{
Component comp = common.getComponent(component.Attribute("ID").Value);
XDocument compDoc = common.ReadXML(comp.GetXML(XMLReadFilter.XMLReadData));
foreach (XElement compNode in compDoc.XPathSelectElements("/tcm:Component/tcm:Data/tcm:Content/Content:Content/Content:feederUrl", NS))
{
MatchedComponents.Add(comp);
}
}

Create Tridion Tag Cloud with Taxonomy Keywords?

Content in the CMS is tagged with Keywords and after publishing they are used as Tracking Keys and the value is incremented each time a Page is loaded. In the past a DB Query was used with the Tridion Broker DB to produce a tag cloud. I would like to change this and use the Tridion Broker API instead.
The Tridion Online Documentation has a nice example (login to http://sdllivecontent.sdl.com/ first). The example shows how to get the count of a keyword using the API.
I would like to have an aggregate query instead of getting the count 1 keyword at a time. Is it possible with the Broker API or using Ambient Framework?
string strTaxURI = "tcm:34-70-512", strTaxKeywordURI = "tcm:34-549-1024";
Query myQuery = new Query();
Criteria myCriteria = null;
TaxonomyKeywordCriteria taxonomyKeywordCriteria = new TaxonomyKeywordCriteria(strTaxURI, strTaxKeywordURI, false);
myCriteria = taxonomyKeywordCriteria;
myQuery.Criteria = myCriteria;
// filter code limiting results commented out....
string[] itemURIs = myQuery.ExecuteQuery();
foreach (string itemURI in itemURIs)
{
Response.Write(itemURI + ", ");
}
Don't think you can achieve what you need by using the BrokerQuery API. You can, however, use the Taxonomy API to get a full taxonomy and to look at the ReferencedContentCount of each Keyword in that Taxonomy.
TaxonomyFactory taxonomyFactory = new TaxonomyFactory();
Tridion.ContentDelivery.Taxonomies.Keyword category = taxonomyFactory.GetTaxonomyKeywords("tcm:9-3-512");
Response.Write(category.ReferencedContentCount);
if (category.HasChildren)
{
// get the category.KeywordChildren and loop over them
}
Hope this helps.
Cheers,
Daniel.

Microsoft dynamics CRM 2011: how to generate lead from external contact form

i developed CMS to one of my customers and he wants that when a user fill in the contact form, it will automatically generate lead in his CRM.
what is the easiest way to do that?
by the way, the contact form is ajax and the data is transfered to asmx, so it will be easy to call to CRM webservice or something like that, because i'm already in the server side.
can someone point me to tutorial or some code example?
thanks!
Your best start will be with the SDK available here, which contains example code and the sdk dlls etc...
Here is a page with a quick reference to all the web service endpoints available in the different flavors of CRM 2011.
From the SDK samplepcode\cs\quickstart creating account, but very similar for lead:
// Connect to the Organization service.
// The using statement assures that the service proxy will be properly disposed.
using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri,
serverConfig.HomeRealmUri,
serverConfig.Credentials,
serverConfig.DeviceCredentials))
{
// This statement is required to enable early-bound type support.
_serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
// Instaniate an account object.
// See the Entity Metadata topic in the SDK documentation to determine
// which attributes must be set for each entity.
Account account = new Account { Name = "Fourth Coffee" };
// Create an account record named Fourth Coffee.
_accountId = _serviceProxy.Create(account);
Console.Write("{0} {1} created, ", account.LogicalName, account.Name);
// Retrieve the account containing several of its attributes.
ColumnSet cols = new ColumnSet(
new String[] { "name", "address1_postalcode", "lastusedincampaign" });
Account retrievedAccount = (Account)_serviceProxy.Retrieve("account", _accountId, cols);
Console.Write("retrieved, ");
// Update the postal code attribute.
retrievedAccount.Address1_PostalCode = "98052";
// The address 2 postal code was set accidentally, so set it to null.
retrievedAccount.Address2_PostalCode = null;
// Shows use of a Money value.
retrievedAccount.Revenue = new Money(5000000);
// Shows use of a boolean value.
retrievedAccount.CreditOnHold = false;
// Update the account record.
_serviceProxy.Update(retrievedAccount);
Console.WriteLine("and updated.");

Resources