1

如何在 .NET Core 3.1 或 .NET Standard (C#) 中反序列化 x-www-form-urlencoded 编码字符串?

我知道这个问题的答案。但是,FormDataCollection 在 .NET Core 3.1 中似乎不可用。 见这里

编辑:我被另一个外部系统传回了这个编码数据。我不是在编写 ASP.NET Core 网站/API。

4

3 回答 3

1

所以我从来没有找到这个问题的简洁答案。所以我敲了自己的粗略序列化器。在这里张贴,以防有人从中得到任何用处。我仍然欢迎更好的答案!:-)

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;

public static class FormUrlEncodedSerializer
{
    public static async Task<string> SerializeAsync(object obj)
    {
        if (obj == null)
            throw new ArgumentNullException(nameof(obj));

        var keyValues = obj.GetPropertiesAsDictionary();

        var formUrlEncodedContent = new FormUrlEncodedContent(keyValues);

        return await formUrlEncodedContent.ReadAsStringAsync();
    }

    public static T Deserialize<T>(string formUrlEncodedText) where T : new()
    {
        if (string.IsNullOrEmpty(formUrlEncodedText))
            throw new ArgumentException("Form URL Encoded text was null or empty.", nameof(formUrlEncodedText));

        var pairs = formUrlEncodedText.Split('&');

        var obj = new T();

        foreach (var pair in pairs)
        {
            var nameValue = pair.Split('=');

            if (HasValue(nameValue))
            {
                obj.SetProperty(nameValue[0], nameValue[1]);
            }
        }

        return obj;
    }

    private static bool HasValue(string[] nameValue)
    {
        return nameValue.Length == 2 && nameValue[1] != string.Empty;
    }
}

public static class ObjectExtensions
{
    public static void SetProperty(this object source, string propertyName, object propertyValue)
    {
        var pi = source.GetProperty(propertyName);

        if (pi != null && pi.CanWrite)
        {
            pi.SetValue(source, propertyValue, null);
        }
    }

    public static PropertyInfo GetProperty(this object source, string propertyName)
    {
        BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

        return source.GetType().GetProperty(propertyName, bindingFlags);
    }

    public static IDictionary<string, string> GetPropertiesAsDictionary(this object source)
    {
        var dict = new Dictionary<string, string>();

        if (source == null)
            return dict;

        var properties = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

        foreach (var property in properties)
        {
            var value = property.GetValue(source);

            if (value == null)
                continue;

            dict.Add(property.Name, value.ToString());
        }

        return dict;
    }
}

编辑:用 GetPropertiesAsDictionary 替换 ToKeyValues。

于 2020-06-01T09:47:34.317 回答
0

您可以使用Microsoft.AspNetCore.WebUtilities.FormReaderx-www-form-urlencoded内容反序列化为字典,如下所示:

static Dictionary<string, StringValues> DeserializeForm(string content) {
    using var reader = new FormReader(content);
    return reader.ReadForm();
}
于 2021-08-10T12:26:57.950 回答
0

为此,一个班轮 linq 是:

Dictionary<string,string> ParamsDict = ReceivedData.Split('&').Select(x => x.Split('=')).ToDictionary(key => key[0].Trim(), value => value[1].Trim()); 
于 2022-01-20T14:21:44.923 回答