0
votes

I've got a wcf dataservice which is using some poco object. In order to validate this objects when a change occurs I want to use the System.ComponentModel.DataAnnotations metadata - validation.

For testing purpose I've created a console app which consumes this wcf dataservice. Everything is working fine. Additionally there should also be client side validation. The servicereference does not expose the validations attribute automatically. So the idea was to put all the data model / structure in a common .net class library like:

    [DataServiceKey("ADRESSEN_KEY")]
public partial class Adresse
{
    [Required(ErrorMessage = "Das ADRESSEN_KEY-Feld darf nicht leer sein.")]
    public int? ADRESSEN_KEY { get; set; }
    public string ADRESSEN_NAM1 { get; set; }
    public string ADRESSEN_STRA { get; set; }
    [StringLength(4, ErrorMessage = "Die PLZ darf nur 4-stellig sein.")]
    public string ADRESSEN_PLZ { get; set; }
    public string ADRESSEN_ORT { get; set; }
}    [DataServiceKey("ORDERUSER_KEY")]
public partial class OrderUser
{
    [Required(ErrorMessage = "Das ORDERUSER_KEY-Feld darf nicht leer sein.")]
    public int? ORDERUSER_KEY { get; set; }
    public string ORDERUSER_NAME { get; set; }
    public string ORDERUSER_VORNAME { get; set; }
    public string ORDERUSER_USER { get; set; }
    public string ORDERUSER_PWD { get; set; }
    public int? ORDERUSER_ADRKEY { get; set; }
}

This two "entities" (POCOs) i'm referencing (as they are situated in the same solution) and using in the wcf dataservice class like:

public class AllEntities
{
    private List<OrderUser> _orderUserCollection = null;
    private List<OrderUser> LoadDataOrderUser()
    {
        List<OrderUser> orderUsers = new List<OrderUser>();
        i3.Data.DataReader dataReader = null;
        try
        {
            dataReader = new i3.Data.DataReader("SELECT * FROM ORDERUSER", ConfigurationManager.ConnectionStrings["i3Database"].ConnectionString);
            if (dataReader.HasRows)
            {
                do
                {
                    orderUsers.Add(new OrderUser() {
                        ORDERUSER_KEY = Convert.ToInt32(dataReader["ORDERUSER_KEY"]),
                        ORDERUSER_NAME = dataReader["ORDERUSER_NAME"].ToString(),
                        ORDERUSER_VORNAME = dataReader["ORDERUSER_VORNAME"].ToString(),
                        ORDERUSER_USER = dataReader["ORDERUSER_USER"].ToString(),
                        ORDERUSER_PWD = dataReader["ORDERUSER_PWD"].ToString(),
                        ORDERUSER_ADRKEY = Convert.ToInt32(dataReader["ORDERUSER_ADRKEY"])});
                } while (dataReader.Read());
            }
        }
        catch { }

        if (dataReader != null)
        {
            if (!dataReader.mRS.IsClosed)
                dataReader.Close();
        }

        return orderUsers;
    }

    public IQueryable<OrderUser> OrderUserCollection
    {
        get { _orderUserCollection = LoadDataOrderUser(); return _orderUserCollection.AsQueryable<OrderUser>(); }
    }


    private List<Adresse> _adresseCollection = null;
    private List<Adresse> LoadDataAdresse()
    {
        List<Adresse> adressen = new List<Adresse>();
        i3.Data.DataReader dataReader = null;
        try
        {
            dataReader = new i3.Data.DataReader("SELECT * FROM ADRESSEN", ConfigurationManager.ConnectionStrings["i3Database"].ConnectionString);
            if (dataReader.HasRows)
            {
                do
                {
                    adressen.Add(new Adresse()
                    {
                        ADRESSEN_KEY = Convert.ToInt32(dataReader["ADRESSEN_KEY"]),
                        ADRESSEN_NAM1 = dataReader["ADRESSEN_NAM1"].ToString(),
                        ADRESSEN_ORT = dataReader["ADRESSEN_ORT"].ToString(),
                        ADRESSEN_PLZ = dataReader["ADRESSEN_PLZ"].ToString(),
                        ADRESSEN_STRA = dataReader["ADRESSEN_STRA"].ToString()
                    });
                } while (dataReader.Read());
            }
        }
        catch { }

        if (dataReader != null)
        {
            if (!dataReader.mRS.IsClosed)
                dataReader.Close();
        }

        return adressen;
    }

    public IQueryable<Adresse> AdresseCollection
    {
        get { _adresseCollection = LoadDataAdresse(); return _adresseCollection.AsQueryable<Adresse>(); }
    }
}

Here I'm loading the data of the database into the objects, very simple for testing purpose before putting the data model into the class library it worked.

Finally in the webservice I'm instanciating my "context"-object like this. as said before puting the data model into the class library this lso worked fine...

public class i3DataService : DataService<AllEntities>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config)
    {
        // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
        config.SetEntitySetAccessRule("*", EntitySetRights.All); // für alle Entities soll CRUD zur Verfügung stehen
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.All); // alle Operationen sind zulässig
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    }
}

I'm also able to build the solution but as soon as I'm calling the service at runntime i'm getting an error like: mettag could not be resolved, soap contract exception aso...

any hints? I now I could use wcf ria and entity framework but I have to rely on a "custom"-workaround...

Thank you!!!

I'm getting closer, perhaps it has something to do with Null-bale types:

not working:

[Required(ErrorMessage = "Das ADRESSEN_KEY-Feld darf nicht leer sein.")]
public **int?** ADRESSEN_KEY { get; set; }

working:

[Required(ErrorMessage = "Das ADRESSEN_KEY-Feld darf nicht leer sein.")]
public **int** ADRESSEN_KEY { get; set; }

keep on searching...because the required attribute needs null or string.Empty...

ugh man, sometimes i'm coding funny things!

    [MetadataType(typeof(Adresse))]
[DataServiceKey("ADRESSEN_KEY")]
public partial class Adresse
{
    public int ADRESSEN_KEY { get; set; }
    public string ADRESSEN_NAM1 { get; set; }
    public string ADRESSEN_STRA { get; set; }
    [StringLength(4, ErrorMessage = "Die PLZ darf nur 4-stellig sein.")]
    public string ADRESSEN_PLZ { get; set; }
    public string ADRESSEN_ORT { get; set; }
    [Required(ErrorMessage = "Das ADRESSEN_TEST-Feld darf nicht leer sein.")]
    public int? ADRESSEN_TEST { get; set; }
}
[MetadataType(typeof(OrderUser))]
[DataServiceKey("ORDERUSER_KEY")]
public partial class OrderUser
{
    public int ORDERUSER_KEY { get; set; }
    public string ORDERUSER_NAME { get; set; }
    public string ORDERUSER_VORNAME { get; set; }
    public string ORDERUSER_USER { get; set; }
    public string ORDERUSER_PWD { get; set; }
    [Required(ErrorMessage = "Das ORDERUSER_ADRKEY-Feld darf nicht leer sein.")]
    public int? ORDERUSER_ADRKEY { get; set; }
}

what does not make much sense is if you specify the keydatafield like:

[DataServiceKey("ORDERUSER_KEY")]

public int? ORDERUSER_KEY { get; set; }

which than should be unique and nullable at once!!!

so the code now works as it is supposed to be, thanks anyway!

1

1 Answers

0
votes

Key properties must not be nullable and they don't allow null values. So the type in question is not recognized as an entity type which usually leads to all kinds of problems, errors and so on.