Unable to see extended Domain Class Property in a WCF Data Service oData v3

8 posts, 0 answers
  1. richard
    richard avatar
    6 posts
    Member since:
    Jun 2014

    Posted 03 Jun 2014 Link to this post

    Hi,

    I have extended one of my auto generated domain model classes to include an extra property, please see the example below:

    Partial Public Class Customer

        Public ReadOnly Property IDName As String
            Get
                Return Me.Id.ToString() + Me.Name
            End Get
        End Property

    End Class

    I have then tested the WCF Data Service (oData v3) I have created using the Data Services wizzard and i'm unable to see the extended property 'IDName', i've tried re-creating the service and no matter what i do i cannot see this additional property.


    Please can someone help?

    Thanks,
    Richard

  2. Raka
    Raka avatar
    71 posts
    Member since:
    Sep 2011

    Posted 03 Jun 2014 Link to this post

    Hello

    This kind of reminds me that you need to have a "Set" even though it is empty.  Something like
    Set {}

    to expose the property to web service. 
  3. DevCraft banner
  4. richard
    richard avatar
    6 posts
    Member since:
    Jun 2014

    Posted 03 Jun 2014 in reply to Raka Link to this post

    Hi Raka,

    Thank you for your quick response.

    I tried the below but it did not seem to make any difference, any other ideas?

    Partial Public Class Customer

        Private _IDName As String
        Public Property IDName As String
            Get
                Return Me.Id.ToString() + Me.Name
            End Get
            Set(ByVal value As String)
                Me._IDName = value
            End Set
        End Property

    End Class
  5. Raka
    Raka avatar
    71 posts
    Member since:
    Sep 2011

    Posted 04 Jun 2014 in reply to richard Link to this post

    I know it is a stupid question, but you did update the ws, right?
    Also the Set can be just empty - to cause it to be in effect 'readonly' property - which is what you originally wanted.

    I am afraid, all I can think of is that a property has to be public and must include a 'set' to make it visible via WS. 
    Is the class seriablizable?  I am just grasping at straws here.  Sorry.
  6. richard
    richard avatar
    6 posts
    Member since:
    Jun 2014

    Posted 06 Jun 2014 in reply to Raka Link to this post

    Thanks again Raka.

    Yes I did update the web service and i tried removing the read only and adding a set but neither fixed the issue.
    Not a stupid question at all, i've done that before!

    Yes the class is serializeable, all other fields are being included just not the one i added.

    Thanks,
    Richard
  7. Kaloyan Nikolov
    Admin
    Kaloyan Nikolov avatar
    118 posts

    Posted 06 Jun 2014 Link to this post

    Hi Richard,

    The metadata for oData services is provided by Telerik Data Access using the base class OpenAccessDataService<T>. It uses the OpenAccessMetadataProvider<T> class for this purpose. If you need to extend the class with more properties you should modify the metadata provider in order to include them in the service. 

    Please have in mind that if you would like to query data based on such properties it will not work as they will not be translated to SQL statements and most probably will cause an exception. 

    If you will use the service in desktop application or in Silverlight application I would suggest you to add such properties in a partial class in the client. It is more efficient as you don't need to transfer the data again, as you just concatenate another two properties that are already part of the class. 

    I hope this helps. 

    Regards,
    Kaloyan Nikolov
    Telerik
     
    OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
     
  8. richard
    richard avatar
    6 posts
    Member since:
    Jun 2014

    Posted 10 Jun 2014 in reply to Kaloyan Nikolov Link to this post

    Hi Kaloyan,

    Thank you for your detailed reply, i'm using the service from an  ASP.NET (VB) web forms application.

    Have you got an example of modifying the MetaDataProvider, is this done through a partial class?

    Can you point me at some examples that are non-silverlight regarding adding properties to a partial class?

    Many thanks,
    Richard
  9. Kaloyan Nikolov
    Admin
    Kaloyan Nikolov avatar
    118 posts

    Posted 13 Jun 2014 Link to this post

    Hi Richard,

    Unfortunately the MetadataProvider is not designed for extension with partial classes. You should apply the changes directly in the class and make sure that it will not be overridden next time you regenerate the service. I would suggest you to rename the folder in which the file resides and thus next time you regenerate the service the default folder will be created again. This will result in compilation errors and to solve them you should just delete the newly created folder. The code which is in this folder is not dynamic, it is one and the same for each service generation so this should be safe operation.

    About the changes you should apply:
    1. You need to add additional metadata in OpenAccessMetadataProvider.AddPropertiesForResourceType() method. You can see in the attached application how this is done by invoking the WebApplication1.oDataExtender.EnrichMetadata(resourceType, persistentType) method. This will provision the new property to the service.

    2. Now the problem is that the client doesn't know that this is a read only property and he/she could try to update it, to prevent it you should modify the OpenAccessUpdateProvider.SetValue() method as well and check if this property is allowed for update. In the attached sample application this is done with the call: if (WebApplication1.oDataExtender.CanUpdate(targetResource, propertyName) == false) return;

     You should know that the SetValue method is called for each and every object and property being updated so your implementation for the check it this is allowed update or not should be extremely fast and efficient. 

    Here is the sample code of the oDataExtender class:
    public static class oDataExtender
    {
        public static void EnrichMetadata(ResourceType resourceType, MetaPersistentType persistentType)
        {
            if (persistentType.Name == "User")
            {
                var propKind = ResourcePropertyKind.Primitive;
                var resType = ResourceType.GetPrimitiveResourceType(typeof(string));
                var prop = new ResourceProperty("DisplayProp", propKind, resType);
                resourceType.AddProperty(prop);
            }
        }
     
        public static bool CanUpdate(object entity, string propertyName)
        {
            return propertyName != "DisplayProp" || !(entity is User);
        }
    }


    Please excuse me that the demo code is in C#, it is really simple and I hope you will not have any problems translating it to VB. Should you have any additional question do not hesitate to get back to us. 


    Regards,
    Kaloyan Nikolov
    Telerik
     
    OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
     
Back to Top
DevCraft banner