열거를 문자열로 직렬화
일람표가 있습니다.
public enum Action {
Remove=1,
Add=2
}
그리고 수업:
[DataContract]
public class Container {
[DataMember]
public Action Action {get; set;}
}
용기의 인스턴스를 직렬화하는 경우 이 테 스 렬 턴 음 화 표 시 serial when됩니다같이:son j다son containerize of i컨으면과하인직{Action:1}
(일 경우)이 제거됩니다.(작업 remove경 (
I would like to get: 다음을 원합니다.{Action:Remove}
(예: 열거된 ) 열거)에 대한 문자열 형식을 지정해야 합니다.
다른 멤버 추가 없이 할 수 있나요?
Json 사용.Net, 커스텀을 정의할 수 있습니다.StringEnumConverter
as ~하듯이
public class MyStringEnumConverter : Newtonsoft.Json.Converters.StringEnumConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is Action)
{
writer.WriteValue(Enum.GetName(typeof(Action),(Action)value));// or something else
return;
}
base.WriteJson(writer, value, serializer);
}
}
로서 연재하다
string json=JsonConvert.SerializeObject(container,new MyStringEnumConverter());
애트리뷰트를 추가할 수 있습니다.
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
문자열로 일련화되지 않은 열거 속성으로 이동합니다.
또는 보다 이국적인 포맷을 염두에 두고 있는 경우 다음과 같은 Atribut을 사용하여 JSON serializer에 원하는 대로 포맷한 속성만 시리얼화하도록 지시할 수 있습니다.나머지 구현에 따라 다릅니다.또한 속성의 DataMember 속성도 인식합니다.
[JsonObject(MemberSerialization = MemberSerialization.OptOut)]
public class Container
{
public Action Action { get; set; }
[JsonProperty(PropertyName = "Action")]
public string ActionString
{
get
{
return Action.ToString();
}
}
}
JSON 포메터는 열거를 사용할 때 매우 특수한 동작을 합니다. 일반 데이터 계약 속성은 무시되고 열거를 다른 형식에서 더 쉽게 읽을 수 있는 문자열이 아닌 숫자로 취급합니다.이렇게 하면 플래그 유형의 열거를 쉽게 처리할 수 있지만 대부분의 다른 유형의 작업은 훨씬 더 어려워집니다.
MSDN에서:
열거 멤버 값은 JSON에서 숫자로 처리되며, 이는 멤버 이름으로 포함되는 데이터 계약에서 처리되는 방법과 다릅니다.데이터 계약 처리에 대한 자세한 내용은 데이터 계약의 열거 유형을 참조하십시오.
를 들어, 「」가 있는 는,
public enum Color {red, green, blue, yellow, pink}
노란색을 시리얼화하면 숫자 3이 생성되고 문자열 "yellow"가 생성되지 않습니다.모든 열거형 구성원은 직렬화할 수 있습니다.EnumMemberAttribute 및 NonSerializedAttribute Atribute Atribute Atribute를 사용할 경우 무시됩니다.
존재하지 않는 열거형 값을 역직렬화할 수 있습니다.예를 들어, 대응하는 색상 이름이 정의되어 있지 않은 경우에도 값 87을 이전 색상 열거형으로 역직렬화할 수 있습니다.
flags 열거형은 특별하지 않으며 다른 열거형과 동일하게 취급됩니다.
이 문제를 해결하는 유일한 실용적인 방법은 최종 사용자가 숫자 대신 문자열을 지정할 수 있도록 계약에서 열거형을 사용하지 않는 것입니다.대신 실제 답변은 열거형을 문자열로 대체하고 값을 유효한 열거형 표현 중 하나로 구문 분석할 수 있도록 내부 검증을 수행하는 것입니다.
또는 (마음의 척이 아닌) JSON 포메터를 자신의 포메터로 대체할 수도 있습니다.이 포메터는 다른 포메터와 마찬가지로 열거를 존중합니다.
간단한 방법은 다음과 같습니다.
JsonConvert.SerializeObject(myObject, Formatting.Indented, new StringEnumConverter());
과 serialization의 serialization에 name 또는 serialization의 이러한 속성은 열거 멤버 이름 또는 값에서 시리얼라이제이션에 사용됩니다.EnumMemberAttribute
.
가장 큰 장점은 다음과 같습니다.
- 시리얼라이저를 사용하여 조정할 필요가 없습니다.
- 모든 시리얼라이제이션 로직이 데이터 오브젝트에 포함됩니다.
- 보조 속성은 DataContractSerializer가 개인 속성을 가져오고 설정할 수 있으므로 보조 속성을 개인으로 설정하여 숨길 수 있습니다.
- 은 '연재하다'로할 수 .
string
int
클래스는 다음과 같습니다.
[DataContract]
public class SerializableClass {
public Shapes Shape {get; set;} //Do not use the DataMemberAttribute in the public property
[DataMember(Name = "shape")]
private string ShapeSerialization // Notice the PRIVATE here!
{
get { return EnumHelper.Serialize(this.Shape); }
set { this.Shape = EnumHelper.Deserialize<Shapes>(value); }
}
}
EnumHelper.cs
/* Available at: https://gist.github.com/mniak/a4d09264ad1ca40c489178325b98935b */
public static class EnumHelper
{
public static string Serialize<TEnum>(TEnum value)
{
var fallback = Enum.GetName(typeof(TEnum), value);
var member = typeof(TEnum).GetMember(value.ToString()).FirstOrDefault();
if (member == null)
return fallback;
var enumMemberAttributes = member.GetCustomAttributes(typeof(EnumMemberAttribute), false).Cast<EnumMemberAttribute>().FirstOrDefault();
if (enumMemberAttributes == null)
return fallback;
return enumMemberAttributes.Value;
}
public static TEnum Deserialize<TEnum>(string value) where TEnum : struct
{
TEnum parsed;
if (Enum.TryParse<TEnum>(value, out parsed))
return parsed;
var found = typeof(TEnum).GetMembers()
.Select(x => new
{
Member = x,
Attribute = x.GetCustomAttributes(typeof(EnumMemberAttribute), false).OfType<EnumMemberAttribute>().FirstOrDefault()
})
.FirstOrDefault(x => x.Attribute?.Value == value);
if (found != null)
return (TEnum)Enum.Parse(typeof(TEnum), found.Member.Name);
return default(TEnum);
}
}
Michal B가 게시한 솔루션은 효과가 있습니다.여기 다른 예가 있어.
Description Attribute는 시리얼화할 수 없으므로 다음을 수행해야 합니다.
[DataContract]
public enum ControlSelectionType
{
[EnumMember(Value = "Not Applicable")]
NotApplicable = 1,
[EnumMember(Value = "Single Select Radio Buttons")]
SingleSelectRadioButtons = 2,
[EnumMember(Value = "Completely Different Display Text")]
SingleSelectDropDownList = 3,
}
public static string GetDescriptionFromEnumValue(Enum value)
{
EnumMemberAttribute attribute = value.GetType()
.GetField(value.ToString())
.GetCustomAttributes(typeof(EnumMemberAttribute), false)
.SingleOrDefault() as EnumMemberAttribute;
return attribute == null ? value.ToString() : attribute.Value;}
를 사용하고 있는 경우.native json 시리얼라이저(즉,시스템.텍스트, Json.시리얼라이제이션에서는 열거형을 int가 아닌 문자열로 변환하도록 열거형에 속성을 추가할 수 있습니다.
문자열로 사용할 열거형에 다음 특성을 추가해야 합니다.
[Json Converter (type of (Json String Enum Converter)]
사용해보십시오.
public enum Action {
[EnumMember(Value = "Remove")]
Remove=1,
[EnumMember(Value = "Add")]
Add=2
}
하지만 이것이 당신의 경우에 적합한지 잘 모르기 때문에 제가 틀릴 수도 있습니다.
자세한 것은, http://msdn.microsoft.com/en-us/library/aa347875.aspx 를 참조해 주세요.
직렬화를 위해 컨테이너에 열거 속성이 포함되지 않아야 하지만 채워진 경우 아래 확장 메서드를 사용할 수 있습니다.
컨테이너 정의
public class Container
{
public string Action { get; set; }
}
열거 정의
public enum Action {
Remove=1,
Add=2
}
뷰의 코드
@Html.DropDownListFor(model => model.Action, typeof (Action))
확장 방식
/// <summary>
/// Returns an HTML select element for each property in the object that is represented by the specified expression using the given enumeration list items.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <typeparam name="TProperty">The type of the value.</typeparam>
/// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
/// <param name="expression">An expression that identifies the object that contains the properties to display.</param>
/// <param name="enumType">The type of the enum that fills the drop box list.</param>
/// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression, Type enumType)
{
var values = from Enum e in Enum.GetValues(enumType)
select new { Id = e, Name = e.ToString() };
return htmlHelper.DropDownListFor(expression, new SelectList(values, "Id", "Name"));
}
이 문제를 해결하기 위해Newtonsoft.Json
。에 의해, 한층 또, 서비스가 아닌 합니다.열거형 문제를 수정하고 오류 처리도 훨씬 개선하며 자체 호스팅된 서비스가 아닌 IIS 호스팅된 서비스에서 작동합니다. 바꿀 , .DataContract
반.꽤 많은 코드이기 때문에 GitHub에서 찾을 수 있습니다.https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.cs
엔트리를 몇 개 추가해야 합니다.Web.config
이 기능을 이용하려면 , 다음의 샘플 파일을 참조해 주세요.https://github.com/jongrant/wcfjsonserializer/blob/master/Web.config
언급URL : https://stackoverflow.com/questions/9156820/serialize-enum-to-string
'programing' 카테고리의 다른 글
왜 이 단순한 Angular는JS ng-show가 안 돼요? (0) | 2023.04.06 |
---|---|
리다이렉트 기능이 있는 스프링 부트 (1페이지 angular 2) (0) | 2023.04.06 |
Spring-Data-MongoDB를 취득하여 오브젝트를 검증하려면 어떻게 해야 합니까? (0) | 2023.04.06 |
각도 이해JS ng-src (0) | 2023.04.06 |
React에서 화면 크기가 모바일로 변경되었는지 감지하는 방법 (0) | 2023.04.06 |