Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. .NET Core 2.2 vs .NET Core 3.1

.NET Core 2.2 vs .NET Core 3.1

Scheduled Pinned Locked Moved The Lounge
csharpvisual-studioasp-netjsonquestion
5 Posts 5 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Marc Clifton
    wrote on last edited by
    #1

    This is NOT a programming question. Just something you might want to be aware of. So I migrated my project and fixed that various things in Startup that broke. Stupid things, like apparent env.IsDevelopment() doesn't exist anymore, and IHostingEnvironment has to be changed to IWebHostEnvironment or something like that, and app.UseMvc(); is wrong now and you have to use:

            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                // endpoints.MapRazorPages(); //Routes for pages
                endpoints.MapControllers(); //Routes for my API controllers
            });
    

    instead, and I don't have Razor pages anyways. And I do wish that the whole NuGet package manager / Visual Studio would figure out that when I change the target framework, yes, please go and get the appropriate packages for the new framework, and now I need to specifically install the System.Data.SqlClient framework? And we're no longer using Microsoft.AspNetCore.App but instead need Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.SqlServer? Sigh. Fine, relatively easy fixes, and all that was an aside, relatively easy to fix, but annoying. So, once I got it to compile, fired it up and tried a very simple API call that returns an access token. Now, in .NET Core 2.2, the response at the client contains the key "access_token" In .NET Core 3.1, the response at the client contains the key "token" As in:

    JSON.parse(xhr.response).access_token;

    has to be changed to:

    JSON.parse(xhr.response).token;

    WTF? On the C# side, the return from the API call is the same:

    ActionResult(resp.token)

    where IAccessToken is quite literally just:

    public interface IAccessToken
    {
        string Token { get; set; }
    }
    

    Now here's where it gets interesting. resp is actually a tuple: (IAccessToken token, HttpStatusCode status) and I'm returning the token part of the tuple resp.token (checking the status is not necessary because if the status isn't "OK", then the token is null so the full line is actually:

    ret = resp.token.Token == null ? Unauthorized() : new ActionResult(resp.token);

    but that's irrelevant to this discussion. The point being, .NET Core 2.2 serializes the container IAccessToken differently than .NET Core 3.1. Good grief. I would

    H L M Richard DeemingR 4 Replies Last reply
    0
    • M Marc Clifton

      This is NOT a programming question. Just something you might want to be aware of. So I migrated my project and fixed that various things in Startup that broke. Stupid things, like apparent env.IsDevelopment() doesn't exist anymore, and IHostingEnvironment has to be changed to IWebHostEnvironment or something like that, and app.UseMvc(); is wrong now and you have to use:

              app.UseRouting();
              app.UseEndpoints(endpoints =>
              {
                  // endpoints.MapRazorPages(); //Routes for pages
                  endpoints.MapControllers(); //Routes for my API controllers
              });
      

      instead, and I don't have Razor pages anyways. And I do wish that the whole NuGet package manager / Visual Studio would figure out that when I change the target framework, yes, please go and get the appropriate packages for the new framework, and now I need to specifically install the System.Data.SqlClient framework? And we're no longer using Microsoft.AspNetCore.App but instead need Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.SqlServer? Sigh. Fine, relatively easy fixes, and all that was an aside, relatively easy to fix, but annoying. So, once I got it to compile, fired it up and tried a very simple API call that returns an access token. Now, in .NET Core 2.2, the response at the client contains the key "access_token" In .NET Core 3.1, the response at the client contains the key "token" As in:

      JSON.parse(xhr.response).access_token;

      has to be changed to:

      JSON.parse(xhr.response).token;

      WTF? On the C# side, the return from the API call is the same:

      ActionResult(resp.token)

      where IAccessToken is quite literally just:

      public interface IAccessToken
      {
          string Token { get; set; }
      }
      

      Now here's where it gets interesting. resp is actually a tuple: (IAccessToken token, HttpStatusCode status) and I'm returning the token part of the tuple resp.token (checking the status is not necessary because if the status isn't "OK", then the token is null so the full line is actually:

      ret = resp.token.Token == null ? Unauthorized() : new ActionResult(resp.token);

      but that's irrelevant to this discussion. The point being, .NET Core 2.2 serializes the container IAccessToken differently than .NET Core 3.1. Good grief. I would

      H Offline
      H Offline
      honey the codewitch
      wrote on last edited by
      #2

      Marc Clifton wrote:

      Don't trust .NET Core. Don't trust open source projects.

      Don't trust FTFY :-D

      Real programmers use butterflies

      1 Reply Last reply
      0
      • M Marc Clifton

        This is NOT a programming question. Just something you might want to be aware of. So I migrated my project and fixed that various things in Startup that broke. Stupid things, like apparent env.IsDevelopment() doesn't exist anymore, and IHostingEnvironment has to be changed to IWebHostEnvironment or something like that, and app.UseMvc(); is wrong now and you have to use:

                app.UseRouting();
                app.UseEndpoints(endpoints =>
                {
                    // endpoints.MapRazorPages(); //Routes for pages
                    endpoints.MapControllers(); //Routes for my API controllers
                });
        

        instead, and I don't have Razor pages anyways. And I do wish that the whole NuGet package manager / Visual Studio would figure out that when I change the target framework, yes, please go and get the appropriate packages for the new framework, and now I need to specifically install the System.Data.SqlClient framework? And we're no longer using Microsoft.AspNetCore.App but instead need Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.SqlServer? Sigh. Fine, relatively easy fixes, and all that was an aside, relatively easy to fix, but annoying. So, once I got it to compile, fired it up and tried a very simple API call that returns an access token. Now, in .NET Core 2.2, the response at the client contains the key "access_token" In .NET Core 3.1, the response at the client contains the key "token" As in:

        JSON.parse(xhr.response).access_token;

        has to be changed to:

        JSON.parse(xhr.response).token;

        WTF? On the C# side, the return from the API call is the same:

        ActionResult(resp.token)

        where IAccessToken is quite literally just:

        public interface IAccessToken
        {
            string Token { get; set; }
        }
        

        Now here's where it gets interesting. resp is actually a tuple: (IAccessToken token, HttpStatusCode status) and I'm returning the token part of the tuple resp.token (checking the status is not necessary because if the status isn't "OK", then the token is null so the full line is actually:

        ret = resp.token.Token == null ? Unauthorized() : new ActionResult(resp.token);

        but that's irrelevant to this discussion. The point being, .NET Core 2.2 serializes the container IAccessToken differently than .NET Core 3.1. Good grief. I would

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        Sounds like they did it on purpose because they couldn't support the old api going from 2.x to 3.x. Force you to update your code if you update your libs. The one I remember (between "libs") was in one case you can use a single char for a string split separator, while the other version will (still) insist on an array. You think it's neat and change your code, then find your lib is no longer compatible with your other libs. I also ran into problems thinking all libs should serialize / compress the same ... not. They may actually read and write but the file sizes will be off.

        It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

        1 Reply Last reply
        0
        • M Marc Clifton

          This is NOT a programming question. Just something you might want to be aware of. So I migrated my project and fixed that various things in Startup that broke. Stupid things, like apparent env.IsDevelopment() doesn't exist anymore, and IHostingEnvironment has to be changed to IWebHostEnvironment or something like that, and app.UseMvc(); is wrong now and you have to use:

                  app.UseRouting();
                  app.UseEndpoints(endpoints =>
                  {
                      // endpoints.MapRazorPages(); //Routes for pages
                      endpoints.MapControllers(); //Routes for my API controllers
                  });
          

          instead, and I don't have Razor pages anyways. And I do wish that the whole NuGet package manager / Visual Studio would figure out that when I change the target framework, yes, please go and get the appropriate packages for the new framework, and now I need to specifically install the System.Data.SqlClient framework? And we're no longer using Microsoft.AspNetCore.App but instead need Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.SqlServer? Sigh. Fine, relatively easy fixes, and all that was an aside, relatively easy to fix, but annoying. So, once I got it to compile, fired it up and tried a very simple API call that returns an access token. Now, in .NET Core 2.2, the response at the client contains the key "access_token" In .NET Core 3.1, the response at the client contains the key "token" As in:

          JSON.parse(xhr.response).access_token;

          has to be changed to:

          JSON.parse(xhr.response).token;

          WTF? On the C# side, the return from the API call is the same:

          ActionResult(resp.token)

          where IAccessToken is quite literally just:

          public interface IAccessToken
          {
              string Token { get; set; }
          }
          

          Now here's where it gets interesting. resp is actually a tuple: (IAccessToken token, HttpStatusCode status) and I'm returning the token part of the tuple resp.token (checking the status is not necessary because if the status isn't "OK", then the token is null so the full line is actually:

          ret = resp.token.Token == null ? Unauthorized() : new ActionResult(resp.token);

          but that's irrelevant to this discussion. The point being, .NET Core 2.2 serializes the container IAccessToken differently than .NET Core 3.1. Good grief. I would

          M Offline
          M Offline
          mmcdaniel
          wrote on last edited by
          #4

          Most of the serialization issues are from them switching from Newtonsoft to System.Text.Json. Beware if you have your own custom converters or attributes to change the serialized property names!

          1 Reply Last reply
          0
          • M Marc Clifton

            This is NOT a programming question. Just something you might want to be aware of. So I migrated my project and fixed that various things in Startup that broke. Stupid things, like apparent env.IsDevelopment() doesn't exist anymore, and IHostingEnvironment has to be changed to IWebHostEnvironment or something like that, and app.UseMvc(); is wrong now and you have to use:

                    app.UseRouting();
                    app.UseEndpoints(endpoints =>
                    {
                        // endpoints.MapRazorPages(); //Routes for pages
                        endpoints.MapControllers(); //Routes for my API controllers
                    });
            

            instead, and I don't have Razor pages anyways. And I do wish that the whole NuGet package manager / Visual Studio would figure out that when I change the target framework, yes, please go and get the appropriate packages for the new framework, and now I need to specifically install the System.Data.SqlClient framework? And we're no longer using Microsoft.AspNetCore.App but instead need Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.SqlServer? Sigh. Fine, relatively easy fixes, and all that was an aside, relatively easy to fix, but annoying. So, once I got it to compile, fired it up and tried a very simple API call that returns an access token. Now, in .NET Core 2.2, the response at the client contains the key "access_token" In .NET Core 3.1, the response at the client contains the key "token" As in:

            JSON.parse(xhr.response).access_token;

            has to be changed to:

            JSON.parse(xhr.response).token;

            WTF? On the C# side, the return from the API call is the same:

            ActionResult(resp.token)

            where IAccessToken is quite literally just:

            public interface IAccessToken
            {
                string Token { get; set; }
            }
            

            Now here's where it gets interesting. resp is actually a tuple: (IAccessToken token, HttpStatusCode status) and I'm returning the token part of the tuple resp.token (checking the status is not necessary because if the status isn't "OK", then the token is null so the full line is actually:

            ret = resp.token.Token == null ? Unauthorized() : new ActionResult(resp.token);

            but that's irrelevant to this discussion. The point being, .NET Core 2.2 serializes the container IAccessToken differently than .NET Core 3.1. Good grief. I would

            Richard DeemingR Offline
            Richard DeemingR Offline
            Richard Deeming
            wrote on last edited by
            #5

            I can't see how any version of Entity Framework would be able to translate a query using your computed property to a SQL query. It's quite likely that EF Core 2.x was loading the entire table into memory and evaluating the condition as a LINQ-to-objects query instead. One of the breaking changes in 3.x is that it won't do that any more.

            Breaking changes in EF Core 3.0 - EF Core | Microsoft Docs[^]

            Old behavior Before 3.0, when EF Core couldn't convert an expression that was part of a query to either SQL or a parameter, it automatically evaluated the expression on the client. By default, client evaluation of potentially expensive expressions only triggered a warning. New behavior Starting with 3.0, EF Core only allows expressions in the top-level projection (the last Select() call in the query) to be evaluated on the client. When expressions in any other part of the query can't be converted to either SQL or a parameter, an exception is thrown.

            There are a couple of ways around this. You could make the property a computed column[^]:

            modelBuilder.Entity<Client>()
            .Property(acct => acct.IsDeleted)
            .HasComputedColumnSql("CAST(IsNull(Deleted, 0) As bit)");

            Or use you use a value converter[^] on the property:

            modelBuilder.Entity<Client>()
            .Property(acct => acct.IsDeleted)
            .HasColumnName("Deleted")
            .HasConversion(new BoolToZeroOneConverter<int>());

            in which case, you'd want to remove the Deleted property, and possibly make IsDeleted writable. Either option should allow your original query to be evaluated in the database

            "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups