parse-community / Parse-SDK-dotNET

Parse SDK for .NET, Xamarin, Unity.
http://parseplatform.org
Apache License 2.0
323 stars 261 forks source link

The type initializer for 'VersionInformation' threw an exception. #316

Closed Jparrishau closed 5 years ago

Jparrishau commented 5 years ago

I am getting this exception thrown when trying to Initialize. It is due to the VersionInformation. It seems the Assembly.GetEntryAssembly() is returning null. Has anyone else gotten this before who can help with fixing it? I've tried over-writting it with the optional parameter and still no luck. I am using a recent build from the master branch.

NullReferenceException: Object reference not set to an instance of an object
Parse.ParseClient+Configuration+VersionInformation..cctor () (at C:/Users/Taylor/Downloads/Parse-SDK-dotNET-master/Parse/Public/ParseClient.cs:130)
Rethrow as TypeInitializationException: The type initializer for 'VersionInformation' threw an exception.
Parse.ParseClient.Initialize (Parse.ParseClient+Configuration configuration) (at C:/Users/Taylor/Downloads/Parse-SDK-dotNET-master/Parse/Public/ParseClient.cs:242)
ParseManager.Start () (at Assets/ParseManager.cs:18)
TobiasPott commented 5 years ago

Hi @Jparrishau actually this is very little information to work with or trying to help you.

Could you elaborate in which environment you are working or trying to use the Parse SDK for .NET? Do you use Unity, do you use Xamarin or are you building a classic .NET application

The "ParseManager.Start()" call in your stack trace looks like Unity but could you provide some more information?

Jparrishau commented 5 years ago

Sorry, I forgot this isn't strictly a unity SDK. Yes it is for Unity.

The problem is that Assembly.GetEntryAssembly() is returning null. I'm still looking into why this is, but regardless. There are no checks in place to prevent this error from being thrown. Even if you overwrite the Storage and VersionInfo using the optional params. You will still get an exception error. Due to lines 137 and 57 of parse client. Where the assembly is attempting to be accessed inline. For now, I manually changed these parameters and re-built. Which solved my problem. I will continue to look into why the assembly is null.

public static MetadataBasedStorageConfiguration NoCompanyInferred { get; } = new MetadataBasedStorageConfiguration { CompanyName = Assembly.GetEntryAssembly().GetName().Name, ProductName = String.Empty };

public static VersionInformation Inferred { get; } = new VersionInformation { BuildVersion = Assembly.GetEntryAssembly().GetName().Version.Build.ToString(), DisplayVersion = Assembly.GetEntryAssembly().GetName().Version.ToString(), OSVersion = Environment.OSVersion.ToString() };

TobiasPott commented 5 years ago

You are welcome @Jparrishau , The automatically generated [..]Configuration instances which are used by default if you not fully create them by your own, rely on calls to the Assembly.GetEntryAssembly() method which does not provide usefaul objects. This is due to the way Unity creates the final application and the assemblies which are contained in it's folders. I did not yet had the time to actually dig into the real reason but I assume that Unity does some stripping of classes and methods usually not required or used in games and/or the fact that some methods or classes are referencing other assemblies which are not allowed on all platforms Unity can target (e.g. some parts of the System.Reflections namespace cannot be used on iOS platforms.

TL;DR: The current master branch of this repository does not support Unity and aims for .NET Standard support for 'classic' .NET/.NET Standard or Xamarin build workflow.

Unity applies some specialities to their builds and support for Unity will be done as soon as a basic plug-in-like structure is defined to allow changing the required parts of the Code without putting all Special code into the master repository @TheFanatr did a better job explaining this in a different issue post ^^.

As for your problem, you might head over to my fork which adopted this repository and made those changes to work with Unity in the first run. https://github.com/TobiasPott/Parse-SDK-dotNET/tree/feature/recode-unity-support Checkout the feature branch i've linked and follow the build steps for Unity in the Readme.md This should resolve all your problems regarding the configurations and get you at least initializing the SDK in your application and communicate with your Parse server instance

You should be aware that some features or Parse SDK (e.g. Push notifications are not available yet with the rewrite of this repository for .NET Standard).

Feel free to ask if you have any further questions or face any new problems.

jthra037 commented 5 years ago

I am new to Parse and I also had this issue, running Windows 10 and Unity 2018.4 with Parse server hosted locally on machine. Using your fork @TobiasPott I stopped receiving errors after building new a DLL, but now I get nothing but errors when I try to do anything with Parse post-initialization. Specifically I am trying to sign up a new user, and getting "Invalid or alternatively-formatted response received from server."

The message originates from this block of code: public static async Task SignUp(string username, string email, string pwd, string location)

{
    ParseObject user = new ParseObject("User");
    user["username"] = username;
    user["email"] = email;
    user["password"] = pwd;
    user["location"] = location;
    try
    {
        await user.SaveAsync();
    }
    catch (Exception e)
    {
        Debug.LogError(string.Format("{0}\n{1}", e.Message, e.StackTrace));
    }
}
TobiasPott commented 5 years ago

Hi @jthra037 I cannot really answer on your issue with the SignUp method yet as I don't use it for our project at work.

