6

I know this is duplicate of some past questions.But there were no real solution.

One of the related links

Another one

I am working with .Net Core 3 Multipage Template. I've tried everything like given below. But no use.

This is my interface from application project:

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using TSE.Kalibrasyon.Roles.Dto;
using TSE.Kalibrasyon.Users.Dto;

namespace TSE.Kalibrasyon.Labs
{
    public interface ILabAppService : IApplicationService
    {
        string Test();
        Task<List<Entities.Labs.Labs>> GetAllAsync();
        System.Threading.Tasks.Task Update(Entities.Labs.Labs input);
        System.Threading.Tasks.Task Create(Entities.Labs.Labs input);
    }
}

and the implementation is:

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Entities;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.IdentityFramework;
using Abp.Linq.Extensions;
using Abp.Localization;
using Abp.Runtime.Session;
using Abp.UI;
using TSE.Kalibrasyon.Authorization;
using TSE.Kalibrasyon.Authorization.Accounts;
using TSE.Kalibrasyon.Authorization.Roles;
using TSE.Kalibrasyon.Authorization.Users;
using TSE.Kalibrasyon.Roles.Dto;
using TSE.Kalibrasyon.Users.Dto;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using TSE.Kalibrasyon.Entities.Labs.Dto;
using TSE.Kalibrasyon.Entities.Labs;
using TSE.Kalibrasyon.Labs.Dto;
using Abp.Web.Models;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;

namespace TSE.Kalibrasyon.Labs
{
    //[AbpAuthorize(PermissionNames.Pages_Users)]
    public class LabAppService : KalibrasyonAppServiceBase, ILabAppService
    {
        private readonly IRepository<Entities.Labs.Labs> _labRepository;


        public LabAppService(IRepository<Entities.Labs.Labs> labRepository)
        {
            _labRepository = labRepository;
        }
        [Microsoft.AspNetCore.Mvc.HttpGet]
        public string Test()
        {
            return "merhaba";
        }
        [DontWrapResult]
        public  async Task<List<Entities.Labs.Labs>> GetAllAsync()
        {
            //var chk = await _labRepository.GetAllListAsync();
            return await _labRepository.GetAllListAsync();
        }

        [DontWrapResult]
        //public  List<Entities.Labs.Labs> GetAll2()
        public  object GetAll2()
        {
            List<Entities.Labs.Labs> chk = _labRepository.GetAllListAsync().Result;
            //return _labRepository.GetAllListAsync().Result;
            var bak= new { Items = chk, Count = chk.Count() };
            return new { Items = chk, Count = chk.Count() };
            //return Json(new { Items = chk, Count = chk.Count() }, new JsonSerializerSettings { ContractResolver = new PascalCasePropertyNamesContractResolver() });
        }

        [DontWrapResult]
        public string GetAll3()
        {
            List<Entities.Labs.Labs> chk = _labRepository.GetAllListAsync().Result;
            var obj= new { Items = chk, Count = chk.Count() };
            //return Json(new { Items = chk, Count = chk.Count() }, new JsonSerializerSettings { ContractResolver = new PascalCasePropertyNamesContractResolver() });
            var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
            //var text = JsonConvert.SerializeObject(configuration, settings);
            var text = JsonConvert.SerializeObject(obj);
            return text;
            //return Json(new { Items = chk, Count = chk.Count() });

        }

        public async Task Update(Entities.Labs.Labs input)
        {
            await _labRepository.UpdateAsync(input);
        }
        public async Task Create(Entities.Labs.Labs input)
        {
            await _labRepository.InsertAsync(input);
        }
    }


    //public class Data
    //{
    //    public bool requiresCounts { get; set; }
    //    public int skip { get; set; }
    //    public int take { get; set; }
    //}
}

and the response body is:

[
  {
    "labName": "BASINÇ KALİBRASYON LABORATUVARI",
    "labKod": "BAS",
    "bolgeKodu": 5,
    "id": 1
  }
]

My model for this entity is :

using Abp.Domain.Entities;
using Abp.Domain.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;

namespace TSE.Kalibrasyon.Entities.Labs
{
    [Table("Labs")]
    public partial class Labs : Entity
    {
        private readonly IRepository<Labs> _lablarRepository;
        //private readonly TownAppService _townAppService;
        //private readonly IRepository<Town> _townRepository;
        public Labs()
        {
            //this.Towns = new List<Town>();
            //this.Districts = new List<District>();
            //this.Neighborhoods = new List<Neighborhood>();
            OnCreated();
        }

        //[System.ComponentModel.DataAnnotations.Key]
        //[System.ComponentModel.DataAnnotations.Required()]
        //public virtual int Id
        //{
        //    get;
        //    set;
        //}

