Saltar al contenido

Píldoras

RSS

Trucos cortos sobre Dynamics 365, Power Pages y Power Platform: un problema, una solución, en dos minutos de lectura. Una nueva cada semana.

Error "The entity name doesn't exist" en las vistas de Dynamics 365

Abres una vista de una tabla personalizada y te salta “The entity name doesn’t exist”. Lo más probable es que la vista tenga guardado un código de tipo de objeto (ObjectTypeCode) que no corresponde a este entorno. Suele pasar al mover soluciones de un entorno a otro, porque las tablas personalizadas no tienen por qué recibir el mismo código en cada uno. Con las estándar (account, contact y demás) no te va a pasar, su código es siempre el mismo.

Para arreglarlo, primero saca el ObjectTypeCode real de la tabla en tu entorno:

https://TU-ENTORNO.crm4.dynamics.com/api/data/v9.2/EntityDefinitions?$select=LogicalName,ObjectTypeCode&$filter=LogicalName eq 'nombre_tabla'

Después abre XrmToolBox → View Designer, carga la tabla y, en cada vista, edita el XML para sustituir el número antiguo del atributo object por el que acabas de copiar. Guarda, publica y la vista debería abrir sin problema.

Compartir:LinkedInX

Cómo llevarte tus cambios a otra rama en Git sin hacer commit

Te pones a programar y a mitad te das cuenta de que estás en la rama que no era, normalmente main. No hace falta copiar archivos a mano a ningún sitio.

Si la rama ya existe, guarda los cambios, cambia de rama y recupéralos:

git stash
git checkout otra-rama
git stash pop

Si la rama todavía no existe es aún más fácil, porque al crearla los cambios sin commit se vienen contigo y ni siquiera necesitas stash:

git switch -c mi-nueva-rama

Puede que el git stash pop te dé conflictos si la otra rama tocó los mismos archivos. No pasa nada, los resuelves como cualquier otro conflicto. El stash no se borra hasta que se aplica bien, así que no pierdes nada y lo puedes ver con git stash list.

Compartir:LinkedInX

Plantilla de plugin en Dataverse: contexto, servicio y Target

Todos los plugins arrancan igual. Hay que sacar el contexto, el servicio de trazas, el servicio de organización y el registro que ha disparado el plugin (Target). Esta es la base que copio siempre:

public void Execute(IServiceProvider serviceProvider)
{
    var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    var tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
    var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
    var service = factory.CreateOrganizationService(context.UserId);
 
    if (!context.InputParameters.Contains("Target") || !(context.InputParameters["Target"] is Entity target))
        return;
 
    tracing.Trace("Plugin ejecutado sobre {0} {1}", target.LogicalName, target.Id);
    // Tu lógica aquí
}

Con CreateOrganizationService(context.UserId) el servicio usa los permisos del usuario que lanzó la acción. Si le pasas null se ejecuta como SYSTEM y se salta la seguridad, algo que yo solo hago cuando no queda otra.

La comprobación del tipo del Target tampoco está de adorno. En un Delete llega una EntityReference y no una Entity, así que si haces el cast directamente a Entity, el plugin falla.

Por último, en un Update el Target solo trae los campos que han cambiado. Si necesitas leer alguno más, configura una pre-image en el paso.

Compartir:LinkedInX

Cómo rellenar un lookup desde JavaScript en un formulario de Dynamics 365

Un campo de búsqueda (lookup) no se rellena pasándole un GUID sin más. Lo que espera es un array con un objeto que tenga id, name y entityType, y yo suelo tener una función pequeña para no repetirlo cada vez:

function setLookup(executionContext, fieldName, id, name, entityType) {
  const formContext = executionContext.getFormContext();
  formContext.getAttribute(fieldName).setValue([
    { id: id, name: name, entityType: entityType },
  ]);
}
 
// Ejemplo: poner la cuenta principal
setLookup(executionContext, "parentcustomerid", "00000000-0000-0000-0000-000000000000", "Axazure", "account");

En entityType va el nombre lógico de la tabla (account, contact), no el nombre para mostrar. El name es el texto que se ve en el formulario, y si no lo pones el campo parece vacío hasta que guardas.

Con los lookups de cliente, como customerid o parentcustomerid, hay que fijarse más, porque aceptan varias tablas y si el entityType no es el correcto el guardado falla.

Para vaciar el campo, formContext.getAttribute(fieldName).setValue(null).

Compartir:LinkedInX

Cómo activar la Web API de Power Pages para una tabla

La Web API de Power Pages (/_api/...) no funciona con ninguna tabla hasta que la activas tú. Hacen falta dos cosas, la configuración del sitio y los permisos de tabla.

En Site Settings crea estas dos entradas:

NombreValor
Webapi/account/enabledtrue
Webapi/account/fieldsaddress1_city,description

Cambia account por el nombre lógico de tu tabla. En fields van, separados por comas, los campos que se podrán leer y escribir. Se puede poner * para que entren todos, pero yo prefiero limitarlo a los que de verdad uso.

Luego, en Table Permissions, crea un permiso para esa tabla con los privilegios que necesites (lectura, creación, escritura) y el ámbito que toque, ya sea global, de contacto o de cuenta. Asígnaselo al rol web de los usuarios que van a llamar a la API.

Si después de todo esto sigue sin responder, seguramente es la caché, que todavía no ha recogido los cambios. Como administrador puedes forzar el refresco desde /_services/about.