Validation of elements in a collection of a WCF data contract - wcf

We have a WCF service that uses Microsoft.Practices.EnterpriseLibrary.Validation and receives an object like so (simplified):
[DataMember]
[NotNullValidator]
public string Name { get; set; }
[DataMember]
public IList<Appointment> Appointments { get; set; }
The Appointment DataContract could look like:
[DataMember]
[NotNullValidator]
public string Description { get; set; }
Now the problem is that the validation of the Name property seems to work, but the Description isn't validated. So you can't pass a request with an empty Name, but you can pass a request with a Name and a list of Appointments with empty Descriptions.
Is it normal that WCF doesn't validate the elements of a collection in a DataContract?

Well, we solved it by adding SelfValidation:
[HasSelfValidation]
public class Client
{
[DataMember]
[NotNullValidator]
public string Name { get; set; }
[DataMember]
public IList<Appointment> Appointments { get; set; }
[SelfValidation]
{
foreach (var appointment in Appointments)
{
results.AddAllResults(Validation.Validate(appointment));
}
}
}

Related

How to implement GET endpoint in ASP.NET Core which returns object with File?

I have the following class:
public class Person
{
public string Name { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public byte[] PersonPhoto{ get; set; }
}
Usually I implement get objects endpoint, which returns not directly file but path to that file, and second endpoint to retrieve file separately.
Is that any solution which will let me implement it from one endpoint?
Is it a good practice?

I am using complex type as datamember of a datacontract

I am using complex type as datamember of a datacontract. But the service is throwing an exception if i set [DataMember] to the complextype. What might be the reason. KIndly suggest. Below is the code snippet
[DataContract]
public class GetDetailsFromCardNumberResponseBody
{
public GetDetailsFromCardNumberResponseBody()
{
}
public GetDetailsFromCardNumberResponseBody
(PatronAccountCardValidation GetDetailsFromCardNumberResult)
{
this.GetDetailsFromCardNumberResult = GetDetailsFromCardNumberResult;
}
[DataMember]
public PatronAccountCardValidation GetDetailsFromCardNumberResult { get; set; }
}
[DataContract(Name="PatronAccountCardValidation")]
public class PatronAccountCardValidation
{
[DataMember]
public Patron Patron { get; set; }
[DataMember]
public Card Card { get; set; }
[DataMember]
public string BonusDollarLocal { get; set; }
[DataMember]
public string BonusDollarRemote { get; set; }
[DataMember]
public bool Valid { get; set; }
[DataMember]
public string MessageText { get; set; }
}
Check the parameter PatronAccountCardValidation.
Check property Card. It is causing an issue. Please help.
Error received:
An unhandled exception of type
'System.ServiceModel.CommunicationException' occurred in mscorlib.dll
Additional information: An error occurred while receiving the HTTP
response to localhost:9090/DoorAccessAndVendingMachineService. This
could be due to the service endpoint binding not using the HTTP
protocol. This could also be due to an HTTP request context being
aborted by the server (possibly due to the service shutting down). See
server logs for more details
Have you consider to apply Data Contract Know types? It allows you to specify, in advance, the types that should be included for consideration during deserialization. And by default during deserialization, an uninitialized object is first created, without calling any constructors on the type. Then all data members are deserialized. See more details here.
[DataContract]
[KnownType(typeof(PatronAccountCardValidation))]
public class GetDetailsFromCardNumberResponseBody
{
public GetDetailsFromCardNumberResponseBody()
{
}
public GetDetailsFromCardNumberResponseBody
(PatronAccountCardValidation GetDetailsFromCardNumberResult)
{
this.GetDetailsFromCardNumberResult = GetDetailsFromCardNumberResult;
}
[DataMember]
public PatronAccountCardValidation GetDetailsFromCardNumberResult { get; set; }
}
[KnownType(typeof(Card))]
[KnownType(typeof(Patron))]
[DataContract(Name="PatronAccountCardValidation")]
public class PatronAccountCardValidation
{
[DataMember]
public Patron Patron { get; set; }
[DataMember]
public Card Card { get; set; }
[DataMember]
public string BonusDollarLocal { get; set; }
[DataMember]
public string BonusDollarRemote { get; set; }
[DataMember]
public bool Valid { get; set; }
[DataMember]
public string MessageText { get; set; }
}

Consuming WCF Service with DataContract

I do have a simple WCF service in which If I put the method with simple Data Type then I can access that service in the MVC project which is in same Solution. But if I change the Data Type of the Service method even to array or list of string or any other simple Data Type, I cannot access the service. Do I need to make any config changes.
[DataContract]
public class Property
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string PropertyPost { get; set; }
[DataMember]
public string PropertyType { get; set; }
[DataMember]
public string DealType { get; set; }
[DataMember]
public string Department { get; set; }
[DataMember]
public string ProjectName { get; set; }
}
I actually want to return the List from the WCF service for which I have created the Datacontract, but it is not working even with simple List Type.
Do we need to specify anything in Service like WebInvoke?
Can any one help?

