2010-02-02 4 views
1

REST 끝 점이있는 ASP.NET MVC 2 사이트를 작성 중입니다. 이 서비스를 Rails 웹 응용 프로그램의 ActiveResource와 함께 사용하려고합니다.Rails 호환 .NET XML 직렬화

지금까지 ActiveResource 규칙과 일치하는 ASP.NET MVC에서 경로 설정을 가져 왔습니다. 하지만 문제가 발생하는 곳은 ActiveResource가 REST 서비스에 보내는 데이터를 역 직렬화하는 것입니다.

레일즈는 .NET과 매우 다른 xml 직렬화를 수행하는 것으로 보이지만 (어디에서나 문서화 된 이러한 규칙을 찾을 수는 없습니다). 예를 들어,이 같은 .NET 클래스를 :

public class Person 
{ 
    public string first_name { get; set; } 
    public string last_name { get; set; } 
    public bool active { get; set; } 
} 

여기에 몇 가지 차이점은 다음과 같습니다 레일 < 사람>

  • 을 수행하면서

    1. .NET이> < 사람으로 루트를 직렬화한다. 레일즈는 네임 스페이스를 추가하지 않는다.
    2. . 레일즈는 < first_name> 과 같은 속성을 serialize한다. 레일 < 활동 유형 =

    번호 (4)는 문제가 발생하지 않는 것> "부울"하지만, 다른 3 원인 .NET을하지 역 직렬화를 수행하면서.NET은> 활성 <으로 부울을 직렬화 메시지. XmlRoot 및 XmlElement 특성을 사용하여 개체를 꾸미면 이러한 문제를 해결할 수 있습니다. 그러나 이것은 오류가 발생하기 쉽고 지루합니다.

    레일즈의 ActiveResource에 의해 직렬화 된 .NET에서 XML을 비 직렬화하는 더 좋은 방법을 알고있는 사람이 있습니까?

  • +0

    '레일즈가하는 동안'은 무엇을 의미합니까? 말의 순서는 나를 혼란스럽게합니다. – smaclell

    +0

    죄송합니다. 태그가 표시되지 않도록 이스케이프하는 것을 잊었습니다. 이제 해결되었습니다. –

    답변

    2

    이것은 XmlAttributeOverrides을 사용하여 달성 할 수 있습니다.

    public class RailsXmlSerializer 
    { 
        private Type type; 
    
        public RailsXmlSerializer(Type type) 
        { 
        this.type = type; 
        } 
    
        public void Serialize(Stream stream, object o) 
        { 
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
        ns.Add("", ""); 
    
        XmlSerializer xmlSerializer = new XmlSerializer(type, GetOverrides(type)); 
        xmlSerializer.Serialize(stream, o, ns); 
        } 
    
        public object Deserialize(Stream stream) 
        { 
        XmlSerializer xmlSerializer = new XmlSerializer(type, GetOverrides(type)); 
        return xmlSerializer.Deserialize(stream); 
        } 
    
        private XmlAttributeOverrides GetOverrides(Type type) 
        { 
        XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 
    
        XmlAttributes classAttributes = new XmlAttributes(); 
        classAttributes.XmlType = new XmlTypeAttribute(type.Name.ToLower()); 
        overrides.Add(type, classAttributes); 
    
        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(type)) 
        { 
         XmlAttributes propertyAttributes = new XmlAttributes(); 
         propertyAttributes.XmlElements.Add(new XmlElementAttribute(property.Name.ToLower().Replace('_', '-'))); 
         overrides.Add(type, property.Name, propertyAttributes); 
        } 
    
        return overrides; 
        } 
    } 
    

    은 물론,이 오류 및 유형 검사로 가능 의 장식으로,보다 강력한 구현 할 필요가 :

    다음은 중요한 일부가되는 기본적인 예를 들어, GetOverrides()이다. 물론 GetOverrides()을 사용자 정의하여 원하는 출력을 제공 할 수도 있습니다. 상기되는 것을 여기서 얻어진 시료 Person 오브젝트를 소정의 출력이 주어진 입력

    <?xml version="1.0" encoding="utf-16"?> 
    <person> 
        <first-name>Jason</first-name> 
        <last-name>Bourne</last-name> 
        <active>true</active> 
    </person> 
    

    하고, 역 직렬화는 적절한 사람 개체를 제공하기 위해 정확하게 수행된다.

    1

    예.

    [XmlType("person", // issue #1 
        Namespace="")] // issue #2 
    public class Person 
    { 
        [XmlElement("first-name")] // issue #3 
        public string first_name { get; set; } 
    
        [XmlElement("last-name")] // issue #3 
        public string last_name { get; set; } 
    
        public bool active { get; set; } 
    } 
    
    +0

    이 접근 방식이 효과가 있지만 오류가 발생하기 쉽고 지루하다는 점을 지적했습니다. 나는 모든 물건을 장식 할 필요가없는 더 좋은 방법을 찾고 있습니다. 어떤 아이디어? 감사. –

    +0

    XmlAttributeOverrides 개체로 인스턴스화 된 특수 XmlSerializer를 사용할 수 있습니다. XmlAttributeOverrides를 동적으로 작성하여 밑줄 - 대시 (-) 대시 및 대문자 규칙을 처리해야합니다. 모든 유형의 객체에 대한 단일 serializer 클래스입니다. – Cheeso