当前位置: 首页 > 面试题库 >

如何在JSON.NET中将其作为ASP.NET MVC控制器的模型绑定器?

诸葛康胜
2023-03-14
问题内容

ASP.NET Web API团队已决定将JSON.NET库用于模型绑定JSON数据。但是,“常规”
MVC控制器仍使用劣质的JsonDataContractSerializer。这会导致解析日期出现问题,并使我非常头疼。

请参阅此作为参考:http :
//www.devcurry.com/2013/04/json-dates-are-different-in-aspnet-
mvc.html

作者选择在客户端的Knockout层中解决此问题。但是我更愿意通过在MVC控制器中使用与Web API控制器相同的JSON.NET模型绑定程序来解决此问题。

如何将不同的JSON模型绑定程序替换为ASP.NET MVC?具体来说,就是JSON.NET库。如果可能的话,使用来自Web
API的相同模型绑定器将是理想的。


问题答案:

我已经做到了,并且还通过以下方式大量定制了Json.NET正在执行的序列化:

替换global.asax.cs中的默认格式化程序Application_Start

GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
GlobalConfiguration.Configuration.Formatters.Add(new CustomJsonMediaTypeFormatter());

我的CustomJsonMediaTypeFormatter是:

public static class CustomJsonSettings
{
    private static JsonSerializerSettings _settings;

    public static JsonSerializerSettings Instance
    {
        get
        {
            if (_settings == null)
            {
                var settings = new JsonSerializerSettings();

                // Must convert times coming from the client (always in UTC) to local - need both these parts:
                settings.Converters.Add(new IsoDateTimeConverter { DateTimeStyles = System.Globalization.DateTimeStyles.AssumeUniversal }); // Critical part 1
                settings.DateTimeZoneHandling = DateTimeZoneHandling.Local;   // Critical part 2

                // Skip circular references
                settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

                // Handle special cases in json (self-referencing loops, etc)
                settings.ContractResolver = new CustomJsonResolver();

                _settings = settings;
            }

            return _settings;
        }
    }
}

public class CustomJsonMediaTypeFormatter : MediaTypeFormatter
{
    public JsonSerializerSettings _jsonSerializerSettings;

    public CustomJsonMediaTypeFormatter()
    {
        _jsonSerializerSettings = CustomJsonSettings.Instance;

        // Fill out the mediatype and encoding we support
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
        SupportedEncodings.Add(new UTF8Encoding(false, true));
    }

    public override bool CanReadType(Type type)
    {
        return true;
    }

    public override bool CanWriteType(Type type)
    {
        return true;
    }

    public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger)
    {
        // Create a serializer
        JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);

        // Create task reading the content
        return Task.Factory.StartNew(() =>
        {
            using (StreamReader streamReader = new StreamReader(stream, SupportedEncodings.First()))
            {
                using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                {
                    return serializer.Deserialize(jsonTextReader, type);
                }
            }
        });
    }

    public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
    {
        // Create a serializer
        JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);

        // Create task writing the serialized content
        return Task.Factory.StartNew(() =>
        {
            using (StreamWriter streamWriter = new StreamWriter(stream, SupportedEncodings.First()))
            {
                using (JsonTextWriter jsonTextWriter = new JsonTextWriter(streamWriter))
                {
                    serializer.Serialize(jsonTextWriter, value);
                }
            }
        });
    }
}

最后,CustomJsonResolver:

public class CustomJsonResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization)
    {
        var list = base.CreateProperties(type, memberSerialization);

        // Custom stuff for my app
        if (type == typeof(Foo))
        {
            RemoveProperty(list, "Bar");
            RemoveProperty(list, "Bar2");
        }

        return list;
    }

    private void RemoveProperty(IList<JsonProperty> list, string propertyName)
    {
        var rmc = list.FirstOrDefault(x => x.PropertyName == propertyName);

        if (rmc != null)
        {
            list.Remove(rmc);
        }
    }
}


 类似资料:
  • 问题内容: 我是SWIFT编程的新手,正在尝试制作一个简单的应用程序,以学习使用核心数据并将其绑定到应用程序中进行显示。我看了很多示例,但似乎都旧了。我正在使用XCode 9。 我从带有Core Data的MacOS Cocoa应用开始。我有一个名为“锻炼”的简单实体,具有4个属性,日期,秒,运动和rpe。 然后,我在视图控制器场景下添加了一个数组控制器。我添加了一个Table视图,该视图将Arr

  • 我需要修改我的代码,使它成为一个模型-视图-控制器。因为我是一个完全的编程新手,如果我诚实的话,我会头疼。任何帮助如何做到这一点将不胜感激。 *在一个牧场上有200只忙碌的绵羊。这群羊由95只白羊、60只黑羊和45只白黑羊组成。牧羊人现在想把它们分开,这样相应的羊毛就可以按颜色剪了。帮他写一个小脚本,这样他就可以更好地点他的羊了。请使用变量、数组、数学运算符和函数实现前三点。提示:为了更好地概述,

  • 我需要调用这个API在我的控制器得到它的数据。 这是我的控制器 以下是XML响应的外观:

  • 在Spring Boot(Spring MVC)中,我试图根据本问题中的#4测试表单到控制器的绑定。我在复制魔法帖请求时遇到问题- 然而,我的断言失败了,itemModel。getId()返回null。当spring调用@Controller类上的方法时,我如何像spring那样初始化模型? 更新 我已经更新了以下内容,但它仍然不起作用:

  • 我的Html代码是这样的。 课程:- 当我调用MVC控制器时,通过上层输入,绑定就发生了。以下方法的方法 x中的值是 但是当我在web api中尝试同样的事情时,它给了我415(不支持的媒体类型)。方法如下 它没有绑定,而是给出了415状态代码,上面写着不支持的媒体类型。我知道这么问很蠢但为什么会这样?如果我想做相同的绑定发生在mvc如何实现?我不想做这样的事 有没有办法做到这一点?

  • 我需要在主控制器中绑定来自不同fxml的控件。我有3个fxml文件,分别名为MainView.fxml、ChildView1.fxml和ChildView2.fxml。 mainview.fxml ChildView1.fxml 默认情况下,从ChildView1Controller禁用button1。 我希望在我的另一个视图(ChildView2.fxml)中的表行被选中时启用它。同样,在取消选