asp.net MVC에서 JsonResult를 통해 반환된 ExpandoObject를 평탄하게 하려면 어떻게 해야 합니까?
는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ExpandoObject
런타임에 서버 측 동적 개체를 컴파일할 때 JSON 시리얼화 중에 이 개체를 평탄화하는 데 문제가 있습니다.이치노
dynamic expando = new ExpandoObject();
var d = expando as IDictionary<string, object>;
expando.Add("SomeProp", SomeValueOrClass);
아직까지는 좋아.MVC 컨트롤러에서 이것을 JsonResult로 전송하고 싶기 때문에 다음 작업을 수행합니다.
return new JsonResult(expando);
그러면 JSON이 브라우저에 의해 소비되도록 다음 항목으로 시리얼화됩니다.
[{"Key":"SomeProp", "Value": SomeValueOrClass}]
하지만 내가 정말 보고 싶은 것은 이것이다.
{SomeProp: SomeValueOrClass}
가 이걸 쓸 수 걸 .dynamic
ExpandoObject
JsonResult
는, 을 할 수 .dynamic
속성 및 값을 단일 개체(키 또는 값 비즈니스 없음)로 변환합니다. 그러나 이 기능을 사용해야 하는 이유는 런타임까지 개체에서 원하는 속성을 모두 알 수 없기 때문입니다.또한 제가 아는 한 속성을 동적으로 추가할 수 없기 때문입니다.dynamic
를 하지 않고ExpandoObject
.
javascript에서 "Key"와 "Value"의 비즈니스를 검토해야 할 것 같습니다만, 고객에게 보내기 전에 이것을 확인하고 싶다고 생각하고 있었습니다.도와주셔서 감사합니다!
JSON 사용.NET Serialize Object를 호출하여 expando 개체를 "평탄화"할 수 있습니다.
dynamic expando = new ExpandoObject();
expando.name = "John Smith";
expando.age = 30;
var json = JsonConvert.SerializeObject(expando);
유언 출력:
{"name":"John Smith","age":30}
ASP의 컨텍스트에서.NET MVC 컨트롤러에서는 Content-Method를 사용하여 결과를 반환할 수 있습니다.
public class JsonController : Controller
{
public ActionResult Data()
{
dynamic expando = new ExpandoObject();
expando.name = "John Smith";
expando.age = 30;
var json = JsonConvert.SerializeObject(expando);
return Content(json, "application/json");
}
}
또한 ExpandoObject에만 사용할 수 있는 특별한 JSONConverter를 만든 후 JavaScriptSerializer 인스턴스에 등록할 수도 있습니다.이렇게 하면 expando 어레이, expando 객체 조합 등을 시리얼화할 수 있습니다.올바르게 시리얼화되지 않는 다른 종류의 오브젝트가 발견될 때까지("way you wanthed") 다른 Converter를 만들거나 이 Converter에 다른 유형을 추가합니다.이게 도움이 됐으면 좋겠다.
using System.Web.Script.Serialization;
public class ExpandoJSONConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
var result = new Dictionary<string, object>();
var dictionary = obj as IDictionary<string, object>;
foreach (var item in dictionary)
result.Add(item.Key, item.Value);
return result;
}
public override IEnumerable<Type> SupportedTypes
{
get
{
return new ReadOnlyCollection<Type>(new Type[] { typeof(System.Dynamic.ExpandoObject) });
}
}
}
컨버터 사용
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJSONConverter()});
var json = serializer.Serialize(obj);
당신이 설명한 행동을 달성하기 위해 제가 한 일은 다음과 같습니다.
dynamic expando = new ExpandoObject();
expando.Blah = 42;
expando.Foo = "test";
...
var d = expando as IDictionary<string, object>;
d.Add("SomeProp", SomeValueOrClass);
// After you've added the properties you would like.
d = d.ToDictionary(x => x.Key, x => x.Value);
return new JsonResult(d);
비용은 데이터를 일련화하기 전에 복사본을 만드는 것입니다.
ExpandoObject를 JSON 문자열로 변환하는 확장 메서드를 작성하여 이 문제를 해결했습니다.
public static string Flatten(this ExpandoObject expando)
{
StringBuilder sb = new StringBuilder();
List<string> contents = new List<string>();
var d = expando as IDictionary<string, object>;
sb.Append("{");
foreach (KeyValuePair<string, object> kvp in d) {
contents.Add(String.Format("{0}: {1}", kvp.Key,
JsonConvert.SerializeObject(kvp.Value)));
}
sb.Append(String.Join(",", contents.ToArray()));
sb.Append("}");
return sb.ToString();
}
이것은 훌륭한 뉴턴소프트 라이브러리를 사용합니다.
Json Result는 다음과 같습니다.
return JsonResult(expando.Flatten());
그리고 브라우저로 돌아갑니다.
"{SomeProp: SomeValueOrClass}"
javascript에서는 다음과 같이 사용할 수 있습니다(여기 참조).
var obj = JSON.parse(myJsonString);
도움이 됐으면 좋겠네요!
JsonFx를 사용하여 같은 문제를 해결할 수 있었습니다.
dynamic person = new System.Dynamic.ExpandoObject();
person.FirstName = "John";
person.LastName = "Doe";
person.Address = "1234 Home St";
person.City = "Home Town";
person.State = "CA";
person.Zip = "12345";
var writer = new JsonFx.Json.JsonWriter();
return writer.Write(person);
출력:
{FirstName}: "John", "LastName": "Doe", "Address": "1234 Home St", "City": "Home Town", "State": "CA", "Zip": "12345"}
평탄화 프로세스를 한 단계 더 진행하여 리스트 오브젝트를 확인했습니다.이것에 의해, 중요한 값의 무의미함이 배제됩니다.:)
public string Flatten(ExpandoObject expando)
{
StringBuilder sb = new StringBuilder();
List<string> contents = new List<string>();
var d = expando as IDictionary<string, object>;
sb.Append("{ ");
foreach (KeyValuePair<string, object> kvp in d)
{
if (kvp.Value is ExpandoObject)
{
ExpandoObject expandoValue = (ExpandoObject)kvp.Value;
StringBuilder expandoBuilder = new StringBuilder();
expandoBuilder.Append(String.Format("\"{0}\":[", kvp.Key));
String flat = Flatten(expandoValue);
expandoBuilder.Append(flat);
string expandoResult = expandoBuilder.ToString();
// expandoResult = expandoResult.Remove(expandoResult.Length - 1);
expandoResult += "]";
contents.Add(expandoResult);
}
else if (kvp.Value is List<Object>)
{
List<Object> valueList = (List<Object>)kvp.Value;
StringBuilder listBuilder = new StringBuilder();
listBuilder.Append(String.Format("\"{0}\":[", kvp.Key));
foreach (Object item in valueList)
{
if (item is ExpandoObject)
{
String flat = Flatten(item as ExpandoObject);
listBuilder.Append(flat + ",");
}
}
string listResult = listBuilder.ToString();
listResult = listResult.Remove(listResult.Length - 1);
listResult += "]";
contents.Add(listResult);
}
else
{
contents.Add(String.Format("\"{0}\": {1}", kvp.Key,
JsonSerializer.Serialize(kvp.Value)));
}
//contents.Add("type: " + valueType);
}
sb.Append(String.Join(",", contents.ToArray()));
sb.Append("}");
return sb.ToString();
}
JsonResult
JavaScriptSerializer
(Dictionary<string, object>
당신이 원하듯이.
이부 there of of of of of 가 되어 있다Dictionary<string, object>
IDictionary<string, object>
.
ExpandoObject
를 실장하다IDictionary<string, object>
알 수 있을 것
단일 수준 Expando Object
dynamic expando = new ExpandoObject();
expando.hello = "hi";
expando.goodbye = "cya";
var dictionary = new Dictionary<string, object>(expando);
return this.Json(dictionary); // or new JsonResult { Data = dictionary };
모든 삽입 유형을 사용하여 코드 한 줄:)
중첩된 Expando Objects
네스트하고 있는 ExpandoObject
모든 으로 ㄴ, ㄴ, ㄴ, 으로 변환해야 합니다.Dictionary<string, object>
s:
public static Dictionary<string, object> RecursivelyDictionary(
IDictionary<string, object> dictionary)
{
var concrete = new Dictionary<string, object>();
foreach (var element in dictionary)
{
var cast = element.Value as IDictionary<string, object>;
var value = cast == null ? element.Value : RecursivelyDictionary(cast);
concrete.Add(element.Key, value);
}
return concrete;
}
당신의 마지막 코드가
dynamic expando = new ExpandoObject();
expando.hello = "hi";
expando.goodbye = "cya";
expando.world = new ExpandoObject();
expando.world.hello = "hello world";
var dictionary = RecursivelyDictionary(expando);
return this.Json(dictionary);
이것은 당신에게 유용하지 않을 수도 있지만, 저는 비슷한 요건이 있었지만 SerializableDynamicObject를 사용했습니다.
사전의 이름을 "필드"로 바꾸면 Json과 연재됩니다.넷은 다음과 같은 json을 생성합니다.
{"필드":{"Property1":"Value1", "Property2":"Value2" 등. 여기서 Property1과 Property2는 동적으로 추가된 속성입니다.사전 키
나머지 부분을 캡슐화하는 추가 "Fields" 속성을 제거할 수 있다면 더할 나위 없이 좋을 것입니다만, 저는 그 한계를 극복해 왔습니다.
요청에 따라 이 질문에서 답변이 이동되었습니다.
늦은 답변이지만, 저도 같은 문제가 있었고, 이 질문이 문제를 해결하는 데 도움이 되었습니다.요약하자면, 다른 사람의 구현이 빨라지길 바라면서 결과를 게시해야겠다고 생각했습니다.
첫 번째 ExpandoJsonResult. 작업 중에 인스턴스를 반환할 수 있습니다.또는 컨트롤러에서 Json 메서드를 재정의하고 반환할 수 있습니다.
public class ExpandoJsonResult : JsonResult
{
public override void ExecuteResult(ControllerContext context)
{
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = !string.IsNullOrEmpty(ContentType) ? ContentType : "application/json";
response.ContentEncoding = ContentEncoding ?? response.ContentEncoding;
if (Data != null)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoConverter() });
response.Write(serializer.Serialize(Data));
}
}
}
다음으로 컨버터(시리얼라이제이션과 디시리얼라이제이션 양쪽을 서포트).디시리얼라이즈의 예에 대해서는, 이하를 참조해 주세요.
public class ExpandoConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{ return DictionaryToExpando(dictionary); }
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{ return ((ExpandoObject)obj).ToDictionary(x => x.Key, x => x.Value); }
public override IEnumerable<Type> SupportedTypes
{ get { return new ReadOnlyCollection<Type>(new Type[] { typeof(System.Dynamic.ExpandoObject) }); } }
private ExpandoObject DictionaryToExpando(IDictionary<string, object> source)
{
var expandoObject = new ExpandoObject();
var expandoDictionary = (IDictionary<string, object>)expandoObject;
foreach (var kvp in source)
{
if (kvp.Value is IDictionary<string, object>) expandoDictionary.Add(kvp.Key, DictionaryToExpando((IDictionary<string, object>)kvp.Value));
else if (kvp.Value is ICollection)
{
var valueList = new List<object>();
foreach (var value in (ICollection)kvp.Value)
{
if (value is IDictionary<string, object>) valueList.Add(DictionaryToExpando((IDictionary<string, object>)value));
else valueList.Add(value);
}
expandoDictionary.Add(kvp.Key, valueList);
}
else expandoDictionary.Add(kvp.Key, kvp.Value);
}
return expandoObject;
}
}
ExpandoJsonResult 클래스에서 직렬화에 사용하는 방법을 확인할 수 있습니다.시리얼화를 해제하려면 시리얼라이저를 작성하고 컨버터를 같은 방법으로 등록합니다만,
dynamic _data = serializer.Deserialize<ExpandoObject>("Your JSON string");
저를 도와주신 모든 참가자들에게 진심으로 감사드립니다.
ASP의 WebApi에서 동적 ExpandoObject를 반환하는 사용.Net 4, 기본 JSON 포메터는 ExpandoObjects를 단순한 JSON 개체로 평탄하게 만듭니다.
시리얼라이저는 Expando를 사전에 캐스팅한 후 시리얼화하는 것 같습니다(즉, 키/밸류 비즈니스).사전으로 역직렬화 한 후 Expando로 다시 돌려보셨나요?
나도 똑같은 문제가 있었는데 이상한 걸 알아냈어.이 경우:
dynamic x = new ExpandoObject();
x.Prop1 = "xxx";
x.Prop2 = "yyy";
return Json
(
new
{
x.Prop1,
x.Prop2
}
);
동작합니다만, 내 메서드가 HttpPost 속성을 사용하는 경우에만 동작합니다.HttpGet을 사용하면 오류가 발생합니다.그래서 제 답변은 Http Post에서만 작동합니다.제 경우 Ajax Call이므로 HttpGet by HttpPPost를 변경할 수 있습니다.
언급URL : https://stackoverflow.com/questions/5156664/how-to-flatten-an-expandoobject-returned-via-jsonresult-in-asp-net-mvc
'source' 카테고리의 다른 글
브라우저에서 패스워드 저장을 요구받으려면 어떻게 해야 하나요? (0) | 2023.02.10 |
---|---|
react-module, 번들 (0) | 2023.02.10 |
부모 노드와 통신하기 위한 react.display 사용자 지정 이벤트 (0) | 2023.02.10 |
다음/이미지 컴포넌트 높이를 100%로 설정하는 방법 (0) | 2023.02.10 |
REST 웹 서비스를 사용하여 메타데이터가 포함된 파일을 업로드하려면 어떻게 해야 합니까? (0) | 2023.02.10 |