web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

Some Questions About Proxy Generation

(0) ShareShare
ReportReport
Posted on by

Hi,

    I got some questions about proxy generation, please help:

Here is the code snippet from the model factory, 

  protected override void BuildActions()
            {
                base.BuildActions();
                var action = CommerceModelFactory.BindEntitySetAction<SampleDataModel.StoreDayHours>("GetStoreDaysByStore");
                action.Parameter<string>("StoreNumber");
                action.ReturnsCollectionFromEntitySet<SampleDataModel.StoreDayHours>("StoreHours");
                action = CommerceModelFactory.BindEntitySetAction<SampleDataModel.Activity>("GetActivitiesByCustomer");
                action.Parameter<string>("AccountNumber");
                action.ReturnsCollectionFromEntitySet<SampleDataModel.Activity>("Activity");
                action = CommerceModelFactory.BindEntitySetAction<SampleDataModel.Activity>("CreateCustomerActivity");
                action.Parameter<string>("CustomerAccountNumber");
                action.Parameter<string>("Type");
                action.Parameter<string>("Responsible");
                action.Parameter<string>("Purpose");
                action.Parameter<DateTime>("DueDate");
                action.Parameter<string>("Category");
                action.Parameter<int>("Priority");
                action.Parameter<string>("Description");
                action.Parameter<int>("Closed");
                action.ReturnsCollectionFromEntitySet<SampleDataModel.Activity>("Activity");
                var var1 = CommerceModelFactory.BindEntitySetAction<Customer>("GetCrossLoyaltyCardDiscountAction");
                var1.Parameter<string>("LoyaltyCardNumber");
                var1.Returns<decimal>();
                action = CommerceModelFactory.BindEntitySetAction<SampleDataModel.Activity>("UpdateActivities");
                action.Parameter<ReadOnlyCollection<Activity>>("Activities");
                action.Returns<bool>();
            }
The generated interface is as following:
  /// <summary>
    /// Interface for Activity Manager.
    /// </summary>
    [GeneratedCodeAttribute("Contoso.Commerce.RetailProxy", "1.0")]
    internal interface IActivityManager : IEntityManager
    {
        /// <summary>
        /// Creates the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns>The updated entity after creation.</returns>
        Task<Activity> Create(Activity entity);

        /// <summary>
        /// Reads the entity with specified identifier.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>The entity.</returns>
        Task<Activity> Read(long id);
      
        /// <summary>
        /// Read all entities with specified query settings.
        /// </summary>
        /// <param name="queryResultSettings">The query result settings.</param>
        /// <returns>The collection of entities.</returns>
        Task<PagedResult<Activity>> ReadAll(QueryResultSettings queryResultSettings);

        /// <summary>
        /// Updates the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns>The updated entity.</returns>
        Task<Activity> Update(Activity entity);

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns>The task object.</returns>
        Task Delete(Activity entity);
        
        /// <summary>
        /// GetActivitiesByCustomer method.
        /// </summary>
        /// <param name="accountNumber">The accountNumber.</param>
        /// <param name="queryResultSettings">The queryResultSettings.</param>
        /// <returns>The Collection of Activity.</returns>
        Task<PagedResult<Activity>> GetActivitiesByCustomer(string accountNumber, QueryResultSettings queryResultSettings);
    
        /// <summary>
        /// CreateCustomerActivity method.
        /// </summary>
        /// <param name="customerAccountNumber">The customerAccountNumber.</param>
        /// <param name="type">The type.</param>
        /// <param name="responsible">The responsible.</param>
        /// <param name="purpose">The purpose.</param>
        /// <param name="dueDate">The dueDate.</param>
        /// <param name="category">The category.</param>
        /// <param name="priority">The priority.</param>
        /// <param name="description">The description.</param>
        /// <param name="closed">The closed.</param>
        /// <param name="queryResultSettings">The queryResultSettings.</param>
        /// <returns>The Collection of Activity.</returns>
        Task<PagedResult<Activity>> CreateCustomerActivity(string customerAccountNumber, string type, string responsible, string purpose, DateTimeOffset dueDate, string category, int priority, string description, int closed, QueryResultSettings queryResultSettings);
    
        /// <summary>
        /// UpdateActivities method.
        /// </summary>
        /// <param name="activities">The activities.</param>
        /// <returns>The bool object.</returns>
        Task<bool> UpdateActivities(ReadOnlyCollection_1OfActivity activities);
    }
    }
question 1: It seems that the generated interface is slightly different from RetailServer controller(i have marked lines that is different in red), is it a bug? How to deal with these situation?
is it a good practice that implement the interface like the following:
  public Task<PagedResult<Activity>> CreateCustomerActivity(string number, string type, string responsible, string purpose, DateTimeOffset dueDate, string category, int priority, string description, int closed, QueryResultSettings queryResultSettings)
            {
                var request = new CreateActivityDataRequest(number,type,responsible,purpose,dueDate.DateTime,category,priority,description, closed) { QueryResultSettings = queryResultSettings };
                return Task.Run(() => CommerceRuntimeManager.Runtime.Execute<CreateActivityDataResponse>(request, null).activities);
            }


