【问题标题】:How to override default deserialization for Controller Action in ASP.NET Core?如何覆盖 ASP.NET Core 中控制器操作的默认反序列化?
【发布时间】:2019-12-24 22:45:38
【问题描述】:

我在控制器中有一个动作,它的参数类型为Class1

[HttpPost]
public IActionResult Create(Class1 c)
{
}

我使用 JQuery 的 Ajax 函数向它发送数据。

我想编写自己的代码来反序列化SampleProperty

class Class1
{
    public string SampleProperty { get; set; }
}

有可能吗?我想覆盖默认反序列化。

我尝试了很多东西,例如写转换器:

public class SamplePropertyConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(string);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
                                    object existingValue, JsonSerializer serializer)
    {
        if ((string)existingValue == "abc")
            return "abc123";
        else
            return existingValue;
    }

    public override void WriteJson(JsonWriter writer, object value,
                                   JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanWrite => false;
    public override bool CanRead => true;
}

然后像这样使用它:

class Class1
{
    [JsonConverter(typeof(SamplePropertyConverter))]
    public string SampleProperty { get; set; }
}

但在这种情况下,SamplePropertyConverter 根本不被使用。 我也尝试在Startup中添加它,但后来我看到它进入CanConvert方法,但仅用于其他一些请求,而不是发送Class1CreateAction。

【问题讨论】:

  • 我认为您需要在asp.net-core 中显式使用[FromBody],然后将Class1 数据作为JSON 发布到请求正文中。如果请求数据为x-www-form-urlencoded,则不会使用 JSON 转换器。请参阅:Confused with FromBody in ASP.NET Core
  • 另外,您的ReadJson() 有一个错误。 existingValueClass1.SimpleProperty 的当前值,因为它正在被反序列化(例如,它已在构造函数中设置),不是正在读取的值。请参阅:Json.Net Is converting on its own before using my JsonConverter
  • @dbc 非常感谢[FromBody]contentType: 'application/json; charset=utf-8' 的提示。然后JsonConverter开始被调用!但为了实现这一点,我还需要 JSON.stringify 我的对象,因为 JQuery 没有自动将它转换为 Json,它仍然像 x-www-form-urlencoded 一样编写。

标签: c# ajax asp.net-core json.net


【解决方案1】:

如果你不使用json,你可以使用自定义模型绑定来制作。

1.假设你有ajax代码:

 var data = { "SampleProperty": "abc"};
   $(document).ready(function () {
        $.ajax({
            url: '/Test/Create',
            type: 'POST',
            data: data,
            success: function () {

            }

        });
   });

2.控制器:

[HttpPost]
public IActionResult Create(Class1 c)
{
}

3.Class1.cs:

class Class1
{
    [ModelBinder(BinderType = typeof(TestModelBinder))]
    public string SampleProperty { get; set; }
}

4.TestModelBinder.cs

public class TestModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));
        var values = bindingContext.ValueProvider.GetValue("SampleProperty");

        string result = "";

        if (values.FirstValue == "abc")
        {
            result = "abc123";
        }else
        {
            result = values.FirstValue;
        }
        bindingContext.Result = ModelBindingResult.Success(result);
        return Task.CompletedTask;
    }
}

【讨论】:

    猜你喜欢
    • 2018-11-04
    • 2018-12-16
    • 1970-01-01
    • 2017-09-30
    • 1970-01-01
    • 2017-07-10
    • 2022-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多