Could you create a new issue, describing your new problem in more detail as this might be not only be related to the Parse SDK for .NET but also the configuration and access limitations of the Parse server (which I don't know that much about =/) I believe it would be helpful to know what configuration you are using either on the client and on the server side, and if the problem also occurs when using a hosted Parse installation on a service like heroku?

I'll consider this case closed as it is not related to the main repository in the latest branch and can be solved using my fork (or use the changes from that one)

NadjibR commented 4 years ago

I have the same issue.

System.TypeInitializationException: 'The type initializer for 'VersionInformation' threw an exception.'

Dev Env : Xamarin Forms 4.4 Parse version : 2.0.0-develop (Compiled from the source code)

The only Parse' code in my app is :

private ParseClient.Configuration config;

config.ApplicationID = "*****";
config.Key = "*****";
config.ServerURI = "http://****:1337/parse";

ParseClient.Initialize(config);
TobiasPott commented 4 years ago

hi @NadjibR

This is very little information you provide but as I'm trying to run the latest repository state it gives me the System.TypeInitializationException too pointing to the constructor of the VersionInformation type. This issue is slightly related to the overall issue when using Parse within Unity for Android or iOS the context the application runs in is different compared to a 'classic' .NET Standard application.

This includes several calls to Assembly.GetEntryAssembly and the 'GetExecuting...' or 'GetCalling...' methods. I'm not too sure about the exact details and anyone with more insight might help out, but some of these methods used in the repository (or working with a pure .NET Standard application) do not work on Android or iOS platforms as the application runs in a different context and referenced returned by the mentioned methods might not point to a managed object but to some classes from the native part surrounding the Xamarin.Forms application (or Unity build for iOS or Android).

I'm addressing this issue with my target platform implementation branch https://github.com/TobiasPott/Parse-SDK-dotNET/blob/feature/implement-target-platform-configurations/Platforms.md for the mentioned Unity platform and I'm pretty sure that it might be possible to provide a solution in a similar manner for Xamarin.Forms applications.

You may give it a try and take a look at the feature branch https://github.com/TobiasPott/Parse-SDK-dotNET/tree/feature/implement-target-platform-configurations and reach out to me on the issue board of that repository.

Best regards Tobias

lunjio commented 4 years ago

Hi all, I am trying to use a parse server as backend and faced with the same exception, I'm using a Prism framework with unity container, and XF 4.4, however changing GetEntryAssembly to GetExecutingAssembly and rebuilding helped me to solve the problem

lunjio commented 4 years ago

Happiness was not so long, now I get exception - "Invalid or alternatively-formatted response recieved from server." while trying to test cloud function

lunjio commented 4 years ago

I have the same issue. System.TypeInitializationException: 'The type initializer for 'VersionInformation' threw an exception.' Dev Env : Xamarin Forms 4.4 Parse version : 2.0.0-develop (Compiled from the source code) The only Parse' code in my app is : private ParseClient.Configuration config;

config.ApplicationID = ""; config.Key = ""; config.ServerURI = "http://****:1337/parse";

ParseClient.Initialize(config);

Have you downloaded project and build it yourself ? If so, try open ParseClient class and change GetEntryAssembly to GetExecutingAssembly, it helped for me, I got the same exception, using Prism and XF 4.4. And don't forget the backslash "http://****:1337/parse/"

NadjibR commented 4 years ago

I have the same issue. System.TypeInitializationException: 'The type initializer for 'VersionInformation' threw an exception.' Dev Env : Xamarin Forms 4.4 Parse version : 2.0.0-develop (Compiled from the source code) The only Parse' code in my app is : private ParseClient.Configuration config; config.ApplicationID = ""; config.Key = ""; config.ServerURI = "http://****:1337/parse"; ParseClient.Initialize(config);

Have you downloaded project and build it yourself ? If so, try open ParseClient class and change GetEntryAssembly to GetExecutingAssembly, it helped for me, I got the same exception, using Prism and XF 4.4. And don't forget the backslash "http://****:1337/parse/"

You're right. Changing GetEntryAssembly to GetExecutingAssembly in : https://github.com/parse-community/Parse-SDK-dotNET/blob/master/Parse/Public/ParseClient.cs#L57 and in : https://github.com/parse-community/Parse-SDK-dotNET/blob/master/Parse/Public/ParseClient.cs#L130

solved the problem.

Thanks :)

lunjio commented 4 years ago

As told TobiasPott it doesn't solve the problem, but at least gives ability to start project and test an API. I came to conclusion, that everywhere where GetEntryAssembly returns null, due to the operation system specific execution (Android doesn't have executable file) we must supply a new method:

public static void PlatformInitialize()
        {
            EntryAssembly = Assembly.GetCallingAssembly();
        }

where EntryAssembly:

private static Assembly EntryAssembly
        {
            get
            {
                return _entryAssembly = _entryAssembly?? Assembly.GetEntryAssembly();
            }

            set
            {
                _entryAssembly = value;

            }
        }

Also as result we must change calls Assembly.GetEntryAssembly() to EntryAssembly. So on android I must only call PlatformInitialize(). It's my solution, so i think there are should be also cheking if Assembly.GetEntryAssembly() returns null, we must to throw exeption to a user and promt to call PlatformInitialize() in the platform specific project.