- Release Notes
- Overview
- Getting Started
- Marketplace Vendors
- Marketplace Customers
- Publishing Guidelines
- Publishing Guidelines for Ready-to-go Automations
- Publishing Guidelines for Solution Accelerators
- Publishing Guidelines for Integration Service Connectors
- Publishing Guidelines for Process Mining app templates
- Security & IP Protection
- Other UiPath Listings- Node-RED
- Setup
- Teams
- Microsoft Teams Scope
- Create Team
- Create Team From Group
- Get Team
- Get Teams
- Channels
- Create Channel
- Delete Channel
- Get Channel
- Get Channels
- Update Channel
- Chats
- Get Chat
- Get Chats
- Get Chat Members
- Messages
- Get Message
- Get Messages
- Get Message Replies
- Reply To Message
- Send Message
- Events
- Create Event
- Delete Event
- Get Event
- Get Events
- Users
- Get User Presence
 
- How It Works
- Technical References
- Get Started
- About
- Setup
- Technical References
- Azure Form Recognizer Scope
- Activities
- Analyze Form
- Analyze Form Async
- Get Analyze Form Result
- Analyze Receipt
- Analyze Receipt Async
- Get Analyze Receipt Result
- Analyze Layout
- Analyze Layout Async
- Get Analyze Layout Result
- Train Model
- Get Models
- Get Model Keys
- Get Model Info
- Delete Model
 
 
- Connectors
- How to Create Activities
- Build Your Integration

Marketplace User Guide
Intro
Every activity begins with an Activity class file that defines its inputs, outputs, and execution logic. To better understand how this is done, open the ChildActivity.cs file in your Activity project and walk through it section by section. This is a simple activity that adds two numbers together and outputs their sum.
using System;
using System.Activities;
using System.Threading;
using System.Threading.Tasks;
using MyCompany.MyProduct.Activities.Properties;
using UiPath.Shared.Activities;
namespace MyCompany.MyProduct.Activities
{
    [LocalizedDisplayName(nameof(Resources.ChildActivityDisplayName))]
    [LocalizedDescription(nameof(Resources.ChildActivityDescription))]
    public class ChildActivity : AsyncTaskCodeActivity
    {
        #region Properties
        [LocalizedDisplayName(nameof(Resources.ChildActivityFirstNumberDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivityFirstNumberDescription))]
        [LocalizedCategory(nameof(Resources.Input))]
        public InArgument<int> FirstNumber { get; set; }
        [LocalizedDisplayName(nameof(Resources.ChildActivitySecondNumberDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivitySecondNumberDescription))]
        [LocalizedCategory(nameof(Resources.Input))]
        public InArgument<int> SecondNumber { get; set; }
        [LocalizedDisplayName(nameof(Resources.ChildActivitySumDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivitySumDescription))]
        [LocalizedCategory(nameof(Resources.Output))]
        public OutArgument<string> Sum { get; set; }
        #endregion
          
        #region Constructors
          
        public ChildActivity()
        {
              Constraints.Add(ActivityConstraints.HasParentType<ChildActivity, ParentScope>(Resources.ValidationMessage));
        }
      
        #endregion
          
