JasperFx / alba

Easy integration testing for ASP.NET Core applications
https://jasperfx.github.io/alba
Apache License 2.0
405 stars 39 forks source link

Alba's built in JSON serialization isn't working for oData endpoints #116

Open jeremydmiller opened 2 years ago

jeremydmiller commented 2 years ago

More research necessary

ticky74 commented 1 year ago

Pretty new to Alba, however I have been using it successfully against OData endpoints with the AspVersioning library. I think there is a bit of a nuance, I'm using Asp.Versioning.OData@7.0.1. Although the OData requests go through controllers, the serialization aligns with the MinimalApiStrategy. In the AlbaHost constructors, the input/output formatters are of type ODataInputFormatter and ODataOutputFormatter, so the MvcStrategy is initialized.

var jsonInput  = findInputFormatter("application/json");
var jsonOutput = findOutputFormatter("application/json");

if (jsonInput != null && jsonOutput != null)
{
    MvcStrategy = new FormatterSerializer(this, jsonInput, jsonOutput);
}

MinimalApiStrategy = new SystemTextJsonSerializer(this);

DefaultJson = MvcStrategy ?? MinimalApiStrategy;

So the DefaultJson is then set to the MvcStrategy and I guess OData isn't a fan.

I have not really tested this against the library, I just grabbed the source and hacked in a couple overloaded constructors and For<>... methods and so far things have been working. Not sure if this helps anyone, or not, but I too had the pleasure of banging my head against the wall with the Asp.Versioning and OData libraries so thought I'd post just in case!

yulivee commented 12 months ago

@ticky74 Would you mind sharing your Hack? Struggeling with a similar Problem, using OData@7.18.0 as a transitive dependency of the ResTier Framework@1.1.0. When Posting Alba supports handing over the MinimalApiStrategy, so we can successfully post json - but when trying to use the ReadAsJson Methods, we get Deserialization Exceptions. Currently stuck testing with ReadAsText which is crude in comparison

vcaraulean commented 3 months ago

I've ran into same issue. Our project has a mix of OData and API controllers. Following snippet:

        await fixture.Host.Scenario(x =>
        {
            x.Post
                .Json(new { name = DocumentName, body })
                .ToUrl("/documents/wiki");

            x.StatusCodeShouldBeOk();
        });

Throws this error:

System.UriFormatException
Invalid URI: The format of the URI could not be determined.
   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions)
   at System.Uri..ctor(String uriString)
   at Microsoft.AspNetCore.OData.Formatter.ODataOutputFormatter.GetDefaultBaseAddress(HttpRequest request)
   at Microsoft.AspNetCore.OData.Formatter.ODataOutputFormatter.GetBaseAddressInternal(HttpRequest request)
   at Microsoft.AspNetCore.OData.Formatter.ODataOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Formatters.TextOutputFormatter.WriteAsync(OutputFormatterWriteContext context)
   at Alba.Serialization.FormatterSerializer.Write[T](T body) in /_/src/Alba/Serialization/FormatterSerializer.cs:line 34
   at Alba.Scenario.<>c__DisplayClass44_0`1.<WriteJson>b__0(HttpContext c) in /_/src/Alba/Scenario.cs:line 250
   at Alba.Scenario.SetupHttpContext(HttpContext context) in /_/src/Alba/Scenario.cs:line 346

A temporary workaround that seems to be working for us is to fall back to using HttpClient:

        using var httpClient = fixture.Host.GetTestServer().CreateClient();
        var response = await httpClient.PostAsync("/documents/wiki", 
                                                  JsonContent.Create(new { name = DocumentName, body }));
        response.EnsureSuccessStatusCode();

A proper fix might require some effort to pick up the right formatter depending on individual request...