C# - Include 3rd party library on client

Hello,

I have been trying to include a third party library into the C# client code and in the server code. The library i’m trying to include is either MessagePack or NewtonsoftJson. I did a little test on the server and it worked like a charm

Example serverside code:

        private async Task OnTick()
        {
            List<int> nums = new List<int>();
            Random r = new Random();

            for (int i = 0; i < 10; i++)
            {
                nums.Add(r.Next(0, 100));
            }

            string value = JsonConvert.SerializeObject(nums);
            Debug.WriteLine(value);

            await Delay(100);
        }

The code will serialize the list of ints to a string that I could send over the network. It runs fine without errors.

Now here is the crux, when I run the exact same code on the client which is setup the exact same as the server (adding reference to NewtonsoftJson) I get an error.

[    270657] Failed to run a tick for CovClient: System.BadImageFormatException: Error verifying CovClient.CovClient/<OnTick>d__1:MoveNext (): Cannot load method from token 0x0a00001e for call at 0x003d
[    270657]   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine] (TStateMachine& stateMachine) [0x0002c] in <a4e3abdd630b4c98a9d6f31a99197de6>:0 
[    270657]   at CovClient.CovClient.OnTick () [0x00026] in <9ec3b266e323436b825bef59ddcd9cd0>:0 
[    270657]   at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x0000f] in <a4e3abdd630b4c98a9d6f31a99197de6>:0 

It is trying to call the NewtonsoftJson library, but for some reason it gets loaded incorrectly (or not at all).

I might have the wrong idea how client deals with extra libraries and references… So tl;dr;

  1. Can you include a 3rd party library (MessagePack, NewtonsoftJson) onto the client side? (Or is this not possible?)
  2. If so, what am i doing wrong?
1 Like

Third-party libraries must a) be specified with file and b) support the (legacy, yes) PCL/SL5 profiles.

For Newtonsoft.Json, this means that you’ll have to manually extract the PCL version from the .nupkg.

3 Likes

Thanks for the quick response, I’ll give that a try! :smiley:

Would you be able to share your findings, @Syntasu? I’m interested in using this as well. What did you end up doing to get this working?

I’ve looked into it… and it seems really bothersome to convert everything to a PCL (Portable Class Library). I tried using it withiout it being a PCL, gave me errors as suspected…

Because PCL is legacy, most 3rd party libraries don’t support it at all, which is really a downer :confused:

Atleast for me C# is out of the question. Simply because i can’t afford to convert everything, it’s way too time consuming. Other ways revolve around a “poor man’s” solution for serialization or what ever your 3rd party library does.

I’ve reverted my code base back to Lua.

why would you even need third-party libraries other than serialization libraries, anyhow?

In my scenario I’m in need of a IoC container for dependency injection. Since I can’t use any of the third party libraries, I wrote my own. I don’t want to reinvent the wheel when possible. Can’t think of anything else right now.

@roentgenium I’ve tried the solution you posted (using the portable Newtonsoft.Json.dll, specified it as a “file” in __resource.lua)

The server script doesn’t throw any errors, but the client script throws a FileNotFoundException, saying it can’t find Newtonsoft.Json.

Any ideas?

EDIT: Somehow got it to load, but now getting this:

Exception loading assembly Newtonsoft.Json: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.

EDIT 2: Switching to System.Runtime.Serialization.dll gives this error:

System.Runtime.Serialization.dll is not a platform image (even though the dir matches).

I just want to serialize/deserialize json data…HELP!

According to this StackOverflow question, JSON.NET has a PCL version of the library available.

JSON.NET is available on NuGet and can be installed using the following command in the VS Package Manager:

Install-Package JSON.NET

Please note that this will only work if you are actually targeting the Portable Class Library with your solution, otherwise it’ll pick a different target.

Fortunately, it is open source, and the binaries can be found on the Github releases page:

Select the .zip file attached to a release, check the Bin folder for the Portable Class Library (PCL) AND SL5 target.

I haven’t tried this myself yet, but I looked into it since I’m likely going to need Json in the future, so please let me know if you can get this to work!

@_hb After talking to a couple people on the FiveM Discord, I had tried the PCL/SL5 DLL, but still had the same results.

