原文地址:https://www.wipfli.com/insights/blogs/connect-microsoft-dynamics-365-blog/160810-calling-custom-actions-from-javascript

Overview

Actions in processes are a way to create custom messages in CRM for an entity.  For example, let’s say you have an entity record that needs escalation or approval.  You could create a custom action that performs the steps needed for this process.  Then you could add a button to the form that the user clicks to initiate the process.  Out of the box for most entities, you have Create, Update, Delete, Assign, and SetState messages and you have the option of writing custom business logic in the form of Plugins or Workflows on these.  With custom actions, you have the ability to create whatever message you need to fulfil your requirements.  Then you can attach plugin code to that message and perform any operations you need without restrictions.  In this post, I am going to explain how to create a custom action, pass input and output parameters, and call that action from JavaScript.  With these basic building blocks, you can create whatever you need.
 
Overall Process
 
The example I am going to document here will involve a button on the ribbon that, when clicked, will display a notification on the form, call the custom action, will run a plugin, will call a web service to get the temperature for the account's zip code, will return that information, and will display it in a notification on the form.  In this case, we are going to have a plugin that will do all the real work. There will be JavaScript that will handle the form notifications and calling the action.
 
The result will look like this:

To make all this happen, I will be using a couple of JavaScript libraries that make working with custom Actions and Notifications much easier.  The first one is called Notify.js and can be found here.  This library makes it easy to display form notifications and adds some functionality to the standard CRM notifications.  The second one is called Process.js and can be found here.  This library simplifies calling custom actions from JavaScript.  Calling custom actions involves creating rather lengthy XML Http Requests and this library simplifies that down to a function call with a couple of parameters.  It also provides callbacks for success and errors.
 
The process looks something like this.

 
 The components needed for this are:
  1. A Custom Action
  2. JavaScript Web Resource (to call the custom action)
  3. Custom Ribbon button (to call the JavaScript)
  4. Plugin to call the weather web service
  5. Notify.js library
  6. Process.js library

Components

The Custom Action
 
In this example, the custom action is fairly simple.  We just need a couple of parameters.  The custom action gives us a way to pass the parameters to and from the plugin.  It also allows us to register the plugin step against the custom action message.

 
JavaScript Web Resource
 
The JavaScript manages the notifications and calling the custom action.  It will validate that we have a Zip Code, load the input parameters, and then call the custom action.  When the action completes, it will call the success callback and display the information on the form as a notification.  While the action is working, there will be a notification on the form letting the user know that something is happening.
 
function CallAction() {
     //Verify that we have a Zip Code 
   if (Xrm.Page.getAttribute("address1_postalcode").getValue() == null) {
      Notify.add("Zip code is missing", "ERROR", "nozip", null, 5);
   }                               
   else {
     //Display the notification that we are working on something
     Notify.add("Processing Action...", "LOADING", "myProcessing");
     //Load the input parameters
     var inputParams = [
     { key: "ParamPostalCode", type: Process.Type.String, value: Xrm.Page.getAttribute("address1_postalcode").getValue() },
     { key: "Target", type: Process.Type.EntityReference, value: new Process.EntityReference(Xrm.Page.data.entity.getEntityName(), Xrm.Page.data.entity.getId()) }
     ];
     //Call the custom action
     Process.callAction("wipfli_GetWeather", inputParams, successCallback, errorCallback);
   }
}
function successCallback(params) {
   //Get the result from the plugin and display the information in a notification
   var outputParamOne = params["OutputParamOne"];
   Notify.add(outputParamOne, "INFO", "mySuccess", [{ type: "button", text: "Clear", callback: function () { Notify.remove("mySuccess"); } }]);
   Notify.remove("myProcessing");
}
function errorCallback(error, trace) {
   Notify.remove("myProcessing");
   Notify.add("Error: " + error, "ERROR", "myError");
}
 
Custom Ribbon Button
 
The ribbon button just has to call the "CallAction" function from the above JavaScript.  Use the Ribbon Workbench for CRM to create a custom button that points to a web resource and calls the CallAction function.

 
Plugin
 
The plugin will read the input parameters and then call the weather web service.  Using the response from the web service, it will format the output information and then return it in the output parameter.  Don’t forget to register the plugin using the Plugin Registration Tool in the CRM SDK.  Then register a step on the GetWeather message.
 
