【问题标题】:Serialize form to string and deserealize it later to complex view model将表单序列化为字符串,稍后将其反序列化为复杂的视图模型
【发布时间】:2018-02-05 11:30:43
【问题描述】:

我正在动态生成的页面上实现“保存草稿”功能,并尝试使其尽可能通用。我所有的控制器和页面都应该支持它,这就是为什么我考虑在我的基本控制器中创建一个SaveDraft() POST 操作,它将接收一个作为字符串的序列化表单,可以直接保存到数据库中并在稍后反序列化为视图模型使用特定视图模型的特定获取操作

[HttpPost]
public ActionResult SaveDraft(string jsonData, long id)

我的第一个想法是创建通用基础控制器并将视图模型类型传递给它,但问题是一些控制器有多个不同命名的 POST 操作并使用不同的视图模型类型,我现在无法更改它。

一些视图模型很复杂,看起来很像

public class CollateralsDataModel
{
    //...
    public List<Applicant> Applicants { get; set; }
}

public class Applicant
{
    public long ApplicantId { get; set; }
    public IList<RealEstateSecurityCollateralsDTO> RealEstateSecurityCollaterals { get; set; }
    public IList<AdditionalCollateralDTO> AdditionalCollaterals { get; set; }
}

public class RealEstateSecurityCollateralsDTO
{
    [Required]
    [Display(ResourceType = typeof(CollateralsData), Name = nameof(CollateralsData.RealEstateSecurityType))]
    public int? RealEstateSecurityTypeId { get; set; }
    //...
}

表单上的输入名称看起来像

"Applicants[0].MortgageApplicantId": "11595",
"Applicants[0].RealEstateSecurityCollaterals[0].Id": "17",
"Applicants[1].MortgageApplicantId": "11596",
"Applicants[1].RealEstateSecurityCollaterals.Index": "0",
"Applicants[1].AdditionalCollaterals[0].Id": "138",
"Applicants[1].AdditionalCollaterals[0].AdditionalCollateralTypeId": "4",

我的问题是 - 如何将它们序列化为字符串,以便以后反序列化?

我尝试使用不同的组合

$('.draft-data-form').serializeArray() 
$('.draft-data-form').serialize()
JSON.stringify($('.draft-data-form').serializeArray());

但在我的操作中,我得到了扁平的 JSON 结构,但我无法反序列化它

var obj = JsonConvert.DeserializeObject<CollateralsDataModel>(jsonData);

无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型 '...Collat​​eralsDataModel',因为该类型需要 JSON 对象(例如 {"name":"value"})正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 对象(例如 {"name":"value"})或将反序列化类型更改为数组或实现集合接口的类型(例如 ICollection、IList),例如可以从 JSON 数组反序列化。 JsonArrayAttribute 也可以添加到类型中,以强制它从 JSON 数组中反序列化。

我也尝试将其反序列化为列表,但随后我得到了 115 个条目的列表

var obj = JsonConvert.DeserializeObject<List<CollateralsDataModel>>(jsonData);

所以我的问题是 - 如何将它们序列化为字符串,以便以后反序列化?

【问题讨论】:

  • “但是我得到了 115 个条目的列表”——嗯,对吗?如果没有:你能先过滤一下吗?
  • 重要提示:任何往返于客户的物品必须被视为有害和污染。你不能相信你从客户那里接受的任何东西是不变的;请非常小心,不要让人们仅通过更改隐藏表单输入中的值来使用他们的浏览器工具来查看其他人的抵押贷款。这是获得巨额法律费用的好方法。
  • @MarcGravell “但后来我得到了 115 个条目的列表”——嗯,对吗?如果没有:你能先过滤它吗?” 不,因为我得到了 115 个视图模型实例,其中填充了一些数据而不是一个
  • @MarcGravell 我知道这一点,但我并没有真正看到这对我来说是个问题,因为我只是将不完整的数据保存为序列化字符串以便稍后显示。无论如何,这是一个后台应用程序,只有员工会使用它。
  • 后台员工总是 100% 值得信赖,并且永远不会滥用系统或流程中的弱点,这是一项很好的工作:)

标签: javascript c# jquery .net asp.net-mvc


【解决方案1】:

您不想序列化/反序列化列表。只有一个模型实例。

我猜想错误在于在模型中实例化列表。我知道 DataContractSerializer 有一个问题,如果在构造模型时 List 没有实例化为空列表,那么反序列化将无法添加到它。

不确定这是否与您面临的问题相同,但值得一试。

例如。使用:

public List<Applicant> Applicants { get; set; } = new List<Applicant>();

【讨论】:

  • 我认为我的问题在于我正在尝试使用平面 JSON 对象创建包含列表的复杂嵌套对象:/
  • 因为你将它序列化为一个数组。使用 .serialize() 代替。
  • 我在问题中写了我也试过了。
  • 我建议的改变?
  • 我试图实例化它,但这没有任何意义,因为 serialize() 创建了一个普通的 GET 参数字符串,所以它也不能被序列化
猜你喜欢
  • 1970-01-01
  • 2019-06-05
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 2020-05-20
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
相关资源
最近更新 更多