I may look at it again in the future, because I can envision having to use JSON for other scripts later.

But for this particular case, I just simplified the data structures that I was transmitting, and ended up passing a bunch of arguments into the events. I needed three Vector3 objects, so I ended up passing nine float arguments! YUCK!

It’s kludgey as hell, but at least it works.

But like I said, I’m going to look at JSON again for a future script, so if you are able to get it working, please let me know! Actually, looking back as I’m typing this…we had an instance where an unrelated code change I made didn’t take effect until we cleared the cache on the server and restarted it. So it’s possible that the PCL/SL5 DLL will work, but I got the same error messages because I hadn’t cleared the cache.

I have a working script now, so I’m not willing to rewind at this point, lol…but if you want to try, it’s worth a shot!!

I have just confirmed that this works as expected, using my own instructions and following what @roentgenium said.

/cc @Syntasu @Stealth22

Yes sorry, I forgot to post back here.

I think I was using the wrong DLL, because I revisited the issue and tried again, and it worked!

Either that, and/or the file Newtonsoft.Json.dll in your resource file has to be before your script. One/both of those fixed it for me! Now I’ve got everything in JSON! :smiley:

I’m reading this post since a week and a don’t add NewtonJson on client with success.

If some one can help me :slight_smile:

There is my resource file :

client_script {
‘client/R68.Client.LoginResource.net.dll’
}

files {
‘Newtonsoft.Json.dll’
}

In my Visual Studio, the client project is setup as :
Targeted framework : .NET Framework 4.5.2
Type: ClassLibrary

In my references, I directly link the NewtonJson.dll in the portable-net40+sl5+win8+wp8+wpa81 folder. NewtonJson was download with Nuget but not reference in the client project with Nugget (only on the server project).

In client log I have :
C:\Users\xxxxxxx\AppData\Local\FiveM\FiveM.app\citizen\clr2\lib\mono\4.5 System.Runtime.Serialization.dll is not a platform image (even though the dir matches).

I’m very confused, I don’t know where I make mistake.
Any body have an idea ?

You will need to use the PCL for .Net 4.0 SL in order to use it client side

Thx for your answer. Where can I found it ? I’m using the dll in the portable-net40+sl5+win8+wp8+wpa81 folder.

It’s seems System.Runtime.Serialization.dll is not a platform image (even though the dir matches) don’t block the system. It’s work.

Just to update everyone, I just ran into the issue and resolved it immediatly by following the info @_hb provided.

In the bin folder of NewtonSoft.Json select the portable-net40+win8+wpa81+wp8+sl5 dll and add that as a reference to your project. I then added it to my files array in the __resource.lua.

No more issues.

1 Like

I was having similar issues, turned out there was an additional requirement that the Newtonsoft.Json.dll reside in the root directory of the resource.

For anyone else trying to include a 3rd party library, here’s the explicit steps I took to get it to work with Newtonsoft.Json:

  1. Make sure the C# project is building with a target of .NET Framework 4.5.2
  2. Add a NuGet dependency on Newtonsoft.Json to the project.
  3. Do “Add->Reference” on the project, select the Newtonsoft.Json.dll from portable-net40+sl5+win8+wp8+wpa81
  • I had to remove the NuGet added reference to Newtonsoft.Json.dll, and re-add the explicit file.
  • Path: <solution>\packages\Newtonsoft.Json.12.0.2\lib\portable-net40+sl5+win8+wp8+wpa81\Newtonsoft.Json.dll
  1. Copy that same dll file to the base of the resource directory.
  2. Add Newtonsoft.Json.dll to __resource.lua
files {
    'Newtonsoft.Json.dll'
}

This is for my server script. I have a client dll and a server dll in my resource, under client/ and server/ directories. The Newtonsoft dependency would not work if it was in the server directory, only works if it is in the root directory of the resource.

3 Likes

I know this is a few years old at this point, but for anyone having issues still with Mono V2 and wanting to try out C# for FiveM. My issue is I was putting all my dependencies in a directory as stated here. Mine was “Dependencies/” while theirs is “server/”. Make sure to place any dependencies in the root of the resource folder. Not sure why this makes a difference, but oh well!