question

alexbraniff avatar image
alexbraniff asked

C# SDK Economy V2 Item DisplayProperties Error

Hello all,

I am attempting to create / update an item stack with custom DisplayProperties in the Economy V2 C# SDK but everything I seem to try results in the same error from PlayFab:

 System.Reflection.TargetParameterCountException: 'Parameter count mismatch.'

I am using the following code to Add a new stack with custom DisplayProperties:

 await PlayFabEconomyAPI.ExecuteInventoryOperationsAsync(new ExecuteInventoryOperationsRequest
 {
     AuthenticationContext = AuthenticationContext,
     CollectionId = item.CollectionId,
     Entity = new EntityKey
     {
         Type = "title_player_account",
         Id = AuthenticationContext?.EntityId,
     },
     Operations = new List<InventoryOperation>
     {
         new InventoryOperation
         {
             Add = new AddInventoryItemsOperation
             {
                 Amount = item.Count.Amount,
                 Item = new InventoryItemReference
                 {
                     Id = item.Id,
                     StackId = item.StackId,
                 },
                 NewStackValues = new InitialValues
                 {
                     DisplayProperties = item.DisplayProperties,
                 },
             },
         }
     },
 });

The Id and StackId are the same string (a guid as a string), the CollectionId is a valid string, Amount is a positive integer, the call even works if I simply do not attempt to pass a NewStackValues property...

I have tried everything I can think of for the DisplayProperties... I've tried a class like I assumed would be possible initially since the underlying type is just 'object,' I've tried a modified class with serialized strings instead of any of the 'real' data types (thinking I could deserialize on my own), I've tried a serialized version of both of those classes, a Dictionary<string, object?>?, an anonymous object with both the true data types and serialized string representations...

Ultimately the data I want to save is the following:

 {
     "startTimeUtc": "2023-05-09T01:18:56.113Z",
     "timeSpan": {
         "timeToCompleteDays": 0,
         "timeToCompleteHours": 0,
         "timeToCompleteMinutes": 15,
         "timeToCompleteSeconds": 0
     },
     "endTimeUtc": "2023-05-09T01:33:56.113Z"
 }

Full stack trace on PasteBin

I am just out of ideas and I think I need help. Any insight or ideas on the matter would be appreciated.

Thank you.

sdksIn-Game Economy
1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

alexbraniff avatar image alexbraniff commented ·

Added to original question

0 Likes 0 ·
Simon Cui avatar image
Simon Cui answered

Thanks for the information. You can try to set a class and create an object like this:

 public class TimeSpan
 {
     public int timeToCompleteDays { get; set; }
     public int timeToCompleteHours { get; set; }
     public int timeToCompleteMinutes { get; set; }
     public int timeToCompleteSeconds { get; set; }
 }
    
 public class MyData
 {
     public DateTime startTimeUtc { get; set; }
     public TimeSpan timeSpan { get; set; }
     public DateTime endTimeUtc { get; set; }
 }
    
    
 // create MyData object and assign value
 MyData myData = new MyData
 {
     startTimeUtc = DateTime.Parse("2023-05-09T01:18:56.113Z"),
     timeSpan = new TimeSpan
     {
         timeToCompleteDays = 0,
         timeToCompleteHours = 0,
         timeToCompleteMinutes = 15,
         timeToCompleteSeconds = 0
     },
     endTimeUtc = DateTime.Parse("2023-05-09T01:33:56.113Z")
 };

Then you can pass the object “MyData” to DisplayProperties and call API Inventory - Execute Inventory Operations - REST API (PlayFab Economy) | Microsoft Learn. Please let us know if there is still any other issue.

3 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

alexbraniff avatar image alexbraniff commented ·

Thanks for the suggestion. This is very very similar to the first thing I tried, produced the same error. Only difference is the the property names are snakeCase and mine were PascalCase. Will try this in a bit but I am not expecting a different outcome. Will report back.

0 Likes 0 ·
alexbraniff avatar image alexbraniff commented ·

