Custom Collection null when passed through WCF Service - wcf

We have some custom collections such as this:
[Serializable]
public class OccupationCollection : Collection<Occupation>
{
}
We use these in objects like the following:
private OccupationCollection _occupations;
public OccupationCollection CurrentOccupations
{
get
{
if (this._occupations == null)
return new OccupationCollection();
else
return _occupations;
}
}
Now we are making a call to a WCF service, passing objects that contain these type of lists. The lists always end up being null in the service.
I'm pretty sure this has somthing to do with serialization or something like that.
What would the simplest solution that would require minimal changes to the existing objects to get this to work?

Have you hosted your service over HTTP?
If yes, can you use fiddler to check the HTTP traffic and confirm whether serialized version of the parameter is being sent across the wire? If yes, there can be a parameter mismatch in contract between server and client.
Also is the object holding OccupationCollection decorated with Serializable/DataContract attribute? If you have DataContract attribute, ensure that the properties that need to be serialized are marked with Datamember attribute.
More details out here..
http://blog.functionalfun.net/2009/09/if-your-wcf-service-is-unexpectedly.html

Related

vb.net receive json data in POST where key has forward slash

I have a restful web service that is receiving a POST with json data coming over. Here is the json sample with the third key/pair having a forward slash in the key name.
{
"_notes": "Test",
"_received": true,
"item/id": "8a69d38fba4c40d5a3d730807db87859"
}
Here is my Post method
Public Sub Post(value As Testing)
And here is the Testing Class definition
Public Class Testing
Public _notes As String
Public _received As Boolean
Public item/ID As String
End Class
I get a compiler error since I can't have the forward slash in the variable name. Is there a different way I'm supposed to be capturing the data on my side? Unfortunately I can't control the key name in the json.
Assuming you're using the .NET Web API framework's built-in de-serialization, you should spend some time learning about those serializers and how to control them. Here is a good introductory point in the documentation.
The built-in stuff uses JSON.NET, by default, for JSON serialization, which has a number of attributes which allow you to control it. The one you will be interested in for this problem is the JsonPropertyAttribute. For instance:
Public Class Testing
Public _notes As String
Public _received As Boolean
<JsonProperty("item/id")>
Public ItemID As String
End Class

ServiceStack implemente CRUD on UserAuth table generated by Authentication

