Issues after upgrading from ServiceStack 4.5.14 to 6.9

Thanks for your help. we have implemented as per your suggestion. With the new ServiceStack 6.9 version I am getting another exception recently from AppHost:

Error message:
System.IO.FileLoadException: ‘Could not load file or assembly ‘Microsoft.Bcl.AsyncInterfaces, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)’

CallStack information:

at ServiceStack.ServiceStackHost…ctor(String serviceName, Assembly assembliesWithServices)
at ServiceStack.AppHostHttpListenerBase…ctor(String serviceName, Assembly assembliesWithServices)
at HP.HPTRIM.ExchangeLink.AdminConsole.AppHost…ctor() in C:\REPOS\trim\CSharp\HP.HPTRIM.ExchangeLink.AdminConsole\Program.cs:line 26

Looks the below ServiceStack code is looking for exact version of 5.0? Currently i am referring Microsoft.Bcl.AsyncInterfaces version 7.0. Is this something i need to change back to 5.0 to compatible with Servicestack?

 protected AppHostHttpListenerBase(string serviceName, params Assembly[] assembliesWithServices)
            : base(serviceName, assembliesWithServices)
        { }

I am surprised to see this issue after my latest upgrade on Visual studio 2022.

You would need to downgrade to continue to using ServiceStack v6.9, otherwise I’ve just upgraded the dependencies to use Microsoft.Bcl.AsyncInterfaces v7.0.0 from v6.10.1 that’s now available in the latest pre-release NuGet packages

1 Like

Thanks for the response. Does downgrading to Microsoft.Bcl.AsyncInterfaces v5.0 will not have any impact with our ServiceStack v6.9 functionalities or if there will be any impacts what are they? Cause we have done our development changes with servciestack v6.9. We want to make sure there won’t be any issues on servicestack APIs on downgrading Microsoft.Bcl.AsyncInterfaces v5.0.

That’s the version the packages were built against, so that’s going to be the recommended version to use.

Thanks, that’s helpful. One last question, this is one of our last issue we are facing with the upgrade.

When running our project with ServiceStack, we will register the license using Licensing.RegisterLicense(“licenseKeyStringValue”). When registering the license, we are receiving the below error message,

Could not load file or assembly ‘System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040).

