将非 JSON 字符串版本的对象转换为对象。

huangapple go评论119阅读模式
英文:

Convert non-json string version of object to object

问题

将非 JSON 字符串转换为 DiscriminatorTags 结构类型,你可以使用自定义逻辑,解析字符串并设置结构的属性。在你的 DiscriminatorTagsBinder 类的 BindModelAsync 方法中,替换以下行:

  1. var x = JsonSerializer.Deserialize<DiscriminatorTags>(valueProviderResult.FirstValue);

使用以下逻辑:

  1. var stringValue = valueProviderResult.FirstValue;
  2. if (stringValue != null)
  3. {
  4. // Assuming the format is consistent, you can implement your parsing logic here
  5. var tagsStartIndex = stringValue.IndexOf("tags: [");
  6. var tagsEndIndex = stringValue.IndexOf("]", tagsStartIndex);
  7. if (tagsStartIndex != -1 && tagsEndIndex != -1)
  8. {
  9. var tagsSubstring = stringValue.Substring(tagsStartIndex + 7, tagsEndIndex - tagsStartIndex - 7);
  10. var tagsArray = tagsSubstring.Split(',').Select(tag => int.Parse(tag.Trim())).ToList();
  11. var discriminatorStartIndex = stringValue.IndexOf("discriminator: ");
  12. var discriminatorEndIndex = stringValue.IndexOf(")", discriminatorStartIndex);
  13. if (discriminatorStartIndex != -1 && discriminatorEndIndex != -1)
  14. {
  15. var discriminatorSubstring = stringValue.Substring(discriminatorStartIndex + 15, discriminatorEndIndex - discriminatorStartIndex - 15);
  16. var selected = stringValue.Contains("selected: true");
  17. var discriminatorTags = new DiscriminatorTags(tagsArray, discriminatorSubstring, selected);
  18. // Now 'discriminatorTags' holds the parsed object
  19. }
  20. }
  21. }

这样,你就可以手动解析非 JSON 字符串并构建 DiscriminatorTags 结构对象。

英文:

How do I convert a string version of an object that is not JSON, to the object type?

I'm creating a custom model binder for this struct so that I can send it as a Query Parameter:

  1. [Serializable]
  2. [ModelBinder(BinderType = typeof(DiscriminatorTagsBinder))]
  3. public struct DiscriminatorTags : IDiscriminatorTags
  4. {
  5. public DiscriminatorTags(List&lt;int&gt; tags, string discriminator, bool selected)
  6. {
  7. this.Tags = tags;
  8. this.Discriminator = discriminator;
  9. this.Selected = selected;
  10. }
  11. [Required]
  12. public List&lt;int&gt; Tags { get; set; }
  13. [Required]
  14. public string Discriminator { get; set; }
  15. [Required]
  16. public bool Selected { get; set; }
  17. }

The binder:

  1. public class DiscriminatorTagsBinder : IModelBinder
  2. {
  3. public DiscriminatorTagsBinder()
  4. {
  5. }
  6. public Task BindModelAsync(ModelBindingContext bindingContext)
  7. {
  8. if (bindingContext == null)
  9. {
  10. throw new ArgumentNullException(nameof(bindingContext));
  11. }
  12. var modelName = bindingContext.ModelName;
  13. // Try to fetch the value of the argument by name
  14. var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
  15. var x = JsonSerializer.Deserialize&lt;DiscriminatorTags&gt;(valueProviderResult.FirstValue);
  16. if (valueProviderResult == ValueProviderResult.None)
  17. {
  18. return Task.CompletedTask;
  19. }
  20. bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
  21. var value = valueProviderResult.FirstValue;
  22. // Check if the argument value is null or empty
  23. if (string.IsNullOrEmpty(value))
  24. {
  25. return Task.CompletedTask;
  26. }
  27. bindingContext.Result = ModelBindingResult.Success(valueProviderResult);
  28. return Task.CompletedTask;
  29. }
  30. }

The value to deserialize is actually not JSON, it is a string version of the object:

> "DiscriminatorTags(tags: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
> 14, 15, 16, 17, 18, 900], selected: true, discriminator: GroceryItm)"

So I am getting a JsonException when I do this: var x = JsonSerializer.Deserialize&lt;DiscriminatorTags&gt;(valueProviderResult.FirstValue);

How do I convert the non-json string to the DiscriminatorTags struct type?

答案1

得分: 4

这可能听起来很明显,但你需要手动解析你的字符串。这里没有免费的午餐。像这样的代码可以帮助你入门:

  1. var str = "DiscriminatorTags(tags: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 900], selected: true, discriminator: GroceryItm)";
  2. var matches = Regex.Matches(str, @"(tags:\s*\[(.*)\])|(selected:\s(true|false))|(discriminator:\s\w*)", RegexOptions.IgnoreCase);
  3. var tagsMatch = matches[0].ValueSpan;
  4. var bracketStartIndex = tagsMatch.IndexOf('[');
  5. var tagsList = tagsMatch.Slice(bracketStartIndex + 1, tagsMatch.LastIndexOf(']') - 1 - bracketStartIndex);
  6. var list = new List<int>();
  7. foreach (var match in Regex.EnumerateMatches(tagsList, "[0-9]+"))
  8. {
  9. list.Add(Convert.ToInt32(tagsList.Slice(match.Index, match.Length).ToString()));
  10. }
  11. var selectedMatch = matches[1];
  12. var isSelected = Regex.Match(selectedMatch.Value, "true|false", RegexOptions.IgnoreCase);
  13. var discriminatorMatch = matches[2].ValueSpan;
  14. var discriminator = discriminatorMatch[(discriminatorMatch.IndexOf(':') + 1)..].Trim();

你需要加强它来防止缺少值等情况,还要使用已编译的正则表达式实例。

英文:

This might sound obvious but you're going to have to manually parse your string. There is no free lunch here. Something like this could get you started:

  1. var str = &quot;DiscriminatorTags(tags: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 900], selected: true, discriminator: GroceryItm)&quot;;
  2. var matches = Regex.Matches(str, @&quot;(tags:\s*\[(.*)\])|(selected:\s(true|false))|(discriminator:\s\w*)&quot;, RegexOptions.IgnoreCase);
  3. var tagsMatch = matches[0].ValueSpan;
  4. var bracketStartIndex = tagsMatch.IndexOf(&#39;[&#39;);
  5. var tagsList = tagsMatch.Slice(bracketStartIndex + 1, tagsMatch.LastIndexOf(&#39;]&#39;) - 1 - bracketStartIndex);
  6. var list = new List&lt;int&gt;();
  7. foreach (var match in Regex.EnumerateMatches(tagsList, &quot;[0-9]+&quot;))
  8. {
  9. list.Add(Convert.ToInt32(tagsList.Slice(match.Index, match.Length).ToString()));
  10. }
  11. var selectedMatch = matches[1];
  12. var isSelected = Regex.Match(selectedMatch.Value, &quot;true|false&quot;, RegexOptions.IgnoreCase);
  13. var discriminatorMatch = matches[2].ValueSpan;
  14. var discriminator = discriminatorMatch[(discriminatorMatch.IndexOf(&#39;:&#39;) + 1)..].Trim();

You would need to harden it to guard against missing values etc. and also use a compiled instance for the Regex

huangapple
  • 本文由 发表于 2023年5月18日 08:08:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276940.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定