wcf return public members of bl object - c#

im tring to return an BL object from wcf server
but i get all the private proprties only.
how to return only the BL public properties.
thats the BL Class in some dll i refernce to wcf server
[Serializable()]
public class Account
{
#region properties
private int _accountId;
public int AccountID
{
get
{
return _accountId;
}
set
{
_accountId = value;
}
}
private string _title;
public string Title
{
get
{
return _title;
}
set
{
_title= value;
}
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name= value;
}
}}
thats the wcf method in the interface
[OperationContract]
[WebGet(UriTemplate = "{Key}/{Client}/Registrations?eventID={eventID}&regStatus={regStatus}")]
List<Registration> GetRegistrations(string key, string client, int eventID, int regStatus);
the method that make the return list:
public List<Registration> GetRegistrations(string key, string client, int eventID, int regStatus)
{
if (Validation.ValidateClient(key, client) == false)
return null;
List<Registration> regs = Registration.GetRegByColumnandValue(eventID, (Registration.RegStatusFlags)regStatus);
return regs;
}

WCF does not use the [Serializable] attribute.
Write your BL object (or a DTO ) like this:
[DataContract]
public class Account
{
private int _accountId;
[DataMember]
public int AccountID
{
// get/set
}
private string _title;
[DataMember]
public string Title
{
// get/set
}
}
The [Serializable] is wrecking the way the type is serialized, it's not suitable for WCF.
If it is embedded in another layer and you cannot remove it, then create a DTO (Data Transfer Object) class. You'll need code to copy the relevant properties, at least server-side.

Related

Inheriting from an interface with properties of the same name

I have an interface IProduct and two partial classes SearchedProductInternal and SearchedProductExternal.
These two classes are extending classes coming from 3rd party webservice searches but both return slightly different result types.
I want to use the interface for both so they type returned is the same. I know how to inherit but what do I do to return the "Name" as both the interface and SearchedProductInternal have the same object name?
My Interface is similar to as follows:
public interface IProduct
{
string Name { get; }
string ID { get; }
string DescriptionShort { get; }
string DescriptionLong { get; }
}
My Object SearchedProductInternal has the following properties:
string Name;
int ObjectIdField;
string DescriptionShortField;
string DescriptionLongField;
So my this is where I am inheriting
public partial class SearchedProductInternal : IProduct
{
public string ID
{
get { return ObjectIdField.ToString(); }
}
public string Name
{
//What do I do here?
}
public string DescriptionShort{get { return shortDescriptionField; }
}
public string DescriptionLong {get { return longDescriptionField; }
}
}
I want to the return the name that has been originality assigned in the SearchedProductInternal class but I don't know how to do that because if I just put
return Name
I get a stackoverflow error as it appears to be just keeping calling its self?
I think what you should do here is to explicitly implement the interface, so that you will have both your Name property as defined in the class and the IProduct.Name property from your interface.
You can explicitly implement the interface, like so:
public partial class SearchedProductInternal : IProduct
{
string IProduct.ID
{
get { return ObjectIdField.ToString(); }
}
string IProduct.Name
{
get { return "Interface name"; }
}
string IProduct.DescriptionShort
{
get { return shortDescriptionField; }
}
string IProduct.DescriptionLong
{
get { return longDescriptionField; }
}
// Name property for the class, not the interface
public string Name
{
get { return "Class name"; }
}
}
This way you can differentiate between calls to your interface properties and properties with the same name on your class.
When accessing both properties you can also decide which you want, in the following manner:
var test = new SearchedProductInternal();
Console.WriteLine(test.Name); // returns "Class name"
Console.WriteLine((test as IProduct).Name); // returns "Interface name"
If your SearchedProductInternal already defines the property Name and you're trying to return the value of same Name property, you don't have to do anything.
Don't create one more property named Name. Just get rid of the Name property you added. Everything should work because the class already implemented the contract defined by the interface IProduct.
If you want to return different value from the IProduct.Name property, you can use explicit interface implementation.
You must change the name of the variable in this case Name.
If that was an ambigous sentence then remember it's the same for the PC. Name cannot be two things. but Name and _Name can.
public class SearchedProductInternal : IProduct
{
string _name = "test";
public string Name
{
get
{
return _name;
}
}
}
public interface IProduct
{
string Name { get; }
}
I agree with the above answer. But a minor issue here, we cannot expose the interface member as public, as it causes compile error.
We can have both class level and interface level members. The interface member cannot be accessed by using class instance, which can be accessed only through interface instance.
public interface IProduct
{
string Name { get; }
string ID { get; }
string DescriptionShort { get; }
string DescriptionLong { get; }
}
public partial class SearchedProductInternal : IProduct
{
private string _clsName;
private string _interfaceName;
private string _objectID;
private string _shortDesc;
private string _longDesc;
public SearchedProductInternal(string _cName, string _iName)
{
_clsName = _cName;
_interfaceName = _iName;
}
public string Name
{
get { return _clsName; }
}
string IProduct.Name
{
get { return _interfaceName; }
}
string IProduct.ID
{
get { return _objectID; }
}
string IProduct.DescriptionShort
{
get { return _shortDesc; }
}
string IProduct.DescriptionLong
{
get { return _longDesc; }
}
}
class Program
{
static void Main(string[] args)
{
SearchedProductInternal clsSearchProduct = new SearchedProductInternal("clsName", "interfaceName");
Console.WriteLine(clsSearchProduct.Name);
IProduct interfaceProduct = (IProduct)clsSearchProduct;
Console.WriteLine(interfaceProduct.Name);
Console.ReadLine();
}
}
I am not sure if I just explained this in a way that was not understood but the way that I got this to work was by just using {get;set;}
public partial class SearchedProductInternal : IProduct
{
public string ID
{
get { return ObjectIdField.ToString(); }
}
public string Name {get;set;}
public string DescriptionShort{get { return shortDescriptionField; }
}
public string DescriptionLong {get { return longDescriptionField; }
}
}

