将 JSON 序列化从 CamelCase 更改为 PascalCase [重复 - 无解决方案?]

Ina*_*can 6 aspnetboilerplate

我知道这与过去的一些问题重复。但没有真正的解决方案。

\n\n

相关链接之一

\n\n

另一个

\n\n

我正在使用 .Net Core 3 多页模板。\n我已经尝试了如下所示的所有操作。但没有用。

\n\n

这是我的应用程序项目的界面:

\n\n
using System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Abp.Application.Services;\nusing Abp.Application.Services.Dto;\nusing TSE.Kalibrasyon.Roles.Dto;\nusing TSE.Kalibrasyon.Users.Dto;\n\nnamespace TSE.Kalibrasyon.Labs\n{\n    public interface ILabAppService : IApplicationService\n    {\n        string Test();\n        Task<List<Entities.Labs.Labs>> GetAllAsync();\n        System.Threading.Tasks.Task Update(Entities.Labs.Labs input);\n        System.Threading.Tasks.Task Create(Entities.Labs.Labs input);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

其实现是:

\n\n
using System.Collections.Generic;\nusing System.Linq;\nusing System.Text.RegularExpressions;\nusing System.Threading.Tasks;\nusing Abp.Application.Services;\nusing Abp.Application.Services.Dto;\nusing Abp.Authorization;\nusing Abp.Domain.Entities;\nusing Abp.Domain.Repositories;\nusing Abp.Extensions;\nusing Abp.IdentityFramework;\nusing Abp.Linq.Extensions;\nusing Abp.Localization;\nusing Abp.Runtime.Session;\nusing Abp.UI;\nusing TSE.Kalibrasyon.Authorization;\nusing TSE.Kalibrasyon.Authorization.Accounts;\nusing TSE.Kalibrasyon.Authorization.Roles;\nusing TSE.Kalibrasyon.Authorization.Users;\nusing TSE.Kalibrasyon.Roles.Dto;\nusing TSE.Kalibrasyon.Users.Dto;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.EntityFrameworkCore;\nusing TSE.Kalibrasyon.Entities.Labs.Dto;\nusing TSE.Kalibrasyon.Entities.Labs;\nusing TSE.Kalibrasyon.Labs.Dto;\nusing Abp.Web.Models;\nusing Newtonsoft.Json;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace TSE.Kalibrasyon.Labs\n{\n    //[AbpAuthorize(PermissionNames.Pages_Users)]\n    public class LabAppService : KalibrasyonAppServiceBase, ILabAppService\n    {\n        private readonly IRepository<Entities.Labs.Labs> _labRepository;\n\n\n        public LabAppService(IRepository<Entities.Labs.Labs> labRepository)\n        {\n            _labRepository = labRepository;\n        }\n        [Microsoft.AspNetCore.Mvc.HttpGet]\n        public string Test()\n        {\n            return "merhaba";\n        }\n        [DontWrapResult]\n        public  async Task<List<Entities.Labs.Labs>> GetAllAsync()\n        {\n            //var chk = await _labRepository.GetAllListAsync();\n            return await _labRepository.GetAllListAsync();\n        }\n\n        [DontWrapResult]\n        //public  List<Entities.Labs.Labs> GetAll2()\n        public  object GetAll2()\n        {\n            List<Entities.Labs.Labs> chk = _labRepository.GetAllListAsync().Result;\n            //return _labRepository.GetAllListAsync().Result;\n            var bak= new { Items = chk, Count = chk.Count() };\n            return new { Items = chk, Count = chk.Count() };\n            //return Json(new { Items = chk, Count = chk.Count() }, new JsonSerializerSettings { ContractResolver = new PascalCasePropertyNamesContractResolver() });\n        }\n\n        [DontWrapResult]\n        public string GetAll3()\n        {\n            List<Entities.Labs.Labs> chk = _labRepository.GetAllListAsync().Result;\n            var obj= new { Items = chk, Count = chk.Count() };\n            //return Json(new { Items = chk, Count = chk.Count() }, new JsonSerializerSettings { ContractResolver = new PascalCasePropertyNamesContractResolver() });\n            var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };\n            //var text = JsonConvert.SerializeObject(configuration, settings);\n            var text = JsonConvert.SerializeObject(obj);\n            return text;\n            //return Json(new { Items = chk, Count = chk.Count() });\n\n        }\n\n        public async Task Update(Entities.Labs.Labs input)\n        {\n            await _labRepository.UpdateAsync(input);\n        }\n        public async Task Create(Entities.Labs.Labs input)\n        {\n            await _labRepository.InsertAsync(input);\n        }\n    }\n\n\n    //public class Data\n    //{\n    //    public bool requiresCounts { get; set; }\n    //    public int skip { get; set; }\n    //    public int take { get; set; }\n    //}\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

响应正文为:

\n\n
[\n  {\n    "labName": "BASIN\xc3\x87 KAL\xc4\xb0BRASYON LABORATUVARI",\n    "labKod": "BAS",\n    "bolgeKodu": 5,\n    "id": 1\n  }\n]\n
Run Code Online (Sandbox Code Playgroud)\n\n

我对该实体的模型是:

\n\n
using Abp.Domain.Entities;\nusing Abp.Domain.Repositories;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations.Schema;\nusing System.Text;\n\nnamespace TSE.Kalibrasyon.Entities.Labs\n{\n    [Table("Labs")]\n    public partial class Labs : Entity\n    {\n        private readonly IRepository<Labs> _lablarRepository;\n        //private readonly TownAppService _townAppService;\n        //private readonly IRepository<Town> _townRepository;\n        public Labs()\n        {\n            //this.Towns = new List<Town>();\n            //this.Districts = new List<District>();\n            //this.Neighborhoods = new List<Neighborhood>();\n            OnCreated();\n        }\n\n        //[System.ComponentModel.DataAnnotations.Key]\n        //[System.ComponentModel.DataAnnotations.Required()]\n        //public virtual int Id\n        //{\n        //    get;\n        //    set;\n        //}\n\n        [System.ComponentModel.DataAnnotations.Required()]\n        public virtual string LabName\n        {\n            get;\n            set;\n        }\n\n        [System.ComponentModel.DataAnnotations.StringLength(3)]\n        [System.ComponentModel.DataAnnotations.Required()]\n        public virtual string LabKod\n        {\n            get;\n            set;\n        }\n\n        [System.ComponentModel.DataAnnotations.Required()]\n        public virtual int BolgeKodu\n        {\n            get;\n            set;\n        }\n\n\n\n\n\n        #region Extensibility Method Definitions\n\n        partial void OnCreated();\n\n        #endregion\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

还有另一个大问题,我使用 Syncfusion .Net Core Grid 作为第三方工具。它需要一种数据库操作方法,如下所示。

\n\n
[IgnoreAntiforgeryToken]\n        public IActionResult UrlDatasource([FromBody]DataManagerRequest dm)\n        {\n            Api api=new Api();\n\n            //IEnumerable DataSource = Orders.GetAllRecords();\n            IEnumerable DataSource = api.LabsGetAll();\n            DataOperations operation = new DataOperations();\n\n\n            if (dm.Search != null && dm.Search.Count > 0)\n            {\n                DataSource = operation.PerformSearching(DataSource, dm.Search);  //Search\n            }\n            if (dm.Sorted != null && dm.Sorted.Count > 0) //Sorting\n            {\n                DataSource = operation.PerformSorting(DataSource, dm.Sorted);\n            }\n            if (dm.Where != null && dm.Where.Count > 0) //Filtering\n            {\n                DataSource = operation.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator);\n\n\n\n            }\n            int count = DataSource.Cast<Entities.Labs.Labs>().Count();\n            if (dm.Skip != 0)\n            {\n                DataSource = operation.PerformSkip(DataSource, dm.Skip);         //Paging\n            }\n            if (dm.Take != 0)\n            {\n                DataSource = operation.PerformTake(DataSource, dm.Take);\n            }\n            return dm.RequiresCounts ? Json(new { result = DataSource, count = count }) : Json(DataSource);\n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我不使用 [IgnoreAntiforgeryToken] 的方法时。它不会命中带有 HTTP ERROR 415 的方法。

\n\n

Syncfusion 表示,这只是因为骆驼外壳并提供添加

\n\n
services.PostConfigure<MvcJsonOptions>(options =>\n{\n    options.SerializerSettings.ContractResolver = new DefaultContractResolver();\n}); \n
Run Code Online (Sandbox Code Playgroud)\n\n

进入StartUp文件的ConfigureServices方法。但我认为它仅适用于 .net core 2.x。对于我来说,这不是一个在 .net core 3.0 上工作的 ABP 的解决方案

\n\n

我在主机应用程序中的 StartUp.cs 是:

\n\n
using System;\nusing System.Linq;\nusing System.Reflection;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Logging;\nusing Castle.Facilities.Logging;\nusing Abp.AspNetCore;\nusing Abp.AspNetCore.Mvc.Antiforgery;\nusing Abp.Castle.Logging.Log4Net;\nusing Abp.Extensions;\nusing TSE.Kalibrasyon.Configuration;\nusing TSE.Kalibrasyon.Identity;\nusing Abp.AspNetCore.SignalR.Hubs;\nusing Abp.Dependency;\nusing Abp.Json;\nusing Microsoft.OpenApi.Models;\nusing Newtonsoft.Json.Serialization;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace TSE.Kalibrasyon.Web.Host.Startup\n{\n    public class Startup\n    {\n        private const string _defaultCorsPolicyName = "localhost";\n\n        private readonly IConfigurationRoot _appConfiguration;\n\n        public Startup(IWebHostEnvironment env)\n        {\n            _appConfiguration = env.GetAppConfiguration();\n        }\n\n        public IServiceProvider ConfigureServices(IServiceCollection services)\n        {\n            //MVC\n            services.AddControllersWithViews(\n                options =>\n                {\n                    options.Filters.Add(new AbpAutoValidateAntiforgeryTokenAttribute());\n                }\n            ).AddNewtonsoftJson(options =>\n            {\n                //options.SerializerSettings.ContractResolver = new AbpMvcContractResolver(IocManager.Instance)\n                //{\n                //    NamingStrategy = new CamelCaseNamingStrategy()\n                //};\n                options.SerializerSettings.ContractResolver = new DefaultContractResolver();\n            });\n\n\n            services.PostConfigure<MvcNewtonsoftJsonOptions>(options =>\n            {\n                options.SerializerSettings.ContractResolver = new DefaultContractResolver();\n            });\n\n\n\n            IdentityRegistrar.Register(services);\n            AuthConfigurer.Configure(services, _appConfiguration);\n\n            services.AddSignalR();\n\n            // Configure CORS for angular2 UI\n            services.AddCors(\n                options => options.AddPolicy(\n                    _defaultCorsPolicyName,\n                    builder => builder\n                        .WithOrigins(\n                            // App:CorsOrigins in appsettings.json can contain more than one address separated by comma.\n                            _appConfiguration["App:CorsOrigins"]\n                                .Split(",", StringSplitOptions.RemoveEmptyEntries)\n                                .Select(o => o.RemovePostFix("/"))\n                                .ToArray()\n                        )\n                        .AllowAnyHeader()\n                        .AllowAnyMethod()\n                        .AllowCredentials()\n                )\n            );\n\n            // Swagger - Enable this line and the related lines in Configure method to enable swagger UI\n            services.AddSwaggerGen(options =>\n            {\n                options.SwaggerDoc("v1", new OpenApiInfo() { Title = "Kalibrasyon API", Version = "v1" });\n                options.DocInclusionPredicate((docName, description) => true);\n\n                // Define the BearerAuth scheme that\'s in use\n                options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()\n                {\n                    Description = "JWT Authorization header using the Bearer scheme. Example: \\"Authorization: Bearer {token}\\"",\n                    Name = "Authorization",\n                    In = ParameterLocation.Header,\n                    Type = SecuritySchemeType.ApiKey\n                });\n            });\n\n            // Configure Abp and Dependency Injection\n            return services.AddAbp<KalibrasyonWebHostModule>(\n                // Configure Log4Net logging\n                options => options.IocManager.IocContainer.AddFacility<LoggingFacility>(\n                    f => f.UseAbpLog4Net().WithConfig("log4net.config")\n                )\n            );\n        }\n\n        public void Configure(IApplicationBuilder app,  ILoggerFactory loggerFactory)\n        {\n            app.UseAbp(options => { options.UseAbpRequestLocalization = false; }); // Initializes ABP framework.\n\n            app.UseCors(_defaultCorsPolicyName); // Enable CORS!\n\n            app.UseStaticFiles();\n\n            app.UseRouting();\n\n            app.UseAuthentication();\n\n            app.UseAbpRequestLocalization();\n\n\n            app.UseEndpoints(endpoints =>\n            {\n                endpoints.MapHub<AbpCommonHub>("/signalr");\n                endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");\n                endpoints.MapControllerRoute("defaultWithArea", "{area}/{controller=Home}/{action=Index}/{id?}");\n            });\n\n            // Enable middleware to serve generated Swagger as a JSON endpoint\n            app.UseSwagger();\n            // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)\n            app.UseSwaggerUI(options =>\n            {\n                options.SwaggerEndpoint(_appConfiguration["App:ServerRootAddress"].EnsureEndsWith(\'/\') + "swagger/v1/swagger.json", "Kalibrasyon API V1");\n                options.IndexStream = () => Assembly.GetExecutingAssembly()\n                    .GetManifestResourceStream("TSE.Kalibrasyon.Web.Host.wwwroot.swagger.ui.index.html");\n            }); // URL: /swagger\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

有您可能知道的解决方案吗?提前致谢。

\n\n

另外,使用 JsonResult 控制属性名称的序列化。但没有用。请问有什么办法吗?

\n

aar*_*ron 7

在 .NET Core 3.x 中,您现在需要修改JsonSerializerOptions.PropertyNamingPolicy.

\n\n

对于 PascalCase \xe2\x80\x94 ,将原始属性名称 \xe2\x80\x94 设置为null

\n\n
services.AddMvc(...)\n    .AddJsonOptions(jsonOptions =>\n    {\n        jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;\n    });\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于小写字母(或其他自定义命名策略),子类化JsonNamingPolicy并重写该ConvertName方法。

\n\n
services.AddMvc(...)\n    .AddJsonOptions(jsonOptions =>\n    {\n        jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = new JsonLowercaseNamingPolicy();\n    });\n
Run Code Online (Sandbox Code Playgroud)\n\n
public class JsonLowercaseNamingPolicy : JsonNamingPolicy\n{\n    public override string ConvertName(string name) => name.ToLowerInvariant();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n

  • @RobertSmith on .net6.0,在 Startup.cs 中我必须为 PascalCase 添加 `services.AddControllers().AddNewtonsoftJson(options =&gt; { options.SerializerSettings.ContractResolver = new DefaultContractResolver(); })` (5认同)

小智 6

在 .NET 6.0 中,我设法解决了同样的问题,只需在 Program.cs 中添加以下代码(ofc,之前安装了 Newtonsoft 包。):

builder.Services.AddControllers().AddJsonOptions(options => 
options.JsonSerializerOptions.PropertyNamingPolicy = null);
Run Code Online (Sandbox Code Playgroud)