Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何从ASP.NET MVC控制器方法返回JSON.NET序列化的camelCase JSON?_Asp.net Mvc_Json_Json.net_Camelcasing - Fatal编程技术网

Asp.net mvc 如何从ASP.NET MVC控制器方法返回JSON.NET序列化的camelCase JSON?

Asp.net mvc 如何从ASP.NET MVC控制器方法返回JSON.NET序列化的camelCase JSON?,asp.net-mvc,json,json.net,camelcasing,Asp.net Mvc,Json,Json.net,Camelcasing,我的问题是,我希望通过从ASP.NET MVC控制器方法返回camelCased(与标准的PascalCase相反)JSON数据,并通过序列化 作为一个例子,考虑下面的C类: 默认情况下,当从MVC控制器返回该类的实例作为JSON时,它将以以下方式序列化: { "FirstName": "Joe", "LastName": "Public" } 我希望(通过JSON.NET)将其序列化为: 我该怎么做?我在Mats Karlsson的网站上找到了解决这个问题的绝佳方法。解决方案是编写A

我的问题是,我希望通过从ASP.NET MVC控制器方法返回camelCased(与标准的PascalCase相反)JSON数据,并通过序列化

作为一个例子,考虑下面的C类:

默认情况下,当从MVC控制器返回该类的实例作为JSON时,它将以以下方式序列化:

{
  "FirstName": "Joe",
  "LastName": "Public"
}
我希望(通过JSON.NET)将其序列化为:


我该怎么做?

我在Mats Karlsson的网站上找到了解决这个问题的绝佳方法。解决方案是编写ActionResult的子类,通过JSON.NET序列化数据,将后者配置为遵循camelCase约定:

public class JsonCamelCaseResult : ActionResult
{
    public JsonCamelCaseResult(object data, JsonRequestBehavior jsonRequestBehavior)
    {
        Data = data;
        JsonRequestBehavior = jsonRequestBehavior;
    }

    public Encoding ContentEncoding { get; set; }

    public string ContentType { get; set; }

    public object Data { get; set; }

    public JsonRequestBehavior JsonRequestBehavior { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
        }

        var response = context.HttpContext.Response;

        response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json";
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data == null)
            return;

        var jsonSerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
        response.Write(JsonConvert.SerializeObject(Data, jsonSerializerSettings));
    }
}
然后在MVC控制器方法中使用此类,如下所示:

public ActionResult GetPerson()
{
    return new JsonCamelCaseResult(new Person { FirstName = "Joe", LastName = "Public" }, JsonRequestBehavior.AllowGet)};
}
或者,简单地说:

JsonConvert.SerializeObject(
    <YOUR OBJECT>, 
    new JsonSerializerSettings 
    { 
        ContractResolver = new CamelCasePropertyNamesContractResolver() 
    });

下面是一个通过序列化对象数组返回json字符串(cameCase)的操作方法

public string GetSerializedCourseVms()
    {
        var courses = new[]
        {
            new CourseVm{Number = "CREA101", Name = "Care of Magical Creatures", Instructor ="Rubeus Hagrid"},
            new CourseVm{Number = "DARK502", Name = "Defence against dark arts", Instructor ="Severus Snape"},
            new CourseVm{Number = "TRAN201", Name = "Transfiguration", Instructor ="Minerva McGonal"}
        };
        var camelCaseFormatter = new JsonSerializerSettings();
        camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver();
        return JsonConvert.SerializeObject(courses, camelCaseFormatter);
    }

请注意,JsonSerializerSettings实例作为第二个参数传递。这就是camelCase发生的原因。

有关WebAPI,请查看以下链接:

基本上,将此代码添加到您的
应用程序\u Start

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();

我想这就是你想要的简单答案。它来自于的博客:


自定义过滤器的另一种选择是创建扩展方法,将任何对象序列化为JSON

public static class ObjectExtensions
{
    /// <summary>Serializes the object to a JSON string.</summary>
    /// <returns>A JSON string representation of the object.</returns>
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new List<JsonConverter> { new StringEnumConverter() }
        };

        return JsonConvert.SerializeObject(value, settings);
    }
}
在ASP.NET核心MVC中

    public IActionResult Foo()
    {
        var data = GetData();

        var settings = new JsonSerializerSettings 
        { 
            ContractResolver = new CamelCasePropertyNamesContractResolver() 
        });

        return Json(data, settings);
    }