Triggering get and set for properties using attribute

I need to build an attribute that will override the getter and the setter of an property. To be more clear, here is how it works today and how it should work using the attribute (the result should be the same).
Old version:
public class A
{
private Handle _handle;
public String StringProp
{
get {
return _handle.GetProperty(PropId.StringProp);
}
set {
_handle.SetProperty(PropId.StringProp, value);
}
}
public int IntProp
{
get {
return _handle.GetProperty(PropId.IntProp);
}
set {
_handle.SetProperty(PropId.IntProp, value);
}
}
}
New version:
public class A
{
private Handle _handle;
[HandleProperty(PropId.StringProp)]
public String StringProp { get; set; }
[HandleProperty(PropId.IntProp)]
public int IntProp { get; set; }
}
The attribute HandleProperty should known to link the getter and setter to _handle.GetProperty and _handle.SetProperty.
I created two enums and some of the fields in one enum were mapped to another enums fields using attributes. I think you can do something like this...
[AttributeUsage(AttributeTargets.Field)]
public sealed class MapsToAttribute : Attribute
{
private string Text;
public string MapsToText
{
get
{
return Text;
}
}
public MapsToAttribute(string mapsToText)
{
Text = mapsToText;
}
public override string ToString()
{
return Text;
}
}

Use custom property attribute to map value to another type

