locked
Serialize read-only properties RRS feed

  • السؤال

  • First up, apologies for the long post, i just like to be as descriptive as possible in my opening post.


    I have written a small webservice that (attempts to) return a class.

    Basic Class Layout:


    <Serializable()> _
    Public Class User

    Private _NTlogin As String
    Private _DisplayName As String
    Private _Department As String
    Private _EmailAddress As String

    Public ReadOnly Property NTlogin() As String
    Get
    Return _NTlogin
    End Get
    End Property

    Public ReadOnly Property DisplayName() As String
    Get
    Return _DisplayName
    End Get
    End Property

    Public ReadOnly Property Department() As String
    Get
    Return _Department
    End Get
    End Property

    Public ReadOnly Property EmailAddress() As String
    Get
    Return _EmailAddress
    End Get
    End Property


    Public Sub New()
    MyBase.New()
    End Sub


    Public Sub New(ByVal a As String, ByVal b As String, ByVal c As String, ByVal d As String)
    _NTlogin = a
    _DisplayName = b
    _Department = c
    _EmailAddress = d
    End Sub


    End Class


     

    This class is populated and returned by a web method:



    <WebMethod()> _
    Public Function get_Specific_User_coll(ByVal ntLogin As String) As ButtyBox.User


    _Conn = New SqlConnection(_ConnS)
    _Comm = New SqlCommand("get_User", _Conn)
    _Comm.CommandType = Data.CommandType.StoredProcedure


    _Para = New SqlParameter("@NT_Login", Data.SqlDbType.VarChar)
    _Para.Value = ntLogin
    _Comm.Parameters.Add(_Para)


    Dim ds As New Data.DataSet("User")
    Dim da As New SqlDataAdapter(_Comm)
    da.Fill(ds)


    _Para = Nothing
    _Comm = Nothing
    _Conn = Nothing
    da = Nothing


    Dim row As Data.DataRow
    Dim myUserO As New ButtyBox.User
    For Each row In ds.Tables(0).Rows
    Dim myUser As New ButtyBox.User(row.Item(0).ToString, row.Item(1).ToString, row.Item(2).ToString, row.Item(3).ToString)
    myUserO = myUser
    Next

    row = Nothing
    ds.Clear()
    ds = Nothing
    Return myUserO


    End Function


     




    This method is an interim test method, as the final output will be a collection of these classes.


    If i run the above, it all runs fine, but im always left with empty results,  e.g.

    <?xml version="1.0" encoding="utf-8" ?>
    <User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://blahblah.com/" />

     

    If i set the properties to read-write, or export the data using a dataset, then the results are displayed, e.g.

    I change the readonly property of NTlogin to a read-write property:


    Public Property NTlogin() As String
    Get
    Return _NTlogin
    End Get
    Set(ByVal value As String)
    _NTlogin = value
    End Set
    End Property


     



    then the results are returned as:

    <?xml version="1.0" encoding="utf-8" ?>
    - <User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://blahblah.com/">
    <ntLogin>ASR\MiWard</ntLogin>
    </User>

     

    So,  long story short, i can serialize read-write properties, but i really want these to be read-only to force other developers to use my methods for populating the classes.  It appears to be a serialization thing where it cannot reverse lookup the values as it cant get into the read-only properties.

    i have read some articles on the iSerializabe interface, but have made no head way with it at all (ie,  i get the same results)


    Anyone here know how to serialize read-only properties?
    is it even possible or am i just missing some glaringly obvious fact here?


    Thanks in advance,
    Mike.

    16/جمادى الأولى/1426 02:09 م

الإجابات

  • Well, unfortunately the short answer to your long post is that XML Serialization has no support for non-public or read-only properties.  That being said, there's nothing that says your setter has to actualy do anything; it just has to exist.  You could take the passive-aggresive route and just have an empty setter, then make an obscure comment in your documentation about the fact that the properties are really read-only in nature (and blame the whole thing on Microsoft of course).  Alternatively, you could throw an exception in your setter, which will give developers consuming your class better debugging info.

    Cheers,
    Todd Gray
    16/جمادى الأولى/1426 03:26 م
  • Suresh -- we hear you, and it's coming with the new [DataContract] serialization system in Windows Communication Foundation (a.k.a. Indigo).

    The new serialization removes many of the limitations of the XmlSerializer. You'll be able to serialize properties or fields, and those properties can be public, private, or even read-only. Also, the requirement to implement a default parameterless constructor will be removed.

    If you'd like to get a first look at this new technology, you can take a look at Beta 1 of WinFX here.

    Hope that helps
    -steve

    Program Manager, Windows Communication Foundation

    30/رجب/1426 07:02 م
    المشرف

جميع الردود

  • Well, unfortunately the short answer to your long post is that XML Serialization has no support for non-public or read-only properties.  That being said, there's nothing that says your setter has to actualy do anything; it just has to exist.  You could take the passive-aggresive route and just have an empty setter, then make an obscure comment in your documentation about the fact that the properties are really read-only in nature (and blame the whole thing on Microsoft of course).  Alternatively, you could throw an exception in your setter, which will give developers consuming your class better debugging info.

    Cheers,
    Todd Gray
    16/جمادى الأولى/1426 03:26 م
  • Why Microsoft doesnt provide support for XML serialization to private and read only members?

    Thanks,
    Suresh.
    17/جمادى الأولى/1426 05:59 ص
  • Default xml serialize uses uses reflection, you can't even have a type without defautl constructor
    You can try to do your own IXmlSerialize, or doing the Xml  doc yourself. the most flexible, you can have the cake and eat it.
    17/جمادى الأولى/1426 08:32 ص
  • Suresh -- we hear you, and it's coming with the new [DataContract] serialization system in Windows Communication Foundation (a.k.a. Indigo).

    The new serialization removes many of the limitations of the XmlSerializer. You'll be able to serialize properties or fields, and those properties can be public, private, or even read-only. Also, the requirement to implement a default parameterless constructor will be removed.

    If you'd like to get a first look at this new technology, you can take a look at Beta 1 of WinFX here.

    Hope that helps
    -steve

    Program Manager, Windows Communication Foundation

    30/رجب/1426 07:02 م
    المشرف
  • Hi would like to know how its possible in WCF, im getting this exception:

    An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior contract: http://tempuri.org/:IBaseFactoryService ----> System.Runtime.Serialization.InvalidDataContractException: No set method for property 'Codigo' in type 'ConMega.Juridico.Base.ClaveAbogado'. en System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type) en System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ImportDataMembers()

    How you can handle private and read-only members in WCF ?

    21/محرم/1429 05:19 م
  • Please start a new thread here: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=118&SiteID=1.

     

    Not only is the thread you replied to already answered (so fewer people will try to help you), but the original question was about ASMX web services, not about WCF.

    21/محرم/1429 06:20 م
    المشرف