        #region Protected Methods
        protected override void CacheMetadata(CodeActivityMetadata metadata)
        {
              if (FirstNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(FirstNumber)));
              if (SecondNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(SecondNumber)));
              base.CacheMetadata(metadata);
        }
        protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken)
        {
              var property = context.DataContext.GetProperties()[ParentScope.ApplicationTag];
              var app = property.GetValue(context.DataContext) as Application;
           
              var firstValue = FirstNumber.Get(context);
              var secondValue = SecondNumber.Get(context);
        
              var sum = app.Sum(firstValue, secondValue);
              return ctx =>
              {
                  Sum.Set(ctx, sum);
              };
       }
        #endregion
    }
}using System;
using System.Activities;
using System.Threading;
using System.Threading.Tasks;
using MyCompany.MyProduct.Activities.Properties;
using UiPath.Shared.Activities;
namespace MyCompany.MyProduct.Activities
{
    [LocalizedDisplayName(nameof(Resources.ChildActivityDisplayName))]
    [LocalizedDescription(nameof(Resources.ChildActivityDescription))]
    public class ChildActivity : AsyncTaskCodeActivity
    {
        #region Properties
        [LocalizedDisplayName(nameof(Resources.ChildActivityFirstNumberDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivityFirstNumberDescription))]
        [LocalizedCategory(nameof(Resources.Input))]
        public InArgument<int> FirstNumber { get; set; }
        [LocalizedDisplayName(nameof(Resources.ChildActivitySecondNumberDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivitySecondNumberDescription))]
        [LocalizedCategory(nameof(Resources.Input))]
        public InArgument<int> SecondNumber { get; set; }
        [LocalizedDisplayName(nameof(Resources.ChildActivitySumDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivitySumDescription))]
        [LocalizedCategory(nameof(Resources.Output))]
        public OutArgument<string> Sum { get; set; }
        #endregion
          
        #region Constructors
          
        public ChildActivity()
        {
              Constraints.Add(ActivityConstraints.HasParentType<ChildActivity, ParentScope>(Resources.ValidationMessage));
        }
      
        #endregion
          
        #region Protected Methods
        protected override void CacheMetadata(CodeActivityMetadata metadata)
        {
              if (FirstNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(FirstNumber)));
              if (SecondNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(SecondNumber)));
              base.CacheMetadata(metadata);
        }
        protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken)
        {
              var property = context.DataContext.GetProperties()[ParentScope.ApplicationTag];
              var app = property.GetValue(context.DataContext) as Application;
           
              var firstValue = FirstNumber.Get(context);
              var secondValue = SecondNumber.Get(context);
        
              var sum = app.Sum(firstValue, secondValue);
              return ctx =>
              {
                  Sum.Set(ctx, sum);
              };
       }
        #endregion
    }
}The file starts with standard boilerplate. It imports some namespaces and then declares that this activity will itself live in the MyCompany.MyProduct.Activities namespace.
using System;
using System.Activities;
using System.Threading;
using System.Threading.Tasks;
using MyCompany.MyProduct.Activities.Properties;
using UiPath.Shared.Activities;
namespace MyCompany.MyProduct.Activities
{using System;
using System.Activities;
using System.Threading;
using System.Threading.Tasks;
using MyCompany.MyProduct.Activities.Properties;
using UiPath.Shared.Activities;
namespace MyCompany.MyProduct.Activities
{AsyncTaskCodeActivity, which provides methods for design-time
                  validation of properties and run-time execution logic, and can be found in the Shared
                  folder included in your solution. Additionally, all activities that extend
                  AsyncTaskCodeActivity may run asynchronously, allowing them to be
                  used with the Parallel
                  and Parallel For Each
                  activities in UiPath Studio.
               [LocalizedDisplayName(nameof(Resources.ChildActivityDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivityDescription))]
public class ChildActivity : AsyncTaskCodeActivity
{[LocalizedDisplayName(nameof(Resources.ChildActivityDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivityDescription))]
public class ChildActivity : AsyncTaskCodeActivity
{LocalizedDisplayName and
                  LocalizedDescription. These allow you to set the name and tooltip
                  description of the activity that appear in UiPath Studio's activities pane. In this
                  example, the attributes reference localized versions of each (e.g.
                  Resources.ChildActivityDisplayName), but simple strings may be used
                  as well. For more information on localization, see
                        here.
               FirstNumber and SecondNumber appear in the Input
                  category, but Sum appears under Output.
               [LocalizedDisplayName(nameof(Resources.ChildActivityFirstNumberDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivityFirstNumberDescription))]
[LocalizedCategory(nameof(Resources.Input))]
public InArgument<int> FirstNumber { get; set; }
[LocalizedDisplayName(nameof(Resources.ChildActivitySecondNumberDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivitySecondNumberDescription))]
[LocalizedCategory(nameof(Resources.Input))]
public InArgument<int> SecondNumber { get; set; }
[LocalizedDisplayName(nameof(Resources.ChildActivitySumDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivitySumDescription))]
[LocalizedCategory(nameof(Resources.Output))]
public OutArgument<int> Sum { get; set; }[LocalizedDisplayName(nameof(Resources.ChildActivityFirstNumberDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivityFirstNumberDescription))]
[LocalizedCategory(nameof(Resources.Input))]
public InArgument<int> FirstNumber { get; set; }
[LocalizedDisplayName(nameof(Resources.ChildActivitySecondNumberDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivitySecondNumberDescription))]
[LocalizedCategory(nameof(Resources.Input))]
public InArgument<int> SecondNumber { get; set; }
[LocalizedDisplayName(nameof(Resources.ChildActivitySumDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivitySumDescription))]
[LocalizedCategory(nameof(Resources.Output))]
public OutArgument<int> Sum { get; set; }InArgument,
                  InOutArgument, or OutArgument and must indicate
                  their expected type (e.g. string, int, ...).
               public ChildActivity()
{
     FirstNumber = 10;
     Constraints.Add(ActivityConstraints.HasParentType<ChildActivity, ParentScope>(Resources.ValidationMessage));
}public ChildActivity()
{
     FirstNumber = 10;
     Constraints.Add(ActivityConstraints.HasParentType<ChildActivity, ParentScope>(Resources.ValidationMessage));
}The constructor is used to set default values and constraints on properties.
- 
                     In the example above, theFirstNumberproperty is given a default value of 10, which appears in the Properties Pane.
 
- 
                     Additionally, a constraint is placed on the activity itself, requiring that it be surrounded by a ParentScope. If it is not, a validation error is shown. 
 
FirstNumber and
                  SecondNumber, and throw a validation error if either is not
                  provided. Until the validation errors are handled, a workflow will not run.
               protected override void CacheMetadata(CodeActivityMetadata metadata)
{
    if (FirstNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(FirstNumber)));
    if (SecondNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(SecondNumber)));
    base.CacheMetadata(metadata);
}protected override void CacheMetadata(CodeActivityMetadata metadata)
{
    if (FirstNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(FirstNumber)));
    if (SecondNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(SecondNumber)));
    base.CacheMetadata(metadata);
}ExecuteAsync is where the execution logic of the activity is held.
- The first two lines of the method
                     query the activity context--or the current state of the ChildActivity and the
                     elements surrounding it--to retrieve an Applicationobject from the ParentScope if one surrounds it. Note that, because of the constraint added in the constructor above, this activity will never be allowed to run if it is not already in a ParentScope.