        [System.ComponentModel.DataAnnotations.Required()]
        public virtual string LabName
        {
            get;
            set;
        }

        [System.ComponentModel.DataAnnotations.StringLength(3)]
        [System.ComponentModel.DataAnnotations.Required()]
        public virtual string LabKod
        {
            get;
            set;
        }

        [System.ComponentModel.DataAnnotations.Required()]
        public virtual int BolgeKodu
        {
            get;
            set;
        }





        #region Extensibility Method Definitions

        partial void OnCreated();

        #endregion
    }
}

And there is an another big problem also, I am using Syncfusion .Net Core Grid as a third party tool. It requires a method for database operations as given below.

[IgnoreAntiforgeryToken]
        public IActionResult UrlDatasource([FromBody]DataManagerRequest dm)
        {
            Api api=new Api();

            //IEnumerable DataSource = Orders.GetAllRecords();
            IEnumerable DataSource = api.LabsGetAll();
            DataOperations operation = new DataOperations();


            if (dm.Search != null && dm.Search.Count > 0)
            {
                DataSource = operation.PerformSearching(DataSource, dm.Search);  //Search
            }
            if (dm.Sorted != null && dm.Sorted.Count > 0) //Sorting
            {
                DataSource = operation.PerformSorting(DataSource, dm.Sorted);
            }
            if (dm.Where != null && dm.Where.Count > 0) //Filtering
            {
                DataSource = operation.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator);



            }
            int count = DataSource.Cast<Entities.Labs.Labs>().Count();
            if (dm.Skip != 0)
            {
                DataSource = operation.PerformSkip(DataSource, dm.Skip);         //Paging
            }
            if (dm.Take != 0)
            {
                DataSource = operation.PerformTake(DataSource, dm.Take);
            }
            return dm.RequiresCounts ? Json(new { result = DataSource, count = count }) : Json(DataSource);
        }

When I don't use the [IgnoreAntiforgeryToken] for the method. It doesn't hit the method with the HTTP ERROR 415.

Syncfusion says that, it is just because of camel casing and offers adding the

services.PostConfigure<MvcJsonOptions>(options =>
{
    options.SerializerSettings.ContractResolver = new DefaultContractResolver();
}); 

into ConfigureServices method of StartUp file. But I think it works only with the .net core 2.x. It was not a solution for me with ABP working on .net core 3.0

My StartUp.cs in Host App is:

using System;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Castle.Facilities.Logging;
using Abp.AspNetCore;
using Abp.AspNetCore.Mvc.Antiforgery;
using Abp.Castle.Logging.Log4Net;
using Abp.Extensions;
using TSE.Kalibrasyon.Configuration;
using TSE.Kalibrasyon.Identity;
using Abp.AspNetCore.SignalR.Hubs;
using Abp.Dependency;
using Abp.Json;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.Mvc;

namespace TSE.Kalibrasyon.Web.Host.Startup
{
    public class Startup
    {
        private const string _defaultCorsPolicyName = "localhost";

        private readonly IConfigurationRoot _appConfiguration;

        public Startup(IWebHostEnvironment env)
        {
            _appConfiguration = env.GetAppConfiguration();
        }

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            //MVC
            services.AddControllersWithViews(
                options =>
                {
                    options.Filters.Add(new AbpAutoValidateAntiforgeryTokenAttribute());
                }
            ).AddNewtonsoftJson(options =>
            {
                //options.SerializerSettings.ContractResolver = new AbpMvcContractResolver(IocManager.Instance)
                //{
                //    NamingStrategy = new CamelCaseNamingStrategy()
                //};
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
            });


            services.PostConfigure<MvcNewtonsoftJsonOptions>(options =>
            {
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
            });



            IdentityRegistrar.Register(services);
            AuthConfigurer.Configure(services, _appConfiguration);

            services.AddSignalR();

            // Configure CORS for angular2 UI
            services.AddCors(
                options => options.AddPolicy(
                    _defaultCorsPolicyName,
                    builder => builder
                        .WithOrigins(
                            // App:CorsOrigins in appsettings.json can contain more than one address separated by comma.
                            _appConfiguration["App:CorsOrigins"]
                                .Split(",", StringSplitOptions.RemoveEmptyEntries)
                                .Select(o => o.RemovePostFix("/"))
                                .ToArray()
                        )
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials()
                )
            );

            // Swagger - Enable this line and the related lines in Configure method to enable swagger UI
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo() { Title = "Kalibrasyon API", Version = "v1" });
                options.DocInclusionPredicate((docName, description) => true);

