.NET의 JSON에서 객체 인스턴스를 인스턴스화 할 수 있습니까?
-
11-07-2019 - |
문제
객체 초기화기는 JSON과 매우 유사하며 이제 .NET에는 익명 유형이 있습니다. JSON과 같은 문자열을 가져 와서 JSON 문자열을 나타내는 익명의 객체를 만들 수 있다는 것은 멋질 것입니다.
객체 이니셜 라이저를 사용하여 익명 유형을 만듭니다.
var person = new {
FirstName = "Chris",
LastName = "Johnson"
};
객체 이니셜 라이저 코드 (바람직하게는 JSON과 같은)의 문자열 표현을 전달하여 해당 데이터와 함께 익명 유형의 인스턴스를 만들 수 있다면 굉장합니다.
C#이 동적이지 않고 컴파일러가 실제로 객체 이니셜 라이저를 변환하기 때문에 가능한지 모르겠습니다.d 익명 유형은 실행할 수있는 강력하게 입력 된 코드로 유형입니다. 이것은 설명되어 있습니다 이 기사.
아마도 JSON을 취하고 키/가치 사전을 만들 수있는 기능이 가장 효과적입니다.
.NET의 JSON에 대한 객체를 직렬화/사형화 할 수 있다는 것을 알고 있지만, 내가 찾는 것은 JavaScript의 작동 방식과 마찬가지로 본질적으로 느슨하게 입력되는 객체를 만드는 방법입니다.
.NET 에서이 작업을 수행하기위한 최상의 솔루션을 아는 사람이 있습니까?
업데이트 : 내가 이것을 묻는 이유의 맥락을 너무 명확하게 설명합니다 ... 나는 C#이 언어 수준에서 JSON을 더 잘 지원할 수있는 방법을 생각하고 있었고, 오늘날 개념적으로 할 수있는 방법을 생각하려고했습니다. 원인. 그래서 토론을 시작하기 위해 여기에 게시 할 것이라고 생각했습니다.
해결책
.NET에 대한 오리를 사용하는 언어가 있지만 C#을 사용하는 경우에는 불가능합니다. Dot.Notation을 사용하려면 필요한 속성이있는 어딘가에 클래스를 정의하고 JSON 데이터에서 클래스를 인스턴스화하려는 모든 메소드를 사용해야합니다. 수업을 사전 정의합니다 하다 강력한 타이핑, Intellisense를 포함한 IDE 지원 및 철자 실수에 대해 걱정하지 않는 것과 같은 혜택을 누리십시오. 익명 유형을 사용할 수 있습니다.
T deserialize<T>(string jsonStr, T obj) { /* ... */}
var jsonString = "{FirstName='Chris', LastName='Johnson, Other='unused'}";
var person = deserialize(jsonString, new {FirstName="",LastName=""});
var x = person.FirstName; //strongly-typed
다른 팁
당신은 확인해야합니다 json.net 프로젝트:
http://james.newtonking.com/pages/json-net.aspx
당신은 기본적으로 JSON의 물체를 수화시키는 능력에 대해 이야기하고 있습니다. 익명의 유형을 수행하지는 않지만 아마도 당신을 충분히 가까이하게 할 것입니다.
JSON을 구문 분석하고 JavaScript의 실제 객체와 유사하게 액세스 할 수있는 이름/값 사전을 반환하는 비교적 짧은 방법을 작성했습니다.
다음은 아래 방법의 샘플 사용량입니다.
var obj = ParseJsonToDictionary("{FirstName: \"Chris\", \"Address\":{Street:\"My Street\",Number:123}}");
// Access the Address.Number value
object streetNumber = ((Dictionary<string, object>)obj["Address"])["Number"];
그리고 다음은 parsejsontodictionary 방법에 대한 코드입니다.
public static Dictionary<string, object> ParseJsonToDictionary(string json)
{
var d = new Dictionary<string, object>();
if (json.StartsWith("{"))
{
json = json.Remove(0, 1);
if (json.EndsWith("}"))
json = json.Substring(0, json.Length - 1);
}
json.Trim();
// Parse out Object Properties from JSON
while (json.Length > 0)
{
var beginProp = json.Substring(0, json.IndexOf(':'));
json = json.Substring(beginProp.Length);
var indexOfComma = json.IndexOf(',');
string endProp;
if (indexOfComma > -1)
{
endProp = json.Substring(0, indexOfComma);
json = json.Substring(endProp.Length);
}
else
{
endProp = json;
json = string.Empty;
}
var curlyIndex = endProp.IndexOf('{');
if (curlyIndex > -1)
{
var curlyCount = 1;
while (endProp.Substring(curlyIndex + 1).IndexOf("{") > -1)
{
curlyCount++;
curlyIndex = endProp.Substring(curlyIndex + 1).IndexOf("{");
}
while (curlyCount > 0)
{
endProp += json.Substring(0, json.IndexOf('}') + 1);
json = json.Remove(0, json.IndexOf('}') + 1);
curlyCount--;
}
}
json = json.Trim();
if (json.StartsWith(","))
json = json.Remove(0, 1);
json.Trim();
// Individual Property (Name/Value Pair) Is Isolated
var s = (beginProp + endProp).Trim();
// Now parse the name/value pair out and put into Dictionary
var name = s.Substring(0, s.IndexOf(":")).Trim();
var value = s.Substring(name.Length + 1).Trim();
if (name.StartsWith("\"") && name.EndsWith("\""))
{
name = name.Substring(1, name.Length - 2);
}
double valueNumberCheck;
if (value.StartsWith("\"") && value.StartsWith("\""))
{
// String Value
d.Add(name, value.Substring(1, value.Length - 2));
}
else if (value.StartsWith("{") && value.EndsWith("}"))
{
// JSON Value
d.Add(name, ParseJsonToDictionary(value));
}
else if (double.TryParse(value, out valueNumberCheck))
{
// Numeric Value
d.Add(name, valueNumberCheck);
}
else
d.Add(name, value);
}
return d;
}
나는이 방법이 약간 거칠다는 것을 알고 있으며 아마도 최적화 될 수 있지만, 첫 번째 초안이며 단지 작동합니다.
또한 정규 표현식을 사용하지 않는 것에 대해 불평하기 전에 모든 사람이 정규 표현을 실제로 이해하는 것은 아니며, 그런 식으로 작성하면 필요한 경우 다른 사람들이 고치기가 더 어려워 질 것입니다. 또한, 나는 현재 정규 표현식을 너무 잘 모르고 문자열 구문 분석이 더 쉬웠습니다.
메소드 **에서 익명 유형을 반환 할 수 없으므로 "재수 화 된"익명 유형의 존재는 재수 화 된 방법으로 제한됩니다. 일종의 무의미합니다.
** 객체로 반환 할 수 있습니다 (특성에 액세스하기 위해 반사가 필요합니다. 객체의 유형은 모양이되어야합니다. 왜 개체를 만들고 처음에 채우지 않겠습니까?
이것에 대한 응용 프로그램은 무엇입니까?
나는 몇 가지 이유로이 길로 가지 않을 것입니다.
첫 번째; 반사를 사용하여 많은 지원 코드가 필요할 수 있습니다.
둘째, 당신이 말했듯이, C#은 강력하게 입력 된 언어이며, 이와 같은 것들은 이유 때문에 언어 사양에서 제외되었습니다.
셋째,이 작업에 대한 오버 헤드는 그만한 가치가 없습니다. 웹 페이지 (특히 Ajax 쿼리)는 실제로 빠르거나 목적을 물리칩니다. 계속해서 C#과 JavaScript 사이에서 객체를 직렬화하는 50%를 소비하면 문제가 있습니다.
내 해결책은 사전을 캡슐화하고 JSON 문자열을 CTOR 인수로 취하는 클래스를 만드는 것입니다. 그런 다음 처리하려는 각 유형의 JSON 쿼리에 대한 해당 클래스를 확장하십시오. 이것은 강력하고 유형이 빠르고 더 빠른 솔루션이지만 여전히 확장 성과 사용 편의성을 유지합니다. 단점은 JSON 요청 유형 당 더 많은 코드가 있다는 것입니다.
:)