- The next lines take the current
                     values of the FirstNumberandSecondNumberproperties and save them to local variables.
- 
                     The last lines perform a Sum operation on the inputted numbers and set theSumproperty to this value. BecauseSumis an output property, this value may then be used by subsequent activities in the workflow.protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { var property = context.DataContext.GetProperties()[ParentScope.ApplicationTag]; var app = property.GetValue(context.DataContext) as Application; var firstValue = FirstNumber.Get(context); var secondValue = SecondNumber.Get(context); var sum = app.Sum(firstValue, secondValue); return ctx => { Sum.Set(ctx, sum); }; }protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { var property = context.DataContext.GetProperties()[ParentScope.ApplicationTag]; var app = property.GetValue(context.DataContext) as Application; var firstValue = FirstNumber.Get(context); var secondValue = SecondNumber.Get(context); var sum = app.Sum(firstValue, secondValue); return ctx => { Sum.Set(ctx, sum); }; }Important:Notice that the ExecuteAsync method returns aTask<Action<AsyncCodeActivityContext>>object.ATaskis returned so this activity can run asynchronously.AnActionis returned within this Task in order to allow for complex functions to be executed after any asynchronous operations have completed. In the example above, this function simply sets the value ofSum.Lastly, theActiontakes anAsyncCodeActivityContextparameter so the context from this activity may be used by any such functions running after the asynchronous operations have finished. If this was not the case, the context could be lost and theSumwould not be easily modifiable.