Wednesday, January 3, 2018

Compare Field-Level Permissions Between Profiles

If you want to compare field level permissions between two profiles, and you can use something like dbAmp to download your data to a SQL database, you can run a query like the following to compare two profiles.

select P1Perms.SobjectType, P1Perms.Field, P1Perms.PermissionsRead, P2Perms.PermissionsRead, P1Perms.PermissionsEdit, P2Perms.PermissionsEdit from 
(select fp.field, SobjectType, fp.PermissionsEdit, fp.PermissionsRead, profile.name from fieldpermissions fp
 join permissionset as ps on ps.id = fp.ParentId
 join profile on profile.Id = ps.ProfileId
 where profile.name = 'System Administrator (Custom)'
) as P1Perms 
left join (select fp.field, SobjectType, fp.PermissionsEdit, fp.PermissionsRead, profile.name from fieldpermissions fp
 join permissionset as ps on ps.id = fp.ParentId
 join profile on profile.Id = ps.ProfileId
 where profile.name = 'Business Development'
) as P2Perms on P1Perms.Field = P2Perms.Field and P1Perms.SobjectType = P2Perms.SobjectType
  where P1Perms.PermissionsRead <> P2Perms.PermissionsRead or P1Perms.PermissionsEdit <> P2Perms.PermissionsEdit or P2Perms.PermissionsRead is null
order by P1Perms.SobjectType, P1Perms.Field

Thursday, December 21, 2017

"The flow failed to access the value for" Error

The following error occurs in a Salesforce flow when you try to check a field on an object that is null.  For example, when you check a field on an Account record related to an Opportunity, but that Opportunity doesn't have an Account assigned.   The error will look somethng like this:
The flow failed to access the value for myVariable_current.Producing_Broker__r.MAP_Services_Not_Allowed_to_Contact__c because it hasn't been set or assigned.

To resolve this in Process Builder, you will need to check to see if the related object is present first.  In the example above, Producing_Broker__r must be checked first before trying to access Producing_Broker__r.MAP_Services_Not_Allowed_to_Contact__c field.     That looks something like this: 

In this case, the first block checks to see if Producing_Broker__c is null.  If it is null, then the Process Builder exits.  If it has a value, it goes to the next block where it can successfully evaluate Producing_Broker__r.MAP_Services_Not_Allowed_to_Contact__c. 

Friday, July 22, 2016

Looking up values in Validation Rules

The VLookup function provides the ability to lookup values from other objects.  Note that it ONLY works on Custom Objects.  The format is: VLookup(field_to_return, field_on_lookup_object, lookup_value).

So if you need need to lookup an item from a custom table with an Id of 00Xj000000NK03j, and return the name, the formula would look something like this:  


Tuesday, July 19, 2016

Viewing the ValidationExceptions Collection

Occassionally, .NET apps that are using EntityFramework will throw the following error

System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
The easiest way to see what these exceptions is to add the following to the Watch window:
((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors


Wednesday, April 13, 2016

Creating an SSL Certificate for Azure App Services


  1. Generate the CSR (Certificate Signing Request).  An easy way to do that is https://www.digicert.com/easy-csr/openssl.htm
  2. Take the output of this page and run it in a Bash shell, or some place that you have access to the OpenSSL library.  This will create a csr file and a key file. 
  3. Buy the certificate.   These guys have good prices: https://www.ssls.com
  4. As part of the checkout, it will ask you to type in the text of the CSR file generated by OpenSSL in Step 2 above. 
  5. Not sure what to select when asked for Apache vs Windows.  But selected Windows, and I got a .cer file.  Support had to send me a .crt file instead. 
  6. After verifying who you are, then will send you a .crt file. 
  7. Use OpenSSL again to convert the .crt file and the .key file to a pfk
    openssl pkcs12 -export -out myserver.pfx -inkey myserver.key -in myserver.crt
  8. Upload the resulting .pfx file to the server.


  9.  


Some of this is taken from: https://azure.microsoft.com/en-us/documentation/articles/web-sites-configure-ssl-certificate/#bkmk_iismgr

Tuesday, November 24, 2015

WebAPI Headaches

WebAPI is great sometimes, and sometimes can cause you headaches.   I've found that using the format below as a starting point seems to resolve a lot of the problems.
  • Return an HTTPResponseMessage instead of a string.  Otherwise you will see an extra set of quotations around any string you return. 
  • Credentials should be pulled from the header instead of as a parameter on the method. 
  • Set the 'Content' property of the ResponseMessage to any string content you want to return.  If you want to return Json, set this value to 
  • Only use a single parameter on the methods you use. 
  • Use a DTO to pass more complex objects into a POST request. 


using System.Net
using System.Net.Http

 [HttpPost]  
 [Route("MyMethod")]  
 public IHttpActionResult MyMethod()  
 {  
     // check credentials  
     var user = Utility.AuthenticateUserFromHeader(Request.Headers);  
     if (user == null)  
         throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.Unauthorized));  
     var data = Request.Content.ReadAsStringAsync().Result;  
     // process the data   
     return Ok("Response message");  
 }  


Dealing with CORS
Put the following in the Web.config to help with CORS.  (If you like this part, go upvote this guys answer: http://stackoverflow.com/a/36901271/224531)

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>
If you have some extra HEADER parameter, you must add it to Access-Control-Allow-Headers, like:
<add name="Access-Control-Allow-Headers" value="Content-Type, X-Your-Extra-Header-Key" />
And finally, to handle OPTIONS requests you must reply with empty response, adding in your application class:
protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}

Monday, November 23, 2015

See 'EntityValidationErrors' property for more details

This is an annoying error.  It generally occurs when calling SaveContext in EF.  It means that there was something wrong with the data you were trying to Save, but it's not going to tell you what exactly.  

Fortunately, there is an easy fix if you are running in the debugger.  To get EF to cough up the EntityValidationErrors, simply create a new watch with the following:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors