Hi Product Team,
We are facing an issue when , in offline mode, we press a custom button that calls custom API.
This button works perfectly if we are in online mode.
When pressing the button in offline mode we get this error in event viewer
Retail proxy client offline request failed. RequestUri: crt://offline/CustCountingManager/CalliopeGetInStoreCustomerByAccountNum?queryResultSettings=SCRUBBED&customerNumber=SCRUBBED&$locale=SCRUBBED. Exception: System.InvalidOperationException: Can't find manager (CustCountingManager) with method (CalliopeGetInStoreCustomerByAccountNum) with parameter count (2)
at Microsoft.Dynamics.Commerce.RetailProxy.Adapters.AdaptorCaller.CallCommerceRuntimeAsync(String allInOneUrlString)
at Microsoft.Dynamics.Commerce.RetailProxy.Adapters.AdaptorCaller.ExecuteAsync(String allInOneUrl).
Please find below all the code needed
1 - ts code in POS button
let getInStoreCustomerRequest: CustCounting.CalliopeGetInStoreCustomerByAccountNumRequest<CustCounting.CalliopeGetInStoreCustomerByAccountNumResponse> =
new CustCounting.CalliopeGetInStoreCustomerByAccountNumRequest(customer.AccountNumber);
let countResponse: ClientEntities.ICancelableDataResult<CustCounting.CalliopeGetInStoreCustomerByAccountNumResponse> = await this.context.runtime.executeAsync(getInStoreCustomerRequest);
2- Controller in crt project
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Dynamics.Commerce.Runtime;
using Microsoft.Dynamics.Commerce.Runtime.DataModel;
using Microsoft.Dynamics.Commerce.Runtime.Hosting.Contracts;
using Microsoft.Dynamics.Commerce.Runtime.Messages;
///
/// The controller to retrieve a new entity.
///
[RoutePrefix("CustCounting")]
[BindEntity(typeof(CustCounting))]
public class CustomerCountController : IController
{
///
/// Gets customer present in a given store by Account number.
///
/// The parameters to this action.
/// The list of customers count records.
[HttpPost]
[Authorization(CommerceRoles.Application, CommerceRoles.Employee)]
public async Task<PagedResult> CalliopeGetInStoreCustomerByAccountNum(IEndpointContext context,string customerNumber, QueryResultSettings queryResultSettings)
{
var request = new GetInStoreCustomerDataRequest(customerNumber) { QueryResultSettings = queryResultSettings };
var reponse = await context.ExecuteAsync(request).ConfigureAwait(false);
return reponse.customers;
}
}
3 - Data entiy class in crt project
( please note that i'am using using SystemDataAnnotations = System.ComponentModel.DataAnnotations for key entity)
namespace Calliope.CommerceRuntime
{
using System;
using System.Runtime.Serialization;
using Microsoft.Dynamics.Commerce.Runtime.ComponentModel.DataAnnotations;
using Microsoft.Dynamics.Commerce.Runtime.DataModel;
using SystemDataAnnotations = System.ComponentModel.DataAnnotations;
/// <summary>
/// Defines a simple class that holds information about Customer couting for a particular day.
/// </summary>
public class CustCounting : CommerceEntity
{
private const string ChannelId = "CHANNELID";
private const string CustomerNumberColumn = "ACCOUNTNUMBER";
private const string EntryDateColumn = "CREATEDDATETIME";
private const string TransactionIdColumn = "TRANSACTIONID";
private const string Name = "NAME";
private const string FirstName = "FIRSTNAME";
private const string LastName = "LASTNAME";
private const string InvoiceAccount= "INVOICEACCOUNT";
private const string Address = "ADDRESS";
private const string Phone = "PHONE";
private const string CardNumber = "CARDNUMBER";
/// <summary>
/// Initializes a new instance of the <see cref="CustCounting"/> class.
/// </summary>
public CustCounting()
: base("CustCounting")
{
}
/// <summary>
/// Gets or sets the customer Name.
/// </summary>
[DataMember]
[Column(Name)]
public string CustomerName
{
get { return (string)this[Name]; }
set { this[Name] = value; }
}
/// <summary>
/// Gets or sets the customer Name.
/// </summary>
[DataMember]
[Column(TransactionIdColumn)]
public string CartTransactionId
{
get { return (string)this[TransactionIdColumn]; }
set { this[TransactionIdColumn] = value; }
}
/// <summary>
/// Gets or sets Customer First Name.
/// </summary>
[DataMember]
[Column(FirstName)]
public string CustomerFirstName
{
get { return (string)this[FirstName]; }
set { this[FirstName] = value; }
}
/// <summary>
/// Gets or sets Customer Last Name.
/// </summary>
[DataMember]
[Column(LastName)]
public string CustomerLastName
{
get { return (string)this[LastName]; }
set { this[LastName] = value; }
}
/// <summary>
/// Gets or sets Customer Invoice account.
/// </summary>
[DataMember]
[Column(InvoiceAccount)]
public string CustomerInvoiceAccount
{
get { return (string)this[InvoiceAccount]; }
set { this[InvoiceAccount] = value; }
}
/// <summary>
/// Gets or sets Customer Address.
/// </summary>
[DataMember]
[Column(Address)]
public string CustomerAddress
{
get { return (string)this[Address]; }
set { this[Address] = value; }
}
/// <summary>
/// Gets or sets Customer Phone.
/// </summary>
[DataMember]
[Column(Phone)]
public string CustomerPhone
{
get { return (string)this[Phone]; }
set { this[Phone] = value; }
}
/// <summary>
/// Gets or sets Customer CardNumber.
/// </summary>
[DataMember]
[Column(CardNumber)]
public string CustomerCardNumber
{
get { return (string)this[CardNumber]; }
set { this[CardNumber] = value; }
}
///// <summary>
///// Gets or sets the Exit date.
///// </summary>
//[DataMember]
//[Column(ExitDateColumn)]
//public DateTime ExitDate
//{
// get { return (DateTime)this[ExitDateColumn]; }
// set { this[ExitDateColumn] = value; }
//}
/// <summary>
/// Gets or sets the Customer account.
/// </summary>
[SystemDataAnnotations.Key]
[Key]
[DataMember]
[Column(CustomerNumberColumn)]
public string CustomerNumber
{
get { return (string)this[CustomerNumberColumn]; }
set { this[CustomerNumberColumn] = value; }
}
/// <summary>
/// Gets or sets the Store Number.
/// </summary>
[SystemDataAnnotations.Key]
[Key]
[DataMember]
[Column(ChannelId)]
public string Channel
{
get { return (string)this[ChannelId]; }
set { this[ChannelId] = value; }
}
/// <summary>
/// Gets or sets the EntryDate.
/// </summary>
[SystemDataAnnotations.Key]
[Key]
[DataMember]
[Column(EntryDateColumn)]
public DateTime EntryDate
{
get { return (DateTime)this[EntryDateColumn]; }
set { this[EntryDateColumn] = value; }
}
}
}
4 - Request
namespace Calliope.CommerceRuntime
{
using System.Runtime.Serialization;
using Microsoft.Dynamics.Commerce.Runtime.Messages;
/// <summary>
/// A simple request class to get a list of customer within a store for a particular day.
/// </summary>
[DataContract]
public sealed class GetInStoreCustomerDataRequest : Request
{
/// <summary>
/// Initializes a new instance of the <see cref="GetInStoreCustomerDataRequest"/> class.
/// </summary>
/// <param name="CustomerNumber">The Customer number.</param>
public GetInStoreCustomerDataRequest(string customerNumber)
{
this.CustomerNumber = customerNumber;
}
/// <summary>
/// Gets the Customer number related to the request.
/// </summary>
[DataMember]
public string CustomerNumber { get; private set; }
}
}
5- Response
namespace Calliope.CommerceRuntime
{
using System.Runtime.Serialization;
using Microsoft.Dynamics.Commerce.Runtime;
using Microsoft.Dynamics.Commerce.Runtime.Messages;
/// <summary>
/// Defines a simple response class that holds a list of customer instances.
/// </summary>
[DataContract]
public sealed class GetInStoreCustomerDataResponse : Response
{
/// <summary>
/// Initializes a new instance of the <see cref="GetInStoreCustomerDataResponse"/> class.
/// </summary>
/// <param name="customers">The collection of customers.</param>
public GetInStoreCustomerDataResponse(PagedResult<CustCounting> customers)
{
this.customers = customers;
}
/// <summary>
/// Gets the found customers as a paged result set.
/// </summary>
[DataMember]
public PagedResult<CustCounting> customers { get; private set; }
}
Hi Product Team, We are facing an issue when , in offline mode, we press a custom button that calls custom API.
This button works perfectly if we are in online mode.
When pressing the button in offline mode we get this error in event viewer
Retail proxy client offline request failed. RequestUri: crt://offline/CustCountingManager/CalliopeGetInStoreCustomerByAccountNum?queryResultSettings=SCRUBBED&customerNumber=SCRUBBED&$locale=SCRUBBED. Exception: System.InvalidOperationException: Can't find manager (CustCountingManager) with method (CalliopeGetInStoreCustomerByAccountNum) with parameter count (2) at Microsoft.Dynamics.Commerce.RetailProxy.Adapters.AdaptorCaller.CallCommerceRuntimeAsync(String allInOneUrlString) at Microsoft.Dynamics.Commerce.RetailProxy.Adapters.AdaptorCaller.ExecuteAsync(String allInOneUrl).
Please find below all the code needed
1 - ts code in POS button
2- Controller in crt project
using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Dynamics.Commerce.Runtime; using Microsoft.Dynamics.Commerce.Runtime.DataModel; using Microsoft.Dynamics.Commerce.Runtime.Hosting.Contracts; using Microsoft.Dynamics.Commerce.Runtime.Messages;
///
/// The controller to retrieve a new entity.
///
[RoutePrefix("CustCounting")]
[BindEntity(typeof(CustCounting))]
public class CustomerCountController : IController
{
///
/// Gets customer present in a given store by Account number.
///
/// The parameters to this action.
/// The list of customers count records.
[HttpPost]
[Authorization(CommerceRoles.Application, CommerceRoles.Employee)]
public async Task<PagedResult> CalliopeGetInStoreCustomerByAccountNum(IEndpointContext context,string customerNumber, QueryResultSettings queryResultSettings)
{
var request = new GetInStoreCustomerDataRequest(customerNumber) { QueryResultSettings = queryResultSettings };
var reponse = await context.ExecuteAsync(request).ConfigureAwait(false);
} }
3 - Data entiy class in crt project ( please note that i'am using using SystemDataAnnotations = System.ComponentModel.DataAnnotations for key entity)
namespace Calliope.CommerceRuntime { using System; using System.Runtime.Serialization; using Microsoft.Dynamics.Commerce.Runtime.ComponentModel.DataAnnotations; using Microsoft.Dynamics.Commerce.Runtime.DataModel; using SystemDataAnnotations = System.ComponentModel.DataAnnotations;
}
4 - Request
namespace Calliope.CommerceRuntime { using System.Runtime.Serialization; using Microsoft.Dynamics.Commerce.Runtime.Messages;
}
5- Response
namespace Calliope.CommerceRuntime { using System.Runtime.Serialization; using Microsoft.Dynamics.Commerce.Runtime; using Microsoft.Dynamics.Commerce.Runtime.Messages;
}
Please help