I"m trying to put together an abstract class that various models in my MVVM will derive from. Part of this is for abstracting IEditableObject/IChangeTracking details.
For my IEditableObject, I want to store a shallow copy of "core data" (a struct that defines data that will be serialized, typically for database storage) so that it can be cancelled or committed. What I don't want to do is type this out for each new Model that I come up with.
I've defined a [DataCoreItem] custom attribute that I thought to use on the derived class's applicable properties. For some unrelated reasons, the abstract class takes a generic DataCoreType and IDType:
public abstract class ModelObject<T, DataCoreType, IDType> : INotifyPropertyChanged, IEditableObject
{
public abstract DataCoreType Load(IDType id);
public abstract bool Save(DataCoreType dataCore);
public abstract bool Delete(IDType id);
// etc...
Here's an example for my CompanyModel
the data core:
public struct CompanyDataCore
{
public int? ID;
public string Code;
public string Name;
public string PrimaryWebsite;
public string PrimaryPhone;
public string PrimaryEmail;
}
the derived class:
public class CompanyModel : ModelObject<CompanyModel, CompanyDataCore, int> {
CompanyDataCore dataCore;
[DataCoreMember]
public int? ID { get { return dataCore.ID; } set { SetProperty(ref dataCore.ID, value); } }
[DataCoreMember]
public string Name { get { return dataCore.Name; } set {SetProperty(ref dataCore.Name, value); } }
[DataCoreMember]
public string Code { get { return dataCore.Code; } set { SetProperty(ref dataCore.Code, value); } }
[DataCoreMember]
public string PrimaryPhone { get { return dataCore.PrimaryPhone; } set {SetProperty(ref dataCore.PrimaryPhone, value); } }
[DataCoreMember]
public string PrimaryEmail { get { return dataCore.PrimaryEmail; } set { SetProperty(ref dataCore.PrimaryEmail, value); } }
[DataCoreMember]
public string PrimaryWebsite { get { return dataCore.PrimaryWebsite; } set { SetProperty(ref dataCore.PrimaryWebsite, value); } }
Ok, finally... what I'd like for my abstract class is to use the BeginEdit(), EndEdit() and CancelEdit() methods to handle storage of a backup copy of the data core automatically. Here's how I envision it:
[DataCoreMember(MemberName="ID")]
public int? ID { get { return dataCore.ID; } set { SetProperty(ref dataCore.ID, value); } }
// etc etc
and in my abstract class:
public virtual void BeginEdit() {
Type t = typeof(T);
var props = t.GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(DataCoreMemberAttribute)));
// WHAT TO DO HERE??? everything else looks good up to here
foreach (object o in props) {
this.dataCoreBackup.???? = o.value;
}
IsEditing = true;
}
How to map the property to which the DataCoreMember is applied to the property of the struct as specified?
I'm inexperienced with reflection (and working generic types as well for that matter), but I gather that this can be done. I've found examples (as of yet untried) for how to get a list of those properties with the attribute applied to them, but I'm unsure how to ultimately reference the DataCore's property based on that. Can anyone show me how? Much appreciated.
Turns out it was a fairly easy task with Reflection. Explanation below (with much of the non-pertinent code stripped out)
This holds the data backup so CancelEdit is supported:
public struct CompanyDataCore
{
public int? ID;
public string Code;
public string Name;
public string PrimaryWebsite;
public string PrimaryPhone;
public string PrimaryEmail;
public string RootPath;
}
Here's the attribute class to denote which fields get backed up:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class DataCoreMemberAttribute : Attribute
{
public string MemberName { get; set; }
}
This is the derived class:
public class CompanyModel : ModelObject<CompanyModel, CompanyDataCore, int>
{
[Identifier]
[DataCoreMember(MemberName="ID")]
public int? ID { get { return dataCore.ID; } set { SetProperty(ref dataCore.ID, value); } }
[DataCoreMember(MemberName="Name")]
public string Name { get { return dataCore.Name; } set {SetProperty(ref dataCore.Name, value); } }
[DataCoreMember(MemberName="Code")]
public string Code { get { return dataCore.Code; } set { SetProperty(ref dataCore.Code, value); } }
[DataCoreMember(MemberName="PrimaryPhone")]
public string PrimaryPhone { get { return dataCore.PrimaryPhone; } set {SetProperty(ref dataCore.PrimaryPhone, value); } }
[DataCoreMember(MemberName="PrimaryEmail")]
public string PrimaryEmail { get { return dataCore.PrimaryEmail; } set { SetProperty(ref dataCore.PrimaryEmail, value); } }
[DataCoreMember(MemberName="PrimaryWebsite")]
public string PrimaryWebsite { get { return dataCore.PrimaryWebsite; } set { SetProperty(ref dataCore.PrimaryWebsite, value); } }
}
And here's the abstract class:
public abstract class ModelObject<T, DataCoreType, IDType> : INotifyPropertyChanged, IEditableObject
{
protected DataCoreType dataCoreBackup;
public virtual void BeginEdit() {
Type t = typeof(T);
// get a the properties with the attribute
var props = t.GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(DataCoreMemberAttribute)));
// backup needs to be boxed because it's a struct
object boxedBackup = this.dataCoreBackup;
foreach (var prop in props) {
foreach (CustomAttributeData attribData in prop.GetCustomAttributesData()) {
if (attribData.Constructor.DeclaringType == typeof(DataCoreMemberAttribute)) {
object origValue = prop.GetValue(this);
FieldInfo field = boxedBackup.GetType().GetField(attribData.NamedArguments[0].TypedValue.Value.ToString());
field.SetValue(boxedBackup, origValue);
}
}
}
this.dataCoreBackup = (DataCoreType)boxedBackup;
IsEditing = true;
}
... and now I can get INotifiyPropertyChanged and IEditbaleObject handled in an abstract class so I don't have to write a bunch of plumbing in each specific model that I'm going to use.
Hopefully someone else can find this useful.

Set method parameters as readonly

