I am trying to create a WCF service with some enumerators exposed for clients to set certain properties on the class object. All enumerators associated with different Operations are put in a separate class.
What I understand after reading through some articles is that the Enumerator is accessible on the client side of a WCF service if,
the enumerator is declared in a separate DataContract. For my case, the problem is I am unable to have the client call the Enumerator like ClassName.Enum.Value per how the class has been designed. For some reason, wsdl generated combines the class name and enum name in to a single name like ClassNameEnumName for the enumerator and that needs to be accessed like Namespace.ClassNameEnumName.
a property of the enum type is declared inside the Class containing the Enumerators. The problem with this approach is that, I do not need this property but it is the only way I could have the enums recognized and included in the proxy class by the proxy generator on the client side as expected so that it could used like ClassName.Enum.Value. Another issue is that it exposes those properties to the client since it needs to be decorated with [DataMember]. I wish the client never sees those because the client never needs to use it. I am not sure how could I expose only the enumerator without the backing property showing up such that it could be used like ClassName.Enum.Value.
What I understand is, without an explicit instance of the DataMember, the object declared never gets defined in the proxy class generated. In my case, I am making it happen by creating a property like in the mock-up code below by creating properties but my concern is that this introduces unwanted DataMembers (like EnumErrType, ErrType) being exposed to the client.
So the question is, how can I have an enumerator declared inside a class to be used by the client which can be used like ClassName.Enum.Value without having to expose backing properties or even not creating one in the first place.
[DataContract]
public class ErrorTransaction
{
[DataMember]
public ICollection<Error> Errors { get; set; }
}
[DataContract]
public class Error
{
[DataMember]
public EnumErrorType EnumErrType { get; set; }
[DataMember]
public int id { get; set; }
[DataMember]
public ErrXYZ.EnumErrorType Type { get; set; }
[DataMember]
public DateTime Date { get; set; }
}
public class ErrXYZ
{
[DataMember]
public EnumErrorType ErrType { get; set; }
public enum EnumErrorType : int
{
[EnumMember]
errType1 = 1,
[EnumMember]
errType2 = 2,
[EnumMember]
errType3 = 3
}
}
Related
Consider a WCF service that can do something like this on the client side:
IMyClass MyClass = getSomeClass("MyClass");
Where IMyClass is:
public interface IMyClass
{
string Property1 { get; set; }
bool Property2 { get; set; }
int Property3 { get; set; }
}
Now, all these properties get initialised out of some JSON file at runtime. The JSON contains init values for all the parameters we want to expose to the client.
In some cases though, we may have init values for Property1 only. It means that the client should not be able to see Property2 or Property3. I understand that this specific example does not work since the interface is explicitely telling the client about Properties 2 and 3.
But, I was wondering if there was a way to filter out these properties (or even methods) of a class at runtime?
I have a class Thing that is deserialized from a JSON file using DataContractJsonSerializer:
[DataContract]
class Thing
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
// and so on...
}
To make this work, all properties need to have public or at least internal setters.
Two other modules (assemblies) need to access this class:
ThingView should have read-only access to most attributes.
ThingEditor needs full access to all attributes.
I could make the setters internal but then the ThingEditor would not get full access.
To restrict access for the ThingView class, the best idea I could come up with is to create a read-only wrapper of the Thing class. But this would involve a lot of code duplication.
Are there better ways to achieve more encapsulation for in a case like this?
(The actual code contains about 20 classes of this type, some of which form nested structures. Also, there are more than two modules that need either read or full access to the properties.)
There is nothing out of the box in the specs that would achieve this. However, you could do something like this for example
public interface IReadOnlInterface
{
int Id { get; }
string Name { get; }
}
public interface IInterface
{
int Id { get; set; }
string Name { get; set; }
}
internal class Thing : IInterface , IReadOnlInterface
{
public int Id { get; set; }
public string Name { get; set; }
}
However there is nothing stopping coders with dirty little fingers casting to the other interface. If its only a runtime issue, then interfaces should be fine. Otherwise youll have to create a better api design with secured data, and proxy type objects with readonly access, Though maybe someone has a better idea.
In my ASP.NET MVC web application, I am using the built in Controller.Json() method to serialize an object and send it back to the client in response to an AJAX call. The class of the object being serialized inherits from another class with some shared property names. This is intentional, as I need the property names to match for some reflection that's happening. I am "shadowing" those properties in the derived class so that they can be a different type from their same-name counterpart in the base class. Here's a simplified example:
public class BaseModel
{
public string Title { get; set; }
public decimal CleanUpHours { get; set; }
public decimal InstallHours { get; set; }
}
public class DerivedModel : BaseModel
{
public new BucketHoursWithCalculations CleanUpHours { get; set; }
public new BucketHoursWithCalculations InstallHours { get; set; }
}
When I serialize an instance of DerivedModel, my JSON object on the client contains only the decimal versions of CleanUpHours and InstallHours, not my custom class BucketHoursWithCalculations.
Inspecting the object in Visual Studio before it gets serialized shows both the base and derived versions of those properties, as shown here (please excuse all the extra properties — my sample classes above are more simplified than what I'm actually using, but the principle is the same):
Here's what that object looks like on the client once it's serialized into JSON:
As you can see, the derived/shadowed properties were not serialized, and the base properties were, but only in the cases where there was a name conflict (for example, the Title property in the base model serialized just fine).
How can I serialize only the shadowed properties where there's a name conflict? I don't believe changing the access modifiers (i.e. from public to protected or something) on the base properties will work in my case, because the BaseModel is used by Entity Framework, and must have public properties. Any help would be appreciated.
One idea is to define type parameter on the base model that is used for the hours properties. Then, define derived models for decimal and BucketHoursWithCalculations. I would be interested to see how BucketHoursWithCalculations serializes to JSON, but in any case the CleanUpHours and InstallHours properties should be serialized.
// use a type parameter on the base model that must be specified
// in derived models.
public class BaseModel<THours>
{
public string Title { get; set; }
public THours CleanUpHours { get; set; }
public THours InstallHours { get; set; }
}
// hours are specified as decimals
public class DecimalModel : BaseModel<decimal>
{
}
// hours are specified as BucketHoursWithCalculations
public class BucketHoursWithCalculationsModel : BaseModel<BucketHoursWithCalculations>
{
}
// usage
DecimalModel d = new DecimalModel();
d.CleanUpHours = 1.0M; // CleanUpHours is a decimal here
BucketHoursWithCalculationsModel b = new BucketHoursWithCalculationsModel();
b.CleanUpHours = new BucketHoursWithCalculations();
b.CleanUpHours.SomeProperty = 1.0M;
I have a situation where I have some DTO classes that should be implemented like:
public class City
{
public string Name { get; set; }
public State State { get; set; }
}
public class State
{
public string Name { get; set; }
}
The problem is, these are actually DTO classes for REST XML resources. And the City resource may include the State resource inline, or it may simply provide the resource ID (a URI). I am handling access to the DTO via the Repository pattern and would like it to be transparent to clients whether State is lazy loaded or not (like how NHibernate does with it's entity classes).
So my current plan is to use Castle DynamicProxy to create a proxy object when the REST Repository detects that the class isn't fully "hydrated" (i.e. not everything is inline). The proxy object will know how to lazy load attributes as needed.
To actually implement this, however, the only thing I've come up with is to have backing attributes for all relationships and put the Xml attributes on those. So the strategy looks like this:
[XmlType]
public class City
{
[XmlElement]
public string Name { get; set; }
[ToOneRestRelationship(BackingPropertyName = "StateBacking")]
public State State { get; set; }
[XmlElement(Name = "state")]
public ResourceBase StateBacking { get; set; }
}
[XmlType]
public class State
{
[XmlElement]
public string Name { get; set; }
}
Then the Repository object knows to set up the proxy object to either get the object from the StateBacking property and use that (inlined resource case) or do a REST request to lazily retrieve the State object (resource URI case, i.e. lazy) from the ID specified in the backing property.
Question
The issue is, this backing field is pretty ugly. What I would like is a way to have Castle generate a class that would have the backing property with the XmlElement attribute applied that I could pass to the XmlSerializer. Then my DTO classes could look more like the first example and wouldn't have to be aware that the actual serialising class has a backing property.
Is something like this possible with Castle or any other Proxy library?
After going an interesting and completely wrong way, i think it is indeed possible to create a backing field that won't be seen by clients. Since proxying works by inheriting from the proxied class, any property on the derived class won't be seen in the scope of the original class. So mixins are the way to go:
Given Foo
public class Foo
{
public virtual string Name { get; set; }
public virtual Bar bar { get; set; }
}
and Bar
public class Bar
{
public virtual string Name { get; set; }
}
We can declare an interface that will let us retrieve the backing field and an implementation
public interface IHasBarBackingField
{
Bar RetrieveBar();
}
public class HasBarBackingField : IHasBarBackingField
{
public HasBarBackingField()
{
// the constructor must contain ways to resolve the bar. Since
// the class is built while proxying you should have all the data
// available at this moment
}
public Bar RetrieveBar()
{
return new Bar(); // example, you could have a backing field somewhere in this class
}
}
Then you just have to mixin both classes when proxying:
var pg = new ProxyGenerator();
var hasBarBackingField = new HasBarBackingField();
var options = new ProxyGenerationOptions();
options.AddMixinInstance(hasBarBackingField);
var test = pg.CreateClassProxy<Foo>(options, new BarInterceptor());
and intercept the call interesting you in order to return the backing Bar
public class BarInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.Name == "get_bar")
{
var hasBarBackingField = invocation.InvocationTarget as IHasBarBackingField;
invocation.ReturnValue = hasBarBackingField.RetrieveBar();
}
else
{
invocation.Proceed();
}
}
}
The HasBarBackingField class should be built to return either the direct object or retrieve the referenced REST object. Hope this helps
Based on what i've seen NSubstitute do i'd say it is possible, as long as your properties are virtual: http://nsubstitute.github.io/help/partial-subs/ .
Creating a City class with virtual property State that is then resolved at runtime using the substitution pattern should be feasable
public class City
{
public string Name { get; set; }
[StateId(10)]
public virtual State State { get; set; }
}
var sCity = Substitute.For<City>();
sCity.State.Returns((core) => {return null; // here you can access informations about the call});
Definitely doable, but it's terra incognita from here on!
I have this ServiceContract
[OperationContract(IsOneWay=true)]
void ProcessMessage(Message message);
and these objects
[DataContract]
public class Message
{
[DataMember]
public long Id { get; set; }
[DataMember]
public string Body { get; set; }
}
[DataContract]
public class ExtendedMessage : Message
{
[DataMember]
public NameValueCollection AdditionalData { get; set; }
}
Will WCF be able to handle if I pass in the subclass to the service method? Or will it drop all extra properties that aren't on the base class?
ExtendedMessage msg = new ExtendedMessage();
...
ProcessMessage(msg);
I think if you didn't specify ExtendedMessage via the KnownType attribute, you would get an error. Once you've told WCF about ExtendedMessage via KnownType, it will work without losing data.
By the way, you don't need to know the set of possible types at compile time because the KnownType attribute can reference a method that will return the set of possible types at runtime.
You could also use the ServiceKnownType attribute to narrow down the scope of the KnownType attribute. You can apply the ServiceKnownType attribute on a specific operation or on your service contract.