我喜欢这样:

public static class JsonExtension
{
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            NullValueHandling = NullValueHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize
        };
        return JsonConvert.SerializeObject(value, settings);
    }
}

这是MVC核心中的一个简单扩展方法,它将为项目中的每个对象提供ToJson()功能,在我看来,在MVC项目中,大多数对象都应该能够成为json,当然这取决于:)

越简单越好

你为什么不这样做

public class CourseController : JsonController
{
    public ActionResult ManageCoursesModel()
    {
        return JsonContent(<somedata>);
    }
}

必须在“Startup.cs”文件中设置设置

您还必须在JsonConvert的默认值中定义它,如果以后要直接使用库序列化对象,则需要这样做

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options => {
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    }

如果您在.net core web api中返回ActionResult或IHttpAction结果,那么您可以使用Ok()方法包装您的模型,该方法将匹配前端的案例,并为您序列化它。无需使用JsonConvert.:)

将Json属性添加到类定义中

[JsonObject(NamingStrategyType=typeof(CamelCaseNamingStrategy))]
公共阶层人士
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}


}
但是使用起来更复杂,因为您必须为每个控制器方法配置ContentResult。是的,我知道您的答案是一个可重用的解决方案,我的目的是要更清楚地说明它只是Serialize方法上的一个参数。如果您从
控制器
方法返回JSON,您可能应该使用<代码> ApiController <代码>,在这种情况下,这个答案非常有用。@西蒙哈切尔考虑了问题的范围,而不是一般情况。JSON的有效内容类型是“代码>应用程序/JSON < /代码>,而不是<代码>文本/普通< /代码>。完美答案:干净和可重用!谢谢。当此解决方案仍然有效时。但这是4年前提出的。我们有更好的解决方案吗?@SharpCoder三年后的今天,你有没有找到更好的替代方案?@DARKGuy:没有调查过(为了方便起见,Web API和MVC已经合并到ASP.NET 6Link中;这个设置很好地解决了这个问题:(不同的问题,但我同时使用它们,这个链接可能会在将来为我和其他人节省一些谷歌搜索的时间)。我很抱歉,伙计们。我读这篇帖子的速度太快了。这是针对ASP.NET 5的。具有讽刺意味的是,我来这里是想找到你在这里回答的问题的答案,所以虽然这不是OP问题的答案,但对我还是有帮助。谢谢!:)我支持@porcus说的话!谢谢@Quantium!ASP.NET Core 1.0的供参考默认情况下是驼峰式的,但事实证明,这毕竟不是.NET Core 1.0的默认情况。此解决方案会影响动态特性,默认情况下不会影响这些特性。更好的是,把它放在Startup.cs文件中。@FatAlbert是的,但是怎么做?@DARKGuy看到Daniel Sánchez对这个问题的回答,优雅而简单。你甚至可以将设置转移到一个静态只读字段中,并添加一个FromJson补码方法。请注意,这个答案对于ASP.NET核心是正确的,而不是ASP.NET(这是问题的框架)。考虑在方法之外提取“设置”变量(作为私有静态字段“CAMECASSETITES”),以便每次调用Tojson方法时不初始化一个新变量。
return Content(person.ToJson(), "application/json");
    public IActionResult Foo()
    {
        var data = GetData();

        var settings = new JsonSerializerSettings 
        { 
            ContractResolver = new CamelCasePropertyNamesContractResolver() 
        });

        return Json(data, settings);
    }
public static class JsonExtension
{
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            NullValueHandling = NullValueHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize
        };
        return JsonConvert.SerializeObject(value, settings);
    }
}
public class CourseController : JsonController
{
    public ActionResult ManageCoursesModel()
    {
        return JsonContent(<somedata>);
    }
}
public class JsonController : BaseController
{
    protected ContentResult JsonContent(Object data)
    {
        return new ContentResult
        {
            ContentType = "application/json",
             Content = JsonConvert.SerializeObject(data, new JsonSerializerSettings { 
              ContractResolver = new CamelCasePropertyNamesContractResolver() }),
            ContentEncoding = Encoding.UTF8
        };
    }
}
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options => {
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    }