locked
Enforcing read-only properties for an OData Service RRS feed

  • Question

  • I have an OData Service (built with the latest WCF Data Services Toolkit) that exposes POCO entities, where some of the properties of those entities need to be read-only and other properties should be read-writable.  So far I have made the read-only properties, use a private setter.  However, when  a .NET client consumes these POCO entities thru the service, the fact that the property is not publicly settable, is ignored.  What is the correct way to expose properties of POCO entities as read only, so the clients can't update them? (Or do I have to intercept an update and block it?)
    Tuesday, March 22, 2011 10:43 PM

All replies

  • You can use SetEntitySetAccessRules and say which entities need to be ReadOnly. You can also use wild card like "*" and make all entities ReadOnly.

    Here is an example:

    using System.Data.Services;
    using System.Linq;
    using System.ServiceModel.Web;

    namespace NorthwindService
    {
        public class Northwind : DataService<NorthwindEntities>
        {
            // This method is called only once to initialize service-wide policies.
            public static void InitializeService(DataServiceConfiguration config)
            {
                // Grant only the rights needed to support the client application.
               config.SetEntitySetAccessRule("Orders", EntitySetRights.AllRead
                    | EntitySetRights.WriteMerge
                    | EntitySetRights.WriteReplace );
                config.SetEntitySetAccessRule("Order_Details", EntitySetRights.AllRead
                    | EntitySetRights.AllWrite);
                config.SetEntitySetAccessRule("Customers", EntitySetRights.AllRead);
            }
        }

    }

    The key here is the EntitySet names. Be it entiry framework entities of POCO entities, you can set rights on a set. EntitySetRights have multiple options on locking down or enabling access.

    Here is URL to the example:
    http://msdn.microsoft.com/en-us/library/system.data.services.dataserviceconfiguration.setentitysetaccessrule.aspx

    Here is the method definition on MSDN:
    http://msdn.microsoft.com/en-us/library/system.data.services.idataserviceconfiguration.setentitysetaccessrule.aspx

    Hope this helps you.

    regards
    Lohith
    http://about.me/kashyapa


    regards kashyapa
    Thursday, April 7, 2011 4:51 AM
  • Sorry, this doesn't quite get at the issue I was asking about.  These SetEntitySetAccessRules control whether an entity as a whole  is readonly or not.  I'm interested in the problem of properties of an entity being readonly.  I might have a customer entity for example, where I want the end user to be able to update the address of the customer but not the name of the customer, or other properties that I want the enduser to be able to read but not write back to.  When the client consumes such an Entity, it doesn't seem there are any notifications to the client of what is read only or not.  

    Connected to this, would be the problem the server has in knowing that the client is attempting to update (change) a readonly property when the entity is used to perform an update.  Assuming simple POCO entities, how is this check performed, assuming the underlying db does not have the same readonly profile on its fields.


    Thursday, April 7, 2011 2:23 PM
  • At this point, all that you can do to prevent a client from trying to update such a "read-only" property on an otherwise read/write entity is to implement a change interceptor and reject or ignore the change only on the "read-only" property. (Note that the change is made to the object before the change interceptor is called, so you will have to reset to the original value if you don't raise an exception.) For more information, see Interceptors (WCF Data Services).

    Of course, this is not a great client experience since the client has no knowledge of the property being read-only. Using the Entity Framework provider, you can add custom attributes to a property in the entity model, but the WCF Data Services client will just ignore it anyway.

    There is a new OData feature being discussed called Vocabularies that would probably be able to do this, but it seems like this is still just in the design stage, so it's probably a while off yet.

    Cheers,

    Glenn Gailey


    This posting is provided "AS IS" with no warranties, and confers no rights.
    Sunday, April 10, 2011 3:45 PM