how can i create a method that get's an object to read only purpose
public class Person
{
public string Name;
}
public void RunMe(Person p)
{
p.Name="XXXX";
}
var p =new Person();
p.Name="YYYY";
RunMe(p);
Console.WriteLine(p.Name);
I am getting XXXX. but i want that the person object will not change it value.
you can use interfaces to restrict the access. It is also better to pass interfaces instead of concrete objects as parameters to methods.
public interface IReadablePerson
{
string Name { get; }
}
public interface IWritablePerson
{
string Name { set; }
}
public class Person : IReadablePerson, IWritablePerson
{
public string Name { get; set; }
}
and then have a method like this
public void RunMe(IReadablePerson p)
{
p.Name = "XXXX"; //compile time error!!!
}
The way to do this is via the get and set accessors, just don't define a set:
public String Name { get; }
This will make a property that you can treat exactly like a normal field for your purposes. Underneath properties are a little more complex using methods to set a backing field which you can read about on msdn
If you need to be able to set the property just once then define the set as private and pass the parameter into the constructor:
public class Person
{
public Person(String name)
{
this.Name = name;
}
public String Name { get; private set; }
}
Classes in C# are reference types, so there's no way to do what you want to do if Person is a class.
You could make it a value type (by making it a struct) in which case, a copy of the object would be passed in, but that may take implications at some other points in your program, so be wary if you do it.
It seems that you want to somehow be able to lock the member. One option would be to make the "set" dependent on another member like this:
public class Name
{
public bool Locked { get; set; }
private string name;
public string Name
{
get { return this.name; }
set
{
if(!this.Locked)
this.name = val;
}
}
}
Edit: Alternate method for making lock permanent.
public class Person
{
private bool locked = false;
public void Lock()
{
this.locked = true;
}
public bool Locked
{
get { return this.locked; }
}
// add same Name member as above
}
Edit: Yet ANOTHER way to lock, using a key.
private object key = null;
public bool Locked
{ get { return this.key != null; } }
public void Lock(object obj)
{
if (this.key == null)
{
this.key = obj;
}
}
public void Unlock(object obj)
{
if (this.key == obj)
{
this.key = null;
}
}
You can throw an exception if you want if trying to unlock with the wrong key object.
The behaviour described after the first setting of the property is this:
private string _name;
public string Name
{
get { return _name; }
set { // no setting }
}
This is NOT A GOOD PRACTICE.
you create unexpected behaviour for properties (if this is a public class).
Any consuming assembly cannot view the body of the get and set methods would expect a set method to behave a sertain way (setting a value).
This kind of behaviour should be put in a seperate set method.
This way you can see if it changed, throw an exception if you want, or return true if it changed.
Then you can still use the property for getting the value.
private bool _locked;
public string Name { get; private set;}
public boolSetName(string value)
{
bool hasChanged = false;
if(!_locked)
{
Name = value;
_locked = true;
hasChanged = true;
}
return hasChanged
}

Is it possible for a non-generic class contain a generic list in .NET (C# or VB.NET)?

I'm hoping someone can assist me with understanding if/how something like this is possible.
In this scenario, imagine you are trying to model a grid like a spreadsheet or in a DB, but where the data in each column can only be of one data type.
Example: Column 1 can only contain integers.
I created a generic class to model the column structure that looks like this:
public class CollectionColumn<T>
{
private string _name;
private string _displayName;
private List<T> _dataItems = new List<T>();
public string Name {
get { return _name; }
set { _name = value; }
}
public string DisplayName {
get { return _displayName; }
set { _displayName = value; }
}
public List<T> Items {
get { return _dataItems; }
set { _dataItems = value; }
}
}
Now what I want to do is have a container for the various columns (there could be CollectionColumn, CollectionColumn, etc.) with it's own properties, but I'm not sure how to do that where I can still access the columns and the data within them when I don't know their types.
This is a .NET 2.0 project so something like dynamic would not work, maybe a list of object? I am also not sure if there is a way to do this with interfaces.
public class ColumnCollection
{
public int Id { get; set; }
public string ContainerName { get; set; }
private List<CollectionColumn<T>> _columns;
public List<CollectionColumn<T>> Columns {
get { return _columns; }
set { _columns = value; }
}
}
What I want to be able to do is add various CollectionColumn's to the Columns collection of a ColumnCollection so I can have columns containing various types of data.
Any help would be very much appreciated.
This is a fairly common problem. What you need to do is either declare a non-generic base class that your generic class inherits from or a non-generic interface that your generic class implements. You can then make your collection of that type.
For example,
public abstract class CollectionColumnBase
{
private string _name;
private string _displayName;
public string Name {
get { return _name; }
set { _name = value; }
}
public string DisplayName {
get { return _displayName; }
set { _displayName = value; }
}
public abstract object GetItemAt(int index);
}
public class CollectionColumn<T> : CollectionColumnBase
{
private List<T> data = new List<T>();
public overrides object GetItemAt(int index)
{
return data[index];
}
public List<T> Items
{
get { return data; }
set { data = value; }
}
}
public class ColumnCollection
{
public int Id { get; set; }
public string ContainerName { get; set; }
private List<CollectionColumnBase> _columns;
public List<CollectionColumnBase> Columns {
get { return _columns; }
set { _columns = value; }
}
}

Categories

Resources