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

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

Convert non-json string version of object to object

问题

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

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

使用以下逻辑:

var stringValue = valueProviderResult.FirstValue;

if (stringValue != null)
{
    // Assuming the format is consistent, you can implement your parsing logic here
    var tagsStartIndex = stringValue.IndexOf("tags: [");
    var tagsEndIndex = stringValue.IndexOf("]", tagsStartIndex);

    if (tagsStartIndex != -1 && tagsEndIndex != -1)
    {
        var tagsSubstring = stringValue.Substring(tagsStartIndex + 7, tagsEndIndex - tagsStartIndex - 7);
        var tagsArray = tagsSubstring.Split(',').Select(tag => int.Parse(tag.Trim())).ToList();

        var discriminatorStartIndex = stringValue.IndexOf("discriminator: ");
        var discriminatorEndIndex = stringValue.IndexOf(")", discriminatorStartIndex);

        if (discriminatorStartIndex != -1 && discriminatorEndIndex != -1)
        {
            var discriminatorSubstring = stringValue.Substring(discriminatorStartIndex + 15, discriminatorEndIndex - discriminatorStartIndex - 15);

            var selected = stringValue.Contains("selected: true");

            var discriminatorTags = new DiscriminatorTags(tagsArray, discriminatorSubstring, selected);

            // Now 'discriminatorTags' holds the parsed object
        }
    }
}

这样,你就可以手动解析非 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:

[Serializable]
[ModelBinder(BinderType = typeof(DiscriminatorTagsBinder))]
public struct DiscriminatorTags : IDiscriminatorTags
{
    public DiscriminatorTags(List&lt;int&gt; tags, string discriminator, bool selected)
    {
        this.Tags = tags;
        this.Discriminator = discriminator;
        this.Selected = selected;
    }

    [Required]
    public List&lt;int&gt; Tags { get; set; }
    [Required]
    public string Discriminator { get; set; }
    [Required]
    public bool Selected { get; set; }
}

The binder:

public class DiscriminatorTagsBinder : IModelBinder
{

    public DiscriminatorTagsBinder()
    {
    }

    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }

        var modelName = bindingContext.ModelName;

        // Try to fetch the value of the argument by name
        var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);

    

        var x = JsonSerializer.Deserialize&lt;DiscriminatorTags&gt;(valueProviderResult.FirstValue);

        if (valueProviderResult == ValueProviderResult.None)
        {
            return Task.CompletedTask;
        }

        bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);

        var value = valueProviderResult.FirstValue;

        // Check if the argument value is null or empty
        if (string.IsNullOrEmpty(value))
        {
            return Task.CompletedTask;
        }

        bindingContext.Result = ModelBindingResult.Success(valueProviderResult);
        return Task.CompletedTask;
    }
}

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

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

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)";
var matches = Regex.Matches(str, @"(tags:\s*\[(.*)\])|(selected:\s(true|false))|(discriminator:\s\w*)", RegexOptions.IgnoreCase);
var tagsMatch = matches[0].ValueSpan;
var bracketStartIndex = tagsMatch.IndexOf('[');
var tagsList = tagsMatch.Slice(bracketStartIndex + 1, tagsMatch.LastIndexOf(']') - 1 - bracketStartIndex);
var list = new List<int>();
foreach (var match in Regex.EnumerateMatches(tagsList, "[0-9]+"))
{
    list.Add(Convert.ToInt32(tagsList.Slice(match.Index, match.Length).ToString()));
}
var selectedMatch = matches[1];
var isSelected = Regex.Match(selectedMatch.Value, "true|false", RegexOptions.IgnoreCase);
var discriminatorMatch = matches[2].ValueSpan;
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:

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;;
var matches = Regex.Matches(str, @&quot;(tags:\s*\[(.*)\])|(selected:\s(true|false))|(discriminator:\s\w*)&quot;, RegexOptions.IgnoreCase);
var tagsMatch = matches[0].ValueSpan;
var bracketStartIndex = tagsMatch.IndexOf(&#39;[&#39;);
var tagsList = tagsMatch.Slice(bracketStartIndex + 1, tagsMatch.LastIndexOf(&#39;]&#39;) - 1 - bracketStartIndex);
var list = new List&lt;int&gt;();
foreach (var match in Regex.EnumerateMatches(tagsList, &quot;[0-9]+&quot;))
{
    list.Add(Convert.ToInt32(tagsList.Slice(match.Index, match.Length).ToString()));
}
var selectedMatch = matches[1];
var isSelected = Regex.Match(selectedMatch.Value, &quot;true|false&quot;, RegexOptions.IgnoreCase);
var discriminatorMatch = matches[2].ValueSpan;
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:

确定