StackTrace:
at System.MemoryExtensions.AsSpan(String text)
at ServiceStack.Text.Jsv.JsvReader`1.Parse(String value)
at ServiceStack.Text.TypeSerializer.DeserializeFromString[T](String value)
at ServiceStack.LicenseUtils.ToLicenseKeyFallback(String licenseKeyText)
at ServiceStack.LicenseUtils.RegisterLicense(String licenseKeyText)
at HP.HPTRIM.Service.TrimUtils.LoadLicense() in

Why ServiceStack is expecting this dependency? By default our compiler has the latest version of this DLL, but looks ServiceStack is expecting with the System.Runtime.CompilerServices.Unsafe v4.0.4.1.

This is typically due to a missing assembly binding redirects, have a look at Resolving Runtime Assembly Loading Issues docs for solutions and workarounds. Basically your assembly binding redirect needs to reference the version of System.Runtime.CompilerServices.Unsafe that’s loaded.

Thanks for the response. I have included binding redirects. The binding redirect works for Asp.net projects. For my Asp.net projects, i have pointed the binding redirects in web.config. For our VSTO projects i have included binding redirect on App.config file.

In our VSTO C# addin project developed, which calls ServiceStack. When running those addin projects even with the binding redirects, i am still facing the same issue. In this case what could be the case as it is not working only for Addin projects?

Don’t know what AddIn projects use, I’m assuming just App.config, so the only thing I’d check is to make sure you’re trying to the correct version the project is referencing in the redirect.

I have a .bat file which will copy the System.Runtime.CompilerServices.Unsafe.dll with version 4.0 in our /bin folders to resolve this problem.

I could see System.Runtime.CompilerServices.Unsafe v6.0 DLL is getting shipped/overwriting my existing copied file into /bin folders automatically once I have compiled my solution. I am not sure the reason why the version 6.0 DLL is getting shipped automatically if I compiled the solution.

Currently as the compiler shipping the version 6.0 DLL automatically.

i have added binding redirects like below:


      <dependentAssembly>
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>

This above binding redirect works for web projects. For my console projects it is not working, and i have changed the binding version to 6.0.21.52210 and 6.0.21.0. Still same issue “Could not load file or assembly ‘System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies.”

If i able to find the root cause of why the compiler generating the DLL with v6.0, and if i stop that it will be resolved i believe.

You’ll want to use the Assembly Version not the Assembly File Version which you can find by in an assembly inspector like JetBrains dotPeek, e.g:

Which is typically a major version like 6.0.0.0. This will need to match with the Assembly Version of System.Runtime.CompilerServices.Unsafe.dll in your projects bin/ directory.

Typically that’s all that’s needed to resolve Assembly version errors, I expect non Web Applications to use App.config in their host project to store their assembly binding configuration. You can get more information about assembly errors and can even specify which assembly .dll the App should use by overriding the AppDomain.CurrentDomain.AssemblyResolve event, see this answer for an example:

This sounds very fragile and I would always recommend against overriding the assemblies the build system uses to build your project against.

Missed to add attribute value xmlns=“urn:schemas-microsoft-com:asm.v1” in <assemblybinding> adding that fixes the problem.

Tested in my development environment after all the changes with ServiceStack v.6.9. In my development environment it’s working as expected.

Strange behavior is happening after the installation with the changes. In installation build, I am receiving the same issue “Could not load file or assembly ‘System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies.”. In installation folder(C:\Program Files\Micro Focus\Content Manager) all our binaries are shipped, even our app.config files.

My entire App.config for reference:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
  </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

I am not sure the issue resolved in dev environment, but not after installation(compared both installation and dev files, every files and required DLLS are available). There could be any reasons for this?

The only way I’ve ever needed to resolve Assembly binding redirects is to add an assembly binding to the version that’s running in the App. If the binding isn’t working you’ll need to double-check the version that’s in the bin/ folder of the App that has the issue.

On the rare occasion where Assembly binding doesn’t work you can manually load and return the assembly in the AssemblyResolve event, here’s an example of this in StackOverflow:

Here is another issue we are facing after upgrading from ServiceStack 4.5.14 to 6.9 Fields Value is Null in response.Results(Null Reference Exception in Fields Property)

We are currently facing an issue after upgrading from ServiceStack version 4.5.14 to version 6.9.

The issue revolves around a property named ‘Fields’ defined as follows:

[DataMember]        
[ApiMember(ExcludeInSchema=true, DataType = "object",  Verb = "NONE")]
public FieldDictionary Fields { get; set; }

When attempting to access the ‘Fields’ value in the response object’s ‘Results’ properties using the following code:
var resultFields = response.Results[0].Fields; // This is null in version 6.9

(new System.Collections.Generic.Mscorlib_CollectionDebugView<xx.ServiceModel.Location>(response.Results).Items[0]).Fields

We encounter a System.NullReferenceException with the message “Object reference not set to an instance of an object.”

We have observed that in version 4.5.14, the behavior was correct, and the ‘Fields’ property was returning the value of Fields as expected. However, in ServiceStack version 6.9, the ‘Fields’ is returning null.

We have thoroughly debugged the issue and confirmed that the ‘Fields’ value is present in the ‘httpResponse’ property of the ‘request’ object within the OnEndRequest method in the ServiceStackHost class.

The relevant portions of the code are as follows:

// Within ServiceStackHost class
new System.Collections.Generic.Mscorlib_DictionaryDebugView<string, xx.ServiceModel.IxProperty>((new System.Collections.Generic.Mscorlib_CollectionDebugView<xx.ServiceModel.Location>(((xx.ServiceModel.ObjectSearchResponse<xx.ServiceModel.Location>)((ServiceStack.Host.AspNet.AspNetResponse)((ServiceStack.Host.AspNet.AspNetRequest)request).HttpResponse).Dto).Results).Items[0]).Fields).Items[0]
public virtual void OnEndRequest(IRequest request = null)
{
    try
    {
        if (request != null)
        {
            if (request.Items.ContainsKey(nameof(OnEndRequest)))
                return;

            request.Items[nameof(OnEndRequest)] = bool.TrueString;
        }
        
        var disposables = RequestContext.Instance.Items.Values;
        foreach (var item in disposables)
        {
            Release(item);
        }

        RequestContext.Instance.EndRequest();

        foreach (var fn in OnEndRequestCallbacks)
        {
            fn(request);
        }
    }
    catch (Exception ex)
    {
        Log.Error("Error when Disposing Request Context", ex);
    }
    finally
    {
        if (request != null)
        {
            if (ShouldProfileRequest(request))
            {
                // Populated in HttpHandlerFactory.InitHandler
                if (request.GetItem(Keywords.RequestActivity) is System.Diagnostics.Activity activity
                    && activity.GetTagItem(Diagnostics.Activity.OperationId) is Guid id)
                {
                    var ex = HttpError.GetException(request.Response.Dto);
                    if (ex != null)
                        Diagnostics.ServiceStack.WriteRequestError(id, request, ex);
                    else
                        Diagnostics.ServiceStack.WriteRequestAfter(id, request);
                    
                    Diagnostics.ServiceStack.StopActivity(activity, new ServiceStackActivityArgs { Request = request, Activity = activity });
                }
            }
            
            // Release Buffered Streams immediately
            if (request.UseBufferedStream && request.InputStream is MemoryStream inputMs)
            {
                inputMs.Dispose();
            }
            var res = request.Response;
            if (res is { UseBufferedStream: true, OutputStream: MemoryStream outputMs })
            {
                try 
                { 
                    res.AllowSyncIO().Flush();
                    outputMs.Dispose();
                }
                catch (Exception ex)
                {
                    Log.Error("Error disposing Response Buffered OutputStream", ex);
                }
            }
        }
    }
}

However, when running the below console application in version 6.9:
the value of Fields is null:
we are getting the System.NullReferenceException “Object reference not set to an instance of an object.”

var resultFields = response.Results[0].Fields; // This is null in version 6.9

The Fields value is not getting mapped correctly.

using ServiceStack;

namespace test
{
    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                AA Client = new Client("http://localhost/zz");

                Client.Credentials = System.Net.CredentialCache.DefaultCredentials;

                Locations request = new Locations()
                {
                    q = "me",
                    Properties = new PropertyList( "AccessToTestInterface"),
                    PropertySets = new List<string> { "All" },
                    pageSize = 30,
                    PropertyValue = PropertyType.Both,
                };

                LocationsResponse response = Client.Get<LocationsResponse>(request);

                Location loctest = response.Results[0];

                string testVal = loctest.GetFieldValue("AccessToTestInterface").StringValue  //Object reference not set to an instance of an object

            }

            catch (Exception ex)

            {
                Console.WriteLine($"{ex.Message}\n{ex.StackTrace}\n Inner Exception: {ex.InnerException}");

            }

        }
    }
}

The issue is occurring after upgrading from ServiceStack version 4.5.14 to version 6.9
The behavior was correct in version 4.5.14 Fields value was returing the properties but now in ServiceStack version 6.9 Fields property is returning null
The ‘Fields’ value in the response object’s ‘Results’ properties is null, leading to a Null Reference Exception.

We are seeking your guidance to understand if there are any changes or considerations in ServiceStack version 6.9 that could be causing this behavior. Are there any updates or modifications we need to make in our code to address this issue?Could you please help us out on this?

We wont be able to identify this issue from here, if you put a stand-alone repro on GitHub we can take a look.

I have created a simplified example to illustrate the problem below since to replicate the issue you will need our setup.

Issue with FieldDictionary Property in ServiceStack 6.9

In ServiceStack version 4.5.14, when we send a GET request , the FieldDictionary Property in the response contains the expected value.

However, after upgrading to ServiceStack version 6.9, the FieldDictionary property in the response is null. It is not returning the value when sending GET request.

Below is a code snippet

using ServiceStack;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

public class ExampleClass
{
      [DataMember]        
      [ApiMember(ExcludeInSchema=true, DataType = "object",  Verb = "NONE")]
      public FieldDictionary Fields { get; set; }
}

public class FieldDictionary
{
    public Dictionary<string, object> Data { get; set; }
}

class Program
{
    static void Main()
    {
        try
        {
            //sending a GET request
            ExampleClass response = SimulateGetRequest();

            // Attempt to access the 'Fields' property
            // This is where we encounter System.NullReferenceException “Object reference not set to an instance of an object.”
            FieldDictionary fields = response.Fields;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An unexpected error occurred: {ex.Message}");
        }
    }

    static ExampleClass SimulateGetRequest()
    {
        ExampleClass exampleResponse = new ExampleClass
        {
        };

        return exampleResponse;
    }
}

We seek your guidance in understanding if there are any changes or considerations in ServiceStack version 6.9 that could be causing this behavior.
Are there any updates or modifications we need to make in our code to address this issue?

This code doesn’t do anything, where’s the code I can run to repro the issue? I need something I can run and debug. Please put a stand-alone project on GitHub I can download and run to see the issue.

You can create a single template project that you can modify with your issue with the x dotnet tool and running:

$ x new empty Test

To reproduce the issue you will need our setup, so I’ve prepared a minimal example to illustrate the problem we are facing
The property we are facing issue with is of FieldDictiory datatype that is not returning the value when sending GET request in Servicestack version 6.9
In the response the Fields will be null , where as in ServiceStack version 4.5.14 we used to get the proper Fields count
Wanted to know why the Fields value is not getting mapped correctly in Servicestack version 6.9

Below is a minimal example, you can run this in your Visual Studio application with ServiceStack.Client , ServiceStack.Interfaces , ServiceStack.Text dlls added in the project
I would have attached the project here but i do not have permission to upload .zip files

using ServiceStack;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace MinimalReproducibleExample
{
    public class ExampleClass
    {
        [DataMember]
        [ApiMember(ExcludeInSchema = true, DataType = "object", Verb = "NONE")]
        public FieldDictionary Fields { get; set; }
    }

    [CollectionDataContract(Name = "EnumItemDetail", ItemName = "EnumItemDetail")]
    public class FieldDictionary : Dictionary<string, object>
    {
        private string someData;
        public string SomeData
        {
            get
            {
                if (someData == null)
                {
                    throw new NullReferenceException("");
                }
                return someData;
            }
            set { someData = value; }
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ExampleClass response = SimulateGetRequest();

                //response.Fields is null but we are expecting the proper count of Fields property
                FieldDictionary fields = response?.Fields;

            }
            catch (Exception ex)
            {
                Console.WriteLine($"An unexpected error occurred: {ex.Message}");
            }

            Console.ReadLine();
        }

        static ExampleClass SimulateGetRequest()
        {
            ExampleClass exampleResponse = new ExampleClass
            {

            };

            return exampleResponse;
        }

    }
}

To reproduce the issue you will need our setup,

This is the entire reason for a stand-alone repro, i.e. we need a reproducible example including any configuration that’s causing it. This still isn’t a valid repro, it uses no serialization, doesn’t test the implementation that’s at issue, doesn’t show what payload is causing it, etc, all it has is a comment saying a property is null, it at least it shows that you’re using an invalid type that would cause the issue. But in future we need a stand-alone reproduction we can run locally. How to create a Minimal, Reproducible Example explains why and what we’re looking for when needing to identify and resolve issues.

You can’t inherit dictionaries which will only serialize its key value pairs, change it to a type that contains a dictionary as done in your previous example. You should also add [DataContract] attribute on DTO classes that you use [DataMember] in.

In general you also want to avoid object properties since serializers have no idea what to deserialize back into that is often a source of runtime serilalization issues that’s restricted to avoid vulnerabilities and not supported by other Add ServiceStack Reference languages. If it only contains scalar value types consider using a Dictionary<string,string> instead.

Please also include any C# code in code fences so they’re rendered properly:

```csharp
// C# code
```

[DataContract] attribute on DTO classes that we use [DataMember] in is already added. To be specific our FieldDictionary looks like this below

public partial class FieldDictionary  : Dictionary<string, IProperty>
{
}
[CollectionDataContract(Name = "EnumItemDetail", ItemName = "EnumItemDetail")]

we cannot go in to test with general recommendation to use Dictionary<string, string>

Below is the method from HttpExtensions.cs On browsing the request properties here we have the vlaue present but while returning the response it is missing

public static async Task EndHttpHandlerRequestAsync(this IResponse httpRes, bool skipHeaders = false, bool skipClose = false, Func<IResponse,Task> afterHeaders = null)
{
    if (!skipHeaders) httpRes.ApplyGlobalResponseHeaders();

    if (afterHeaders != null)
    {
        try
        {
            await afterHeaders(httpRes).ConfigAwait();
        }
        catch (Exception e)
        {
            var log = LogManager.LogFactory.GetLogger(typeof(HttpExtensions));
            log.Error("Error executing async afterHeaders: " + e.Message, e);
        }
    }

    var req = httpRes.Request;
    if (req != null && !req.Items.ContainsKey(Keywords.HasLogged))
    {
        HostContext.TryResolve<IRequestLogger>()?.Log(req, req.Dto, httpRes.Dto, req.GetElapsed());
    }

    if (!skipClose && !httpRes.IsClosed)
    {
        await httpRes.CloseAsync().ConfigAwait();
    }

    HostContext.CompleteRequest(req);
}

You’re still trying to create custom types which inherit a dictionary which wont work, also definitely don’t use interfaces in DTOs. If you want your DTOs to be interoperable you should avoid object entirely, e.g. you can restructure your DTO to use concrete collections for the different data types you want to support:

public class Dto
{
    public Dictionary<string,string> StringDictionary { get; set; }
    public Dictionary<string,Poco> PocoDictionary { get; set; }
}

Please also wrap any C# code in code fence blocks so they’re formatted properly:

```csharp
// C#
```

But if you want us to have a look at an actual issue, we absolutely need a stand-alone repro on GitHub that we can download and run to see the actual issue, these inline code examples that don’t reproduce the issue aren’t useful.