I'm trying the built-in Authentication of ServiceStack. My approach is 'OrmLiteAuthRepository' so users' information are stored in Sql Server instead of the default in memory storage. I use Postman to test the endpoints.
My target is receiving user rows, updating user information, creating users, deleting an user row. Those are the endpoints I found in Postman after importing (I didn't create those endpoints):
GET 'http://localhost:47391/api/register',
PUT 'http://localhost:47391/api/json/reply/Register'
POST 'http://localhost:47391/api/json/reply/Register'
I tested POST, Sql Server automatically created the tables to store user data. And the data could be written into Sql Server so I have no problem with POST.
But with PUT, isn't it for updating the existing row? I append '/{id}' to the end. But it created a new row in the database instead of updating the existing one. How does it work?
With GET, I got no implementation error.
{
"ResponseStatus": {
"ErrorCode": "NotImplementedException",
"Message": "Could not find method named Get(Register) or Any(Register) on Service RegisterService",
"StackTrace": " at ServiceStack.Host.ServiceExec`1.Execute(IRequest request, Object instance, Object requestDto, String requestName)\r\n at ServiceStack.Host.ServiceRequestExec`2.Execute(IRequest requestContext, Object instance, Object request)\r\n at ServiceStack.Host.ServiceController.<>c__DisplayClass11.<>c__DisplayClass13.<RegisterServiceExecutor>b__10(IRequest reqCtx, Object req)\r\n at ServiceStack.Host.ServiceController.ManagedServiceExec(ServiceExecFn serviceExec, IService service, IRequest request, Object requestDto)\r\n at ServiceStack.Host.ServiceController.<>c__DisplayClass11.<RegisterServiceExecutor>b__f(IRequest requestContext, Object dto)\r\n at ServiceStack.Host.ServiceController.Execute(Object requestDto, IRequest req)\r\n at ServiceStack.HostContext.ExecuteService(Object request, IRequest httpReq)\r\n at ServiceStack.Host.RestHandler.GetResponse(IRequest request, Object requestDto)\r\n at ServiceStack.Host.RestHandler.ProcessRequestAsync(IRequest httpReq, IResponse httpRes, String operationName)"
}
}
How to implement it? I assume I consider the user a normal Web Service entity? and create 'UserService', and requests like:
[Route("/register")]
public class User : IReturn<UserResponse>
{
...
}
BUT there isn't a model class like 'User' due to the tables are created by ServiceStack itself, how to solve this?
Or is there something I am not aware of. Thanks.
The error message:
Could not find method named Get(Register) or Any(Register) on Service RegisterService
Is saying you're trying to call the built-in ServiceStack Register Service instead of your Service. But the Register Services isn't enabled by default, your AuthFeature likely explicitly enables it, either with:
Plugins.Add(new RegistrationFeature());
Or on the AuthFeature:
Plugins.Add(new AuthFeature(...) {
IncludeRegistrationService = true
});
If you don't want to enable ServiceStack's built-in Register Service you'll need to remove the registration where it's enabled.
If you instead want the Register Service registered at a different path, you can specify a different route with:
Plugins.Add(new RegistrationFeature {
AtRestPath = "/servicestack-register"
});

Silverlight enabled WCF Service and Entity Framework 504 issue

I'm building a Silverlight MVVM template and and am getting stuck with the WCF Service returning and Entity Object.
Here's what I did:
Using Entity Framework on the server side
Created a small test database with a couple of tables.
Created a WCF Service on the server side
I then created a small test method returning an integer.
On my client side, I added a service reference and I receive the integer result in my completed method successfully
then changed my test service method to return a "Person" object (which is an Entity from Entity Framework)
updated my service reference and then it doesn't work!
I then the return type to any basic CLR Type and it works again
I checked Fiddler and I get the following 504 error in my service response:
HTTP/1.1 504 Fiddler - Receive Failure
Content-Type: text/html; charset=UTF-8
Connection: close
Timestamp: 08:56:23.783
[Fiddler] ReadResponse() failed: The server did not return a response for this request.
After trying to figure this out, I came across WCF Trace Logging and found this error:
There was an error while trying to serialize parameter :BasicResult. The InnerException message was 'Type 'MVVMProject.Web.DataSource.Person' with data contract name 'Person:http://schemas.datacontract.org/2004/07/MVVMProject.Web.DataSource' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
I don't understand why this is so difficult? Must I set some property on my Entity to make it serializable? If I look at the Entity Framework's designer.cs file, I see a Serializable attribute on the Entity. Surely this means I can pass this via the WCF Service??? I don't understand this error, unfortunately...
Is it even possible to use Entity Framework with WCF Service?
Any help would be greatly appreciated.
I had same problem, it seams that the DataContractSerializer has a problem with the navigation properties of ef objects.
In my test project, I'm using the northwind database. I wanted to test the CodeFirst approach with the recommended DbContext.
The provided navigation properties are virtual and they are loading on demand, but the ef just return with the first level of the entity on navigation properties is filled.
On serializing the entity object the DataContractSerializer failed because the entity object is no longer bound to the DbContext and the serialization of the navigation properties failed.
This is happen when I try to consume a NW Employee object over my wcf service.
My soultion is to copy all data in a new object with the data contract attributes!
the service call:
public IEnumerable<EmployeeWcf> GetAll()
{
IEnumerable<EmployeeWcf> result = null;
result = from e in context.Employees.OrderBy( e => e.LastName )
select new EmployeeWcf
{
EmployeeId = e.EmployeeID,
Firstname = e.FirstName,
Lastname = e.LastName
};
return result;
}
the class:
[DataContract]
public class EmployeeWcf
{
[DataMember]
public int EmployeeId { get; set; }
[DataMember]
public string Firstname { get; set; }
[DataMember]
public string Lastname { get; set; }
}
This work but it seems to me that this is not a perfect solution.
I hope this helps you.

How to expose ErrorCode values?

I have web services written on WCF. I use request/response pattern and don't use FaultException. I return an error code in response contract as string. I need to expose error codes for clients in order to clients can handle exceptions. 
For example:
Var r = client.DoSomething();
Switch (r.ErrorCode)
{
Case ERROR_CODES.SomeCode:
//TODO:
}
Clients are WS-*, not only .Net.
UPDATE:
Sorry, my English is elementary. I've tried to explain in a different way.
When I use class File, I know that this class can throws some exceptions, for example, FileNotFoundException or DirectoryNotFoundException. If I create a File service How can I tell client that my service can returns "FileNotFound" or other error codes?
We generally try and use FaultContracts.
When we cannot we use a Response object that inherits from ResponseBase. ResponseBase has 2 properties, StatusCode and StatusMessage.
In your case ErrorCode, just add this property to your data contract.

WCF Unique ID for each service method call

I'm logging using log4net, and I want to log a id that is unique for each serice method call. I dont need it unique across service calls, just within a method call. Is there any built in id i can use in wcf? I don't want to manually create a guid or something at the start of the method call.
e.g.
wcfMethod(int x)
{
log("xxx");
somework
log("yyy");
}
private log(string message)
{
var frame = new StackFrame(1);
var method = frame.GetMethod();
var type = method.DeclaringType;
var name = method.Name;
var log = LogManager.GetLogger(type);
// LOG ID HERE
ThreadContext.Properties["MessageId"] = OperationContext.Current.IncomingMessageHeaders.MessageId; // SOMETHING HERE
}
I've tried OperationContext.Current.IncomingMessageHeaders.MessageId but thats always null.
I've read about wcf instance correlation but i don't need something that complicated (e.g. unique across different method calls).
Please if anyone can help that would be much apprieciated. Thanks in advance.
Plain SOAP or REST has no such identification included in messages. You must use some additional feature or transport protocol (for example MSMQ) supporting identifications of messages. In case of MessageId you have to use SOAP service with WS-Addressing and this information must be passed from client.