Pergunta

I have an abstract class that's autogenerated by a code template. We then have several classes that derive from this class. There is a particular property on that class that for one of the derived implementations I would like to override the getter and setter. Unfortunately I can find no way of overriding the property as it is not declared virtual.

So as another approach, I decided to make the property protected, and then in the partial class (.shared.cs) create a public virtual property that effectively wraps the protected one. Then I can override this in the one specific implementation.

So on the server side this looks fine, but once I build it, it turns out that the partial shared file that ria generates for me on the client seems to have no visibility of the protected property.

ClassA.cs:

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated from a template.
//
//    Manual changes to this file may cause unexpected behaviour in your application.
//    Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace ABC.Web.Models.DomainModel
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    [RoundtripOriginal]
    public abstract partial class ClassA
    {
        public int Id { get; set; }
        public string Title { get; set; }
        protected string ApplicationNumber { get; set; }
    }
}

ClassA.shared.cs

namespace ABC.Web.Models.DomainModel
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;

    public abstract partial class ClassA
    {
        [IgnoreDataMember]
        public virtual string ApplicationNumberAccessor
        {
            get
            {
                return this.ApplicationNumber;
            } 
            set
            {
                this.ApplicationNumber = value;
            }
        }
    }
}

This effectively gives the error 'ABC.Web.Models.DomainModel.ClassA' does not contain a definition for 'ApplicationNumber' and no extension method 'ApplicationNumber' accepting a first argument of type 'ABC.Web.Models.DomainModel.ClassA' could be found (are you missing a using directive or an assembly reference?)

When double clicking the error it takes me to the client version of the file, where for some reason it can not see that protected property.

Any idea why? or alternatively is there a way (using Database first) to mark a field so it generates as virtual?

Foi útil?

Solução

WCF RIA does not create a member in the Web.g.cs unless the member would have been serialized. As ApplicationNumber is a protected property, WCF RIA ignores it. This explains why it compiles in the web project, but not in Silverlight.

Have you tried not sharing the other partial but adding the property instead?

Change it to ClassA.cs or ClassA.partial.cs and the contents to:

namespace ABC.Web.Models.DomainModel
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;

    public abstract partial class ClassA
    {
        // You _do_ want this serialized to the client and back
        // so remove the [IgnoreDataMember] atribute
        public virtual string ApplicationNumberAccessor
        {
            get
            {
                return this.ApplicationNumber;
            } 
            set
            {
                this.ApplicationNumber = value;
            }
        }
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top