protected override void ExecuteCrmPlugin(LocalPluginContext localContext)
{
   if (localContext == null)
   {
     throw new ArgumentNullException("localContext");
   }
   //Get the parameters from the Action call
EntityReference accountRef =      (EntityReference)localContext.PluginExecutionContext.InputParameters["Target"];
string paramPostalCode = (string)localContext.PluginExecutionContext.InputParameters["ParamPostalCode"];
string webAddress = @"http://api.openweathermap.org/data/2.5/weather?zip=" +       paramPostalCode + ",us&mode=xml&units=imperial&appid={your specific APPID}";
       string output = "";
   try
   {
     using (WebClient client = new WebClient())
     {
       Byte[] responseBytes = client.DownloadData(webAddress);
       String response = Encoding.UTF8.GetString(responseBytes);
       localContext.TracingService.Trace("Response is: " + response);
       XmlDocument xmlDoc = new XmlDocument();
       xmlDoc.LoadXml(response);
       XmlNodeList current = xmlDoc.SelectNodes("/current");
       foreach (XmlNode xn in current)
      {
output = xn["city"].Attributes["name"].Value + " is " + Math.Round(Double.Parse(xn["temperature"].Attributes["value"].Value), 0) + " " + xn["temperature"].Attributes["unit"].Value;
      }
 
      localContext.TracingService.Trace("OUTPUT IS: " + output);
    }
  }
  catch (WebException exception)
  {
    string str = string.Empty;
    if (exception.Response != null)
   {
     using (StreamReader reader =
       new StreamReader(exception.Response.GetResponseStream()))
    {
       str = reader.ReadToEnd();
    }
    exception.Response.Close();
  }
  if (exception.Status == WebExceptionStatus.Timeout)
  {
     throw new InvalidPluginExecutionException(
       "The timeout elapsed while attempting to issue the request.", exception);
  }
throw new InvalidPluginExecutionException(String.Format(CultureInfo.InvariantCulture,
       "A Web exception occurred while attempting to issue the request. {0}: {1}",
       exception.Message, str), exception);
  }
  localContext.PluginExecutionContext.OutputParameters["OutputParamOne"] = output;
}
 
 
Additional Libraries
 
The Notifiy.js and Process.js libraries will need to be loaded on the form.  To do this, include them as form libraries in the Form Properties.

Conclusion

 
With all the components in place, clicking the button should produce the weather notification.  While this example may not be very useful in the real world, the purpose was to demonstrate some of the basic concepts of custom actions.  It shows you how to call a custom action from JavaScript and pass input and output parameters.  It also demonstrates triggering a Plugin from a custom action.

Calling Custom Actions from JavaScript的更多相关文章

  1. Installation Phases and In-Script Execution for Custom Actions in Windows Installer

    用 InstallShield 依照 Custom Action Wizard 创建 Custom Action 时,会遇到下面的几个选项: In-Script Execution Install U ...

  2. custom event in javascript and jquery

    javascript: // add a eventListener document.addEventListener("abc", function(){alert('this ...

  3. [转]UIWebView的Javascript运行时对象

    An alternative, that may get you rejected from the app store, is to use WebScriptObject. These APIs ...

  4. WIX Custom Action (immediate, deffered, rollback)

    Following content is directly reprinted from From MSI to WiX, Part 19 - The Art of Custom Action, Pa ...

  5. I Take It All Back: Using Windows Installer (MSI) Rollback Actions

    Original Link: http://blogs.flexerasoftware.com/installtalk/2011/10/i-take-it-all-back-using-windows ...

  6. Default Custom Action Locations and IDs

    Default Custom Action Locations and IDs SharePoint 2013                             The following ta ...

  7. Wix打包系列(三)自定义Action(Custom Action)

    原文:Wix打包系列(三)自定义Action(Custom Action) 3.1 关于Action 我们已经知道如何生成具有标准安装界面的安装程序了,Windows Installer按照我们的界面 ...

  8. How To Add Custom Build Steps and Commands To setup.py

    转自:https://jichu4n.com/posts/how-to-add-custom-build-steps-and-commands-to-setuppy/ A setup.py scrip ...

  9. 所有selenium相关的库

    通过爬虫 获取 官方文档库 如果想获取 相应的库 修改对应配置即可 代码如下 from urllib.parse import urljoin import requests from lxml im ...

随机推荐

  1. 2015-10-21 C#1

    C#(一) 一.C#的数值类型 byte----字节型 short---短整型 int------整型 long----长整型 char----字符型 float----单精度型 double--双精 ...

  2. JDBC数据库连接工具

    什么是JDBC? JDBC是一种可以执行sql语句的Java API,提供对数据库的访问方法. 什么是JDBC驱动? JDBC连接数据库需要驱动,驱动是两个设备要进行通信,满足一定的数据驱动格式.一般 ...

  3. c函数创建文件和路径

    bool NewFileName(const char* filename) { size_t len; < (len = strlen(filename))) { char* tmpbuf, ...

  4. java通过StringToKenizer获取字符串中的单词根据空格分离-简写版

    public class StringToKenizer { public static void main(String[] args) { String strin = "Hello J ...

  5. python项目运行环境安装小结

    安装最新即可,实际的版本号可能不一样 安装过程较复杂,建议用一台单独的vm安装,能做成docker image最好 基础软件 nginx-1.10.0: sudo apt-get install ng ...

  6. C语言函数的存储类别

    函数默认的隐含存储类型是extern auto:只能用于局部变量 extern:允许被其他文件调用 static:只能被本源程序文件调用

  7. C++ 常用设计模式(学习笔记)

    1.工厂模式:简单工厂模式.工厂方法模式.抽象工厂模式 1).简单工厂模式:主要特点是需要在工厂类中做判断,从而创造相应的产品,当增加新产品时,需要修改工厂类. typedef enum { T80 ...

  8. 使用css时的一些技巧及注意事项

    <!-- TITLE: 使用css时的一些技巧及注意事项 --> # CSS推荐书写顺序: 1. 位置属性(position, top, right, z-index, display, ...

  9. 剑指Offer 1. 二维数组中的查找 (数组)

    题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...

  10. Reactor

    Flux和Mono Flux和Mono是Reactor中的两个基本概念.Flux表示的是包含0到N个元素的异步序列.在该序列中可以包含三种不同类型的消息通知:正常的包含元素的消息,序列结束的消息和序列 ...