As to the UpdateActivities, I really have no idea how to implement , I don't know how to convert
ReadOnlyCollection_1OfActivity  to ReadOnlyCollection<Activity> .

question 2: There are several interface that not defined in the model factory, say,ReadAll,Update.What is the good practice to leverage them? Should I create a correspondent action in the controller as following?
            /// <summary>
            /// Update a activity for a given customer.
            /// </summary>
            /// <param name="parameters">The parameters to this action.</param>
            /// <returns>The result that  if the action is succeed or not.</returns>
            [HttpPost]
            [CommerceAuthorization(AllowedRetailRoles = new string[] { CommerceRoles.Anonymous, CommerceRoles.Customer, CommerceRoles.Device, CommerceRoles.Employee })]
            public Activity Update(Activity entity)
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("parameters");
                }
                var runtime = CommerceRuntimeManager.CreateRuntime(this.CommercePrincipal);
                QueryResultSettings queryResultSettings = QueryResultSettings.SingleRecord;
                queryResultSettings.Paging = new PagingInfo(10);
                var request = new UpadteActivityServiceRequest(entity) { QueryResultSettings = queryResultSettings };
                runtime.Execute<Response>(request, null);
                var request1 = new GetActivityDataRequest(entity.Id);
                Activity activity= runtime.Execute<GetActivityDataResponse>(request1, null).activity;
                return activity;
            }





Thanks in advance.



Regards.
Leon

*This post is locked for comments

I have the same question (0)
  • SergeyP Profile Picture
    2,928 on at
    RE: Some Questions About Proxy Generation

    1. ODATA v4 (this is what is used in RS in AX7) supports DateTimeOffset but not DateTime, therefore, on your CRT/RS side whenever you need to work with date time use DateTimeOffset, that is what out of the box CRT/RS does.

    2. If you have a parameter which is in fact a collection you then need to use method CollectionParameter() rather than just Parameter() to build the method's metadata.

    3. The reason why you see such methods like ReadAll, Update is because you have registered new entity set based on your class StoreDayHours and for that entity all standard operations are defined, if you don't really need them you don't have to have real implementation for them in RS proxy, you could just have there let's say

    throw new NotSupportedException();


     

    that is by the way what exactly is done in let's say such proxy methods like ProductManager.Update() - it just doesn't make sense to update a product by leveraging a proxy so that method was marked as not supported, if the same applies to your entities - you can do the same.

  • Community Member Profile Picture
    on at
    RE: Some Questions About Proxy Generation

    Thank you,Sergey .

       What if I need these standard operations? I means what should I do if I want to leverage these method. Say I need the Update method,  Should I create a correspondent action in the controller as following?

               /// <summary>

               /// Update a activity for a given customer.

               /// </summary>

               /// <param name="parameters">The parameters to this action.</param>

               /// <returns>The result that  if the action is succeed or not.</returns>

               [HttpPost]

               [CommerceAuthorization(AllowedRetailRoles = new string[] { CommerceRoles.Anonymous, CommerceRoles.Customer, CommerceRoles.Device, CommerceRoles.Employee })]

               public Activity Update(Activity entity)

               {

                   if (entity == null)

                   {

                       throw new ArgumentNullException("parameters");

                   }

                   var runtime = CommerceRuntimeManager.CreateRuntime(this.CommercePrincipal);

                   QueryResultSettings queryResultSettings = QueryResultSettings.SingleRecord;

                   queryResultSettings.Paging = new PagingInfo(10);

                   var request = new UpadteActivityServiceRequest(entity) { QueryResultSettings = queryResultSettings };

                   runtime.Execute<Response>(request, null);

                   var request1 = new GetActivityDataRequest(entity.Id);

                   Activity activity= runtime.Execute<GetActivityDataResponse>(request1, null).activity;

                   return activity;

               }

  • SergeyP Profile Picture
    2,928 on at
    RE: Some Questions About Proxy Generation

    You can see an example of Update operation in, for instance, CustomersController.UpdateEntity

  • Community Member Profile Picture
    on at
    RE: Some Questions About Proxy Generation

    Hi,Sergey, I searched the RetailSDK directory with keyword "UpdateEntity ", and found  some dll file , I can't find the source code.

  • Verified answer
    SergeyP Profile Picture
    2,928 on at
    RE: Some Questions About Proxy Generation
            [CommerceAuthorization(CommerceRoles.Employee, CommerceRoles.Customer)]
            protected override Customer UpdateEntity(string key, Customer update)
            {
                return this.customerManager.UpdateCustomer(update);
            }

    So, the point is to override the method UpdateEntity in your Controller and call a CRT method from there.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Abhilash Warrier – Community Spotlight

We are honored to recognize Abhilash Warrier as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
Martin Tocauer Profile Picture

Martin Tocauer 4

#2
Community Member Profile Picture

Community Member 2

#2
Nayyar Siddiqi Profile Picture

Nayyar Siddiqi 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans