【问题标题】:How to return indented json content from an OData controller in asp core web api?如何从 asp 核心 web api 中的 OData 控制器返回缩进的 json 内容?
【发布时间】:2019-05-26 23:04:47
【问题描述】:

我可以使用以下方式从普通 WebApi 中检索预期的 json 结果。

  services.AddMvc()
         .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
         .AddJsonOptions(x=>
         {
             x.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
         });

但是当使用 ODataController 而不是使用 Web api 时的 ControllerBase 时,我找不到像这样输出 json 的方法。 ODataController 总是发送一个缩小的 json。

public class EmployeeController : ODataController
{

    [EnableQuery()]
    public IActionResult Get()
    {
        return Ok(new BOContext().Employees.ToList());
    }
}

还有,startup.cs

 public class Startup
    {
        private static IEdmModel GetModel()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Employee>("Employee");
            return builder.GetEdmModel();
        }

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddOData();
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });



            services.AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
                .AddJsonOptions(x=>
                {
                    x.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.None;
                });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapODataServiceRoute("odata", "odata", GetModel());
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");

            });
        }
    }

路线正在运行,我正在接收正确的数据。

有没有办法从 OData 控制器控制和输出缩进的 json?

【问题讨论】:

  • 您是否有任何具体原因希望返回缩进 json 而不是资源友好的最小化版本?
  • 我正在构建一种后端,其中视图显示一些要编辑的 json。这是一些高级用户使用的。为了可用性,它应该是一个可读的 json。如果这可以由服务器处理,那就太好了。

标签: asp.net-core odata entity-framework-core asp.net-core-webapi asp.net-core-2.1


【解决方案1】:

不确定这是否仍然是实际的,但您可以在返回数据时指定格式化程序

// [...]
public IActionResult Get()
        {
            var res = Ok(_db.Employees);
            res.Formatters.Add(new Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter(
                new Newtonsoft.Json.JsonSerializerSettings() { Formatting = Newtonsoft.Json.Formatting.Indented }, 
                System.Buffers.ArrayPool<char>.Create()));
            return res;
        }

当然,如果您想要更通用的解决方案(或者您已经编写了很多代码),您可以创建临时抽象类并从该类继承,而不仅仅是ODataController

public abstract class AbstractFormattedOdataController : ODataController
    {
        public override OkObjectResult Ok(object value)
        {
            var res = base.Ok(value);
            res.Formatters.Add(new Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter(
                new Newtonsoft.Json.JsonSerializerSettings() { Formatting = Newtonsoft.Json.Formatting.Indented },
                System.Buffers.ArrayPool<char>.Create()));
            return res;
        }
    }
// [...]
public class EmployeesController : AbstractFormattedOdataController 
{
    [EnableQuery()]
    public IActionResult Get()
    {
        return Ok(new BOContext().Employees.ToList());
    }
}

【讨论】:

    【解决方案2】:

    我建议您使用缩小的 jsonm 进行传输,但使用 json beutifier 显示格式化的 json。不要在数据流阶段这样做。

    如果您在前端使用 javascript。你可以简单地使用

    JSON.stringify(jsObj, null, "\t"); // stringify with tabs inserted at each level
    JSON.stringify(jsObj, null, 2);    // stringify with 2 spaces at each level
    

    【讨论】:

    • 感谢 JSON.stringify 变体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 1970-01-01
    • 2014-02-11
    • 2017-07-29
    • 2020-07-01
    相关资源
    最近更新 更多