【问题标题】:Asp.Net Core: How to json serialize and deserialize IFormCollection?Asp.Net Core:如何对 IFormCollection 进行 json 序列化和反序列化?
【发布时间】:2017-03-27 07:53:53
【问题描述】:

在控制器中,我将表单数据序列化为 json 并保存到数据库:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(IFormCollection formData)
{
    var json = JsonConvert.SerializeObject(formData);
    var doc = new Doc()
    {
        Subject = formData["subject"],
        Content = json
    };

    _context.Docs.Add(doc);
    _context.SaveChanges();

    return RedirectToAction("Edit", new { Id = doc.Id });
}

现在,我想反序列化表单数据并重建表单:

public IActionResult Edit(int id)
{
    var doc = _context.Docs
        .Where(o => o.Id == id).FirstOrDefault();

    if (doc == null)
    {
        ViewData["ErrorMessage"] = "Not found";
        return View("Error");
    }

    var formData = JsonConvert.DeserializeObject<IFormCollection>(doc.Content);
    ViewData["FormData"] = formData;

    return View(doc);
}

上面会在反序列化时抛出异常:

JsonSerializationException:无法创建和填充列表类型 Microsoft.AspNetCore.Http.IFormCollection。路径'',第 1 行,位置 1。

如果我不指定类型,则反序列化成功;但我更喜欢它 被反序列化为 IFormCollection。反序列化 IFormCollection 的正确方法是什么?

另外,我保存 json 的原因是,我正在处理大约 30 种类型的表单,并且我不想为每个表单创建强类型模型对象。欢迎任何建议。

【问题讨论】:

  • 在不知道具体类型的情况下,您希望编译器如何反序列化为接口?一个接口没有实现,一个接口不能用new关键字实例化。您必须提供 concrete 类型,或者在类型中对其进行序列化(您将在 json 中有一个 _type (或左右)属性),然后丢弃该类型并将其转换回接口:(IFormCollection)JsonConvert.DeserializeObject(doc.Content)

标签: asp.net json asp.net-core json-deserialization


【解决方案1】:

我以前处理数据库中json对象的方式:

在您的实体对象中添加另一个类来处理与您的 json 对象的映射:

public class Contact
{
    public int Id { get; set; }
    internal string _Data { get; set; }

    [NotMapped]
    public UserData Data
    {
        get { return _Data == null ? null : JsonConvert.DeserializeObject<UserData>(_Data); }
        set { _Data = JsonConvert.SerializeObject(value); }
    }
}

public class UserData
{
    public string Name { get; set; }

    //Add your json data here
}

我的控制器看起来像

public IActionResult Add(AddContactViewModel model)
{
        var contact = new Contact()
        {
            Data = JsonConvert.DeserializeObject<UserData>(model.Data.ToString())
        };
        _contactService.Add(contact);
        return new OkObjectResult(contact);
}

public class AddContactViewModel
{
    public JObject Data { get; set; }
}

感谢映射,当您访问对象联系人所包含的对象数据时,您可以访问之前在 UserData 对象中定义的所有数据(对象名称可以根据您的情况更改)

var contact = new Contact()
{
    Data = JsonConvert.DeserializeObject<UserData>(model.Data.ToString())
};

contact.Data.Name;

【讨论】:

  • ASP.NET Core 如何在内部序列化东西?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 1970-01-01
  • 2016-11-20
相关资源
最近更新 更多