                // Define the BearerAuth scheme that's in use
                options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
                {
                    Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey
                });
            });

            // Configure Abp and Dependency Injection
            return services.AddAbp<KalibrasyonWebHostModule>(
                // Configure Log4Net logging
                options => options.IocManager.IocContainer.AddFacility<LoggingFacility>(
                    f => f.UseAbpLog4Net().WithConfig("log4net.config")
                )
            );
        }

        public void Configure(IApplicationBuilder app,  ILoggerFactory loggerFactory)
        {
            app.UseAbp(options => { options.UseAbpRequestLocalization = false; }); // Initializes ABP framework.

            app.UseCors(_defaultCorsPolicyName); // Enable CORS!

            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();

            app.UseAbpRequestLocalization();


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<AbpCommonHub>("/signalr");
                endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapControllerRoute("defaultWithArea", "{area}/{controller=Home}/{action=Index}/{id?}");
            });

            // Enable middleware to serve generated Swagger as a JSON endpoint
            app.UseSwagger();
            // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint(_appConfiguration["App:ServerRootAddress"].EnsureEndsWith('/') + "swagger/v1/swagger.json", "Kalibrasyon API V1");
                options.IndexStream = () => Assembly.GetExecutingAssembly()
                    .GetManifestResourceStream("TSE.Kalibrasyon.Web.Host.wwwroot.swagger.ui.index.html");
            }); // URL: /swagger
        }
    }
}

Is there any solution that you might know? Thanks in advance.

and also, Controlling serialization of property names with JsonResult. But no use.Any idea please?

Inanc Akcan
  • 115
  • 1
  • 1
  • 8
  • Please read [ask] and show us how you determine "no result". Show how you generate the response and how you obtain the output. – CodeCaster Jan 02 '20 at 07:11
  • @CodeCaster Ok. I've updated my question. It is always a tedious task asking here. There is a problem of mine. And there are always members of doctoral jury. It was just a question that was telling what was intented with my limited english. That is all .. – Inanc Akcan Jan 02 '20 at 07:23
  • _"It is always a tedious task asking here"_ - just remember that we can't look on your screen nor into your head. You have to explain all the relevant parts. Your question still doesn't show your code or your output. – CodeCaster Jan 02 '20 at 07:33
  • @CodeCaster I've started to feel that, you realy want to help me with that problem. Thank you for your interest. I've updated my question once again. Thanks in advance – Inanc Akcan Jan 02 '20 at 08:02
  • @CodeCaster Dear Sir, I think you are agree with me right now? There is no solution? I was hopeful – Inanc Akcan Jan 02 '20 at 14:37
  • 1
    Of course there's a way, but you've shown way too much code. See for example https://stackoverflow.com/a/58135043/266143. – CodeCaster Jan 02 '20 at 14:40
  • @CodeCaster Great! Thank you very much. Not the example that you've given but in the same thread https://stackoverflow.com/a/59032665/9305367 did the trick. – Inanc Akcan Jan 03 '20 at 07:53

3 Answers3

6

In .NET Core 3.x, you now need to modify JsonSerializerOptions.PropertyNamingPolicy.

For PascalCase — following your original property name — set to null:

services.AddMvc(...)
    .AddJsonOptions(jsonOptions =>
    {
        jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;
    });

For lowercase (or another custom naming policy), subclass JsonNamingPolicy and override the ConvertName method.

services.AddMvc(...)
    .AddJsonOptions(jsonOptions =>
    {
        jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = new JsonLowercaseNamingPolicy();
    });
public class JsonLowercaseNamingPolicy : JsonNamingPolicy
{
    public override string ConvertName(string name) => name.ToLowerInvariant();
}

Reference: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?view=netcore-3.1#use-a-custom-json-property-naming-policy

aaron
  • 39,695
  • 6
  • 46
  • 102
  • This is assuming that the user is using the new .net json serializer. I'm having a hard time coming up with a way to do this in Newtonsoft. – Robert Smith Apr 30 '20 at 14:22
  • 4
    @RobertSmith on .net6.0, in Startup.cs I had to add this `services.AddControllers().AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver(); })` for PascalCase – ManiVI Aug 10 '22 at 15:03
4

In .NET 6.0, I managed to fix the same issue, just add this code inside Program.cs (ofc, with Newtonsoft package previously installed.):

builder.Services.AddControllers().AddJsonOptions(options => 
options.JsonSerializerOptions.PropertyNamingPolicy = null);
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
1

For newtonsoft this is the implementation.

.AddControllersWithViews()
.AddNewtonsoftJson(options =>
{
    options.SerializerSettings.ContractResolver = null;
}
);

Hope it helps.