I am flabbergasted that having lowercase property name changes anything about this at all but thank you so much. That apparently was the problem and it serializes what you have provided, no issues. If you know why this happens, could you explain? Or is this a bug that I should report somehow?

Thank you again!

0 Likes 0 ·
alexbraniff avatar image alexbraniff commented ·

P.S. In case anyone is wondering, my original classes were as follows:

  public class TimeSpanDetail
  {
      public int TimeToCompleteDays { get; set; }
      public int TimeToCompleteHours { get; set; }
      public int TimeToCompleteMinutes { get; set; }
      public int TimeToCompleteSeconds { get; set; }
  }
        
  public class MyData
  {
      public DateTime StartTimeUtc { get; set; }
      public TimeSpan TimeSpan { get; set; }
      public DateTime EndTimeUtc { get; set; }
  }
        
        
  // create MyData object and assign value
  MyData myData = new MyData
  {
      StartTimeUtc = DateTime.Parse("2023-05-09T01:18:56.113Z"),
      TimeSpan = new TimeSpan
      {
          TimeToCompleteDays = 0,
          TimeToCompleteHours = 0,
          TimeToCompleteMinutes = 15,
          TimeToCompleteSeconds = 0
      },
      EndTimeUtc = DateTime.Parse("2023-05-09T01:33:56.113Z")
  };

You can see why one might not expect the casing of their properties to make a difference to the serializer. At the very least, there could be a better exception message to hint at the problem to future devs.

0 Likes 0 ·
Simon Cui avatar image
Simon Cui answered

As I can see from your codes, the “Operations” should be a list instead of single object. Such as: Operations = new List{}. Please also check if there is any other type issues. 5935-microsoftteams-image.png


1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

alexbraniff avatar image alexbraniff commented ·

Yeah, at some point dotnet began allowing use of new() to drop the need for explicitly mentioning type so in my code

 Operations = new()
      {
          new InventoryOperation { ... }
      },

is equivalent to

 Operations = new List&lt;InventoryOperation&gt;()
      {
          new InventoryOperation { ... }
      },

Sorry for the confusion there and I have updated the post. No other type issues as far as I can tell, like I said, the call works if I keep everything the same and leave off NewStackValues property. Very strange.

0 Likes 0 ·
kylemc@microsoft.com avatar image
kylemc@microsoft.com answered

Do you have a better stack trace? I suspect the error is happening in the serializer and not the request construction, but it's hard to tell. A location like this wouldn't surprise me.

https://github.com/PlayFab/CSharpSDK/blob/master/PlayFabSDK/source/Json/SimpleJson.cs#L1620

After looking through that file a bit, I think using a Dictionary<string, object> is probably the type you need.

2 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

alexbraniff avatar image alexbraniff commented ·

Yes, and it does look like you are correct, something with playfab's serializer when it does reflection. Pastebin link has the full stack trace:

PasteBin Stack Trace

I will give the Dictionary<string, object> another shot while Im at it, thanks for the suggestion

0 Likes 0 ·
alexbraniff avatar image alexbraniff commented ·

Seems to produce the same error when I try providing Dictionary<string, object> with all serialized strings, both dateTimes and a string to represent the sub object, strings as dateTimes and the full sub object, all three as the raw types... :(

I've also tried just including endTimeUtc in a bunch of different ways now as well:

 new
             {
                 EndTimeUtc = DateTime.UtcNow,
             }


 new Dictionary&lt;string, object&gt;
             {
                 { "EndTimeUtc", DateTime.UtcNow },
             }

 new Dictionary&lt;string, object&gt;
             {
                 { "EndTimeUtc", DateTime.UtcNow.ToString() },
             }

 new Dictionary&lt;string, object&gt;
             {
                 { "EndTimeUtc", Json.Serialize(DateTime.UtcNow) },
             }

(Json.Serialize just uses System.Text.Json to provide some JsonSerializerOptions we use for everything in our project)

Not sure what else to try...

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.