NameValueCollection을 JSON 문자열로 변환하는 방법
나는 시도했다.
NameValueCollection Data = new NameValueCollection();
Data.Add("foo","baa");
string json = new JavaScriptSerializer().Serialize(Data);
반환:["foo"]
기대했었어{"foo" : "baa"}
이거 어떻게 해요?
Name Value Collection을 직렬화하는 방법 중 하나는 먼저 사전으로 변환한 다음 사전을 직렬화하는 것입니다.사전으로 변환하려면:
thenvc.AllKeys.ToDictionary(k => k, k => thenvc[k]);
변환을 자주 수행해야 하는 경우 NameValueCollection 확장 메서드를 만들 수도 있습니다.
public static class NVCExtender
{
public static IDictionary<string, string> ToDictionary(
this NameValueCollection source)
{
return source.AllKeys.ToDictionary(k => k, k => source[k]);
}
}
다음과 같이 한 줄로 변환할 수 있습니다.
NameValueCollection Data = new NameValueCollection();
Data.Add("Foo", "baa");
var dict = Data.ToDictionary();
그런 다음 사전을 직렬화할 수 있습니다.
var json = new JavaScriptSerializer().Serialize(dict);
// you get {"Foo":"baa"}
그러나 NameValueCollection은 하나의 키에 대해 다음과 같은 여러 값을 가질 수 있습니다.
NameValueCollection Data = new NameValueCollection();
Data.Add("Foo", "baa");
Data.Add("Foo", "again?");
이것을 연재하면,{"Foo":"baa,again?"}
.
변환기를 수정하여 다음을 생성할 수 있습니다.IDictionary<string, string[]>
대신:
public static IDictionary<string, string[]> ToDictionary(
this NameValueCollection source)
{
return source.AllKeys.ToDictionary(k => k, k => source.GetValues(k));
}
따라서 다음과 같은 시리얼화된 값을 얻을 수 있습니다.{"Foo":["baa","again?"]}
.
NameValueCollection
사전이 아니기 때문에JavaScriptSerializer
는, 직접 시리얼화할 수 없습니다.먼저 사전으로 변환한 다음 연재해야 합니다.
업데이트: 키당 여러 값에 대한 다음 문의:nvc[key]
콤마로 구분하여 반환하기만 하면 됩니다.그렇지 않은 경우 언제든지 전화할 수 있습니다.GetValues
그 값을 어떻게 할지를 결정하는 것입니다.다음 코드를 업데이트하여 가능한 한 가지 방법을 표시.
public class StackOverflow_7003740
{
static Dictionary<string, object> NvcToDictionary(NameValueCollection nvc, bool handleMultipleValuesPerKey)
{
var result = new Dictionary<string, object>();
foreach (string key in nvc.Keys)
{
if (handleMultipleValuesPerKey)
{
string[] values = nvc.GetValues(key);
if (values.Length == 1)
{
result.Add(key, values[0]);
}
else
{
result.Add(key, values);
}
}
else
{
result.Add(key, nvc[key]);
}
}
return result;
}
public static void Test()
{
NameValueCollection nvc = new NameValueCollection();
nvc.Add("foo", "bar");
nvc.Add("multiple", "first");
nvc.Add("multiple", "second");
foreach (var handleMultipleValuesPerKey in new bool[] { false, true })
{
if (handleMultipleValuesPerKey)
{
Console.WriteLine("Using special handling for multiple values per key");
}
var dict = NvcToDictionary(nvc, handleMultipleValuesPerKey);
string json = new JavaScriptSerializer().Serialize(dict);
Console.WriteLine(json);
Console.WriteLine();
}
}
}
사전이 많은 항목을 포함하지 않는 경우 클래스를 사용할 수 있습니다.System.Collections.Specialized.ListDictionary
Json을 사용하고 있는 한, 완전성을 위해, 그리고 질문이 계속되기 때문에(예를 들면, 여기서) Json을 사용하고 있는 한).NET 또는 (단, 아님)어댑터 패턴을 사용하여NameValueCollection
에 있어서IDictionary<string, string[]>
어댑터 및 임의의 사전의 시리얼화를 완전히 지원하는 시리얼라이저를 사용하여 시리얼화합니다.
이러한 어댑터는 다음과 같습니다.
public class NameValueCollectionDictionaryAdapter<TNameValueCollection> : IDictionary<string, string[]>
where TNameValueCollection : NameValueCollection, new()
{
readonly TNameValueCollection collection;
public NameValueCollectionDictionaryAdapter() : this(new TNameValueCollection()) { }
public NameValueCollectionDictionaryAdapter(TNameValueCollection collection)
{
this.collection = collection;
}
// Method instead of a property to guarantee that nobody tries to serialize it.
public TNameValueCollection GetCollection() { return collection; }
#region IDictionary<string,string[]> Members
public void Add(string key, string[] value)
{
if (collection.GetValues(key) != null)
throw new ArgumentException("Duplicate key " + key);
if (value == null)
collection.Add(key, null);
else
foreach (var str in value)
collection.Add(key, str);
}
public bool ContainsKey(string key) { return collection.GetValues(key) != null; }
public ICollection<string> Keys { get { return collection.AllKeys; } }
public bool Remove(string key)
{
bool found = ContainsKey(key);
if (found)
collection.Remove(key);
return found;
}
public bool TryGetValue(string key, out string[] value)
{
return (value = collection.GetValues(key)) != null;
}
public ICollection<string[]> Values
{
get
{
return new ReadOnlyCollectionAdapter<KeyValuePair<string, string[]>, string[]>(this, p => p.Value);
}
}
public string[] this[string key]
{
get
{
var value = collection.GetValues(key);
if (value == null)
throw new KeyNotFoundException(key);
return value;
}
set
{
Remove(key);
Add(key, value);
}
}
#endregion
#region ICollection<KeyValuePair<string,string[]>> Members
public void Add(KeyValuePair<string, string[]> item) { Add(item.Key, item.Value); }
public void Clear() { collection.Clear(); }
public bool Contains(KeyValuePair<string, string[]> item)
{
string[] value;
if (!TryGetValue(item.Key, out value))
return false;
return EqualityComparer<string[]>.Default.Equals(item.Value, value); // Consistent with Dictionary<TKey, TValue>
}
public void CopyTo(KeyValuePair<string, string[]>[] array, int arrayIndex)
{
foreach (var item in this)
array[arrayIndex++] = item;
}
public int Count { get { return collection.Count; } }
public bool IsReadOnly { get { return false; } }
public bool Remove(KeyValuePair<string, string[]> item)
{
if (Contains(item))
return Remove(item.Key);
return false;
}
#endregion
#region IEnumerable<KeyValuePair<string,string[]>> Members
public IEnumerator<KeyValuePair<string, string[]>> GetEnumerator()
{
foreach (string key in collection)
yield return new KeyValuePair<string, string[]>(key, collection.GetValues(key));
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
#endregion
}
public static class NameValueCollectionExtensions
{
public static NameValueCollectionDictionaryAdapter<TNameValueCollection> ToDictionaryAdapter<TNameValueCollection>(this TNameValueCollection collection)
where TNameValueCollection : NameValueCollection, new()
{
if (collection == null)
throw new ArgumentNullException();
return new NameValueCollectionDictionaryAdapter<TNameValueCollection>(collection);
}
}
public class ReadOnlyCollectionAdapter<TIn, TOut> : CollectionAdapterBase<TIn, TOut, ICollection<TIn>>
{
public ReadOnlyCollectionAdapter(ICollection<TIn> collection, Func<TIn, TOut> toOuter)
: base(() => collection, toOuter)
{
}
public override void Add(TOut item) { throw new NotImplementedException(); }
public override void Clear() { throw new NotImplementedException(); }
public override bool IsReadOnly { get { return true; } }
public override bool Remove(TOut item) { throw new NotImplementedException(); }
}
public abstract class CollectionAdapterBase<TIn, TOut, TCollection> : ICollection<TOut>
where TCollection : ICollection<TIn>
{
readonly Func<TCollection> getCollection;
readonly Func<TIn, TOut> toOuter;
public CollectionAdapterBase(Func<TCollection> getCollection, Func<TIn, TOut> toOuter)
{
if (getCollection == null || toOuter == null)
throw new ArgumentNullException();
this.getCollection = getCollection;
this.toOuter = toOuter;
}
protected TCollection Collection { get { return getCollection(); } }
protected TOut ToOuter(TIn inner) { return toOuter(inner); }
#region ICollection<TOut> Members
public abstract void Add(TOut item);
public abstract void Clear();
public virtual bool Contains(TOut item)
{
var comparer = EqualityComparer<TOut>.Default;
foreach (var member in Collection)
if (comparer.Equals(item, ToOuter(member)))
return true;
return false;
}
public void CopyTo(TOut[] array, int arrayIndex)
{
foreach (var item in this)
array[arrayIndex++] = item;
}
public int Count { get { return Collection.Count; } }
public abstract bool IsReadOnly { get; }
public abstract bool Remove(TOut item);
#endregion
#region IEnumerable<TOut> Members
public IEnumerator<TOut> GetEnumerator()
{
foreach (var item in Collection)
yield return ToOuter(item);
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
#endregion
}
그런 다음 주어진 시간에 맞게 적응된 것을 구성할 수 있습니다.NameValueCollection Data
간단하게 할 수 있습니다.
var adapter = Data.ToDictionaryAdapter();
주의:
어댑터를 사용하면 단순히 복사된 사전을 작성하는 것보다 성능이 향상될 수 있습니다.또, 사전의 시리얼화를 완전하게 서포트하고 있는 시리얼 라이저에서는 정상적으로 동작할 수 있습니다.
이 어댑터는 또한 다음 기능을 사용할 때 유용할 수 있습니다.
NameValueCollection
다른 코드와 조합하여IDictionary
일종의 - 이것이 어댑터 패턴의 근본적인 장점입니다.말하자면
JavaScriptSerializer
이 직렬화기는 구현 중인 임의 유형을 직렬화할 수 없으므로 어댑터와 함께 사용할 수 없습니다.IDictionary<TKey, TValue>
에서Dictionary<TKey, TValue>
자세한 내용은 JavaScript Serializer를 사용한 사전 시리얼화를 참조하십시오.「」를 사용하고
DataContractJsonSerializer
,a ,aNameValueCollection
는 데이터 계약 대리 메커니즘을 사용하여 시리얼화 그래프의 어댑터로 대체할 수 있습니다.Json j j j j j j 。 a '''a''
NameValueCollection
는 다음과 같은 커스텀을 사용하여 어댑터로 교체할 수 있습니다.public class NameValueJsonConverter<TNameValueCollection> : JsonConverter where TNameValueCollection : NameValueCollection, new() { public override bool CanConvert(Type objectType) { return typeof(TNameValueCollection).IsAssignableFrom(objectType); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.SkipComments().TokenType == JsonToken.Null) return null; // Reuse the existing NameValueCollection if present var collection = (TNameValueCollection)existingValue ?? new TNameValueCollection(); var dictionaryWrapper = collection.ToDictionaryAdapter(); serializer.Populate(reader, dictionaryWrapper); return collection; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var collection = (TNameValueCollection)value; var dictionaryWrapper = new NameValueCollectionDictionaryAdapter<TNameValueCollection>(collection); serializer.Serialize(writer, dictionaryWrapper); } } public static partial class JsonExtensions { public static JsonReader SkipComments(this JsonReader reader) { while (reader.TokenType == JsonToken.Comment && reader.Read()) ; return reader; } }
예를 들어 다음과 같이 사용할 수 있습니다.
string json = JsonConvert.SerializeObject(Data, Formatting.Indented, new NameValueJsonConverter<NameValueCollection>());
NameValueCollection
의 모든 합니다.- A
null
값; "" - 특정 키에 대한 여러 값(이 경우 쉼표로 구분된 값 목록을 반환합니다)
- 콤마를 값(''를 사용하는 할 수 .
NameValueCollection.Item[String]
를 참조해 주세요.
는 '어댑터'를 구현해야 .IDictionary<string, string[]>
IDictionary<string, string>
'나'나 '나'나 '나'나 '나'나 '나'나 '나'나 '나'나 '나'나 '나'나 '나'나 '나' 같은 것도null
값 배열- A
바이올린의 샘플(일부 기본적인 유닛 테스트 포함)은, https://dotnetfiddle.net/gVPSi7 를 참조해 주세요.
언급URL : https://stackoverflow.com/questions/7003740/how-to-convert-namevaluecollection-to-json-string
'programing' 카테고리의 다른 글
파일에서 검색된 JSON 데이터에 키 값을 추가하려면 어떻게 해야 합니까? (0) | 2023.03.28 |
---|---|
React 17에서 작동하는 효소 어댑터는 무엇입니까? (0) | 2023.03.28 |
Word press 첨부 파일 이미지 캡션 가져오기 (0) | 2023.03.28 |
ACF 달력 선택기에서 Wordpress의 시작 날짜와 종료 날짜에 대해 두 개의 날짜를 제한하는 방법은 무엇입니까? (0) | 2023.03.28 |
Axios가 내 요청 매개 변수를 인코딩하지 못하도록 하려면 어떻게 해야 합니까? (0) | 2023.03.28 |