MVC4 Mailgun delivered webhook

I'm having an issue making use of the Mailgun delivered webhook, it can be found here: http://documentation.mailgun.net/user_manual.html#events-webhooks, look for "Delivered Event Webhook"
I am unable to reference Request.Params["Message-Id"] unless I modify the app's requestValidationMode to 2.0
I do get the potentially unsafe error when trying to reference this field without requestValidationMode = 2.0. The contents of the field are: <20130203200110.12345.12345#mydomain.mailgun.org>. I've also tried to declare a model to take advantage of auto model binding. My model looks like this:
public class MailgunDeliveredEvent
{
public string Id { get; set; }
public string Event { get; set; }
public string Recipient { get; set; }
public string Domain { get; set; }
[AllowHtml]
[JsonProperty(PropertyName="Message-Id")]
public object MessageId { get; set; }
public int Timestamp { get; set; }
public string Token { get; set; }
public string Signature { get; set; }
}
When I attempt to reference the MessageId field it returns null. I've tried to add
[Bind(Exclude="message-headers")]
As I'm not interested in that field.
In the Controller, I've set
[ValidateInput(false)]
I can't seem to get the Message-Id field back. Any help?
I seem to have got it working, in case anyone runs into the same issue...
I added a new model binder as referenced here:
Asp.Net MVC 2 - Bind a model's property to a different named value
I then changed my model like so:
[ModelBinder(typeof(DefaultModelBinderEx))]
public class MailgunDeliveredEvent
{
public string Id { get; set; }
public string Event { get; set; }
public string Recipient { get; set; }
public string Domain { get; set; }
[BindAlias("Message-Id")]
public string MessageId { get; set; }
public int Timestamp { get; set; }
public string Token { get; set; }
public string Signature { get; set; }
}
And all seems to work, I didn't need to call
[ValidateInput(false)]
on the controller either.
Hope that helps someone.

Interface segregation in WCF for JSON

I am a newbie in WCF. I was wondering if we can retrive properties from base interface in the REST output.
Please consider following structure. Product includes IVenueView not Venue. Is it possible to only have Venue.Id in Product JSON response?
[DataContract]
public class Product {
[DataMember]
public Guid? Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public IVenueView Venue { get; set; }
}
public interface IVenueView {
[DataMember]
Guid? Id { get; set; }
}
[DataContract]
public class Venue : IVenueView
{
[DataMember]
public Guid? Id { get; set; }
[DataMember]
public string Name { get; set; }
}
Data contracts are all about data - interfaces define behaviors, so they don't really mix up well. The data contract that you have likely will not work (because the serializer doesn't "know" about the Venue type (it only knows about IVenueView), it won't be able to serialize / deserialize instances of Product.
No it is not possible because serialization and deserialization works with the implementation (actual data) not with interfaces. Moreover for pure serialization you will have to use something like:
[DataContract]
[KnownType(typeof(Venue))]
public class Product
{
[DataMember]
public Guid? Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public IVenueView Venue { get; set; }
}