Return class instance using WCF service - wcf

I am not sure did anyone had this type of problem. Can you please give some clues with the approach i am trying in WCF.
I have say 100 dlls registered in server GAC. When my WCF client invokes with the name of the dll, WCF service should look in to the GAC using reflection and create instance for that and send it back to the client. I dont know anything about 100 dlls and all those are POCO objets.
I tried and and was getting errors at serialization of datacotract. Below is my datacontract.
[DataContract]
public class RDSContract
{
private Type _oType;
private Object _oObject;
private string _strOutput;
[DataMember]
public Type TypeProp { get; set; }
[DataMember]
public Object ObjectProp { get; set; }
[DataMember]
public string StrOutput { get { return _strOutput + " test"; } set { _strOutput = value; } }
}

Related

How to pass List<ABC> to WCF test client

I have DataContract as below
[DataContract]
public class Test
{
public List<Validation> val { get; set; }
}
and my OperationContract as below
public bool TestValidation(Test t, out string message)
{
return ValidationUtility.ValidateFields(t.val, out message);
}
I am not getting how to set value for Test.val on WCF Test Client
Firstly, it seems like you're missing the DataMember attribute for your list.
[DataContract]
public class Test {
[DataMember]
public List <Validation> val { get; set; }
}
Also, ensure that the DataContract and DataMember attributes for Validation are set up properly as well. Then restart your WCF Test Client and try calling the service again.
Expand the objvalidation part on the Name column. A + sign should appear next to the request parameter name. You can then add elements and fill out their properties (Value column) by expanding each individual element you've added.

Return Entity Framework objects over WCF

We have a problem concerning Entity Framework objects and sending them through WCF.
We have a database, and Entity Framework created classes from that database, a 'Wallet' class in this particular situation.
We try to transfer a Wallet using this code:
public Wallet getWallet()
{
Wallet w = new Wallet();
w.name = "myname";
w.walletID = 123;
return w;
}
We need to transfer that Wallet class, but it won't work, we always encounter the same exception:
"An error occurred while receiving the HTTP response to localhost:8860/ComplementaryCoins.svc. 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."
We searched on the internet, and there is a possibility that the error is due to the need of serialization of Entity Framework-objects.
We have absolutely no idea if this could be the case, and if this is the case, how to solve it.
Our DataContract looks like this (very simple):
[DataContract]
public partial class Wallet
{
[DataMember]
public int getwalletID { get { return walletID; } }
[DataMember]
public string getname { get { return name; } }
}
Does anyone ever encountered this problem?
EDIT: Our Entity Framework created class looks like this:
namespace ComplementaryCoins
{
using System;
using System.Collections.Generic;
public partial class Wallet
{
public Wallet()
{
this.Transaction = new HashSet<Transaction>();
this.Transaction1 = new HashSet<Transaction>();
this.User_Wallet = new HashSet<User_Wallet>();
this.Wallet_Item = new HashSet<Wallet_Item>();
}
public int walletID { get; set; }
public string name { get; set; }
public virtual ICollection<Transaction> Transaction { get; set; }
public virtual ICollection<Transaction> Transaction1 { get; set; }
public virtual ICollection<User_Wallet> User_Wallet { get; set; }
public virtual ICollection<Wallet_Item> Wallet_Item { get; set; }
}
}
Thanks for helping us.
I had the same problem some time ago and the solution for this was:
The entity framework was returning a serialized class instead of normal class.
eg. Wallet_asfawfklnaewfklawlfkawlfjlwfejlkef instead of Wallet
To solve that you can add this code:
base.Configuration.ProxyCreationEnabled = false;
in your Context file.
Since the context file is auto generated you can add it in the Context.tt
In the Context.tt file it can be added around lines 55-65:
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
base.Configuration.ProxyCreationEnabled = false;
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
this.Configuration.LazyLoadingEnabled = false;
<#
Try specifying a setter for the properties, something like this :
[DataContract]
public partial class Wallet
{
[DataMember]
public int getwalletID { get { return walletID; } set { } }
[DataMember]
public string getname { get { return name; } set { } }
}
If it still doesn't work, you may consider creating an intermediate POCO class for this purpose, and use mapper library like AutoMapper or ValueInjecter to transfer the data from the EF objects.
The POCO class should have same properties as your EF class :
[DataContract]
public class WalletDTO
{
[DataMember]
public int walletID { get; set; }
[DataMember]
public string name { get; set; }
}
And modify your method to return this class instead :
public WalletDTO getWallet()
{
Wallet w = new Wallet(); // or get it from db using EF
var dto = new WalletDTO();
//assuming we are using ValueInjecter, this code below will transfer all matched properties from w to dto
dto.InjectFrom(w);
return dto;
}
Are you trying to recieve a IEnumerable<Wallets>? If - yes, please modify your server class that returns the IEnumerable by adding .ToArray() method

WCF: How to create an object as a parameter of message on client side

I have WCF service that uses raw messages (Message class).
1) Service side:
[DataContract]
public class Person
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
[ServiceContract]
public interface ITestService
{
[OperationContract(Action = TestService.RequestAction3)]
void AddNewPerson(Message newPerson);
public void AddNewPerson(Message newPerson)
{
Person personToAdd = newPerson.GetBody<Person>();
Employees.Persons.Add(personToAdd);
}
2) Client side:
TestServiceClient client = new TestServiceClient();
String RequestAction3 = "http://localhost:4249/Message_RequestAction3";
TestService.Person person = new TestService.Person
{
Id = 6,
FirstName = "Aleksey",
LastName = "Alekseyev"
};
Message request3 = Message.CreateMessage(MessageVersion.Default, RequestAction3, person);
string soapRequest = request3.ToString();
client.AddNewPerson(request3);
What's the problem here? I have Person class (data contract) on service side that is placed in TestService namespace: TestService.Person. Everything is fine on service side. But after I added service reference to client side by using "Add Service Reference..." option in VS2008, there's no such a type (TestService.Person) on client side. What I did to resolve this issue? I've simply copied the file with original data contract (TestService.Person) on client side, created object of Person type and passed it to the service method.
My question is - did I do it in correct way or there is another way to do this?
Thank you in advance.
Goran
Because Person class is not exposed in none of your service contracts their information is not shared via service metadata. That's why you get an error on the client side. If you copy the classes to your client with the same namespace that will do.
However a better solution is to place Person class in another assembly and reference this assembly from your client.

Passing List<T> as parameter to WCF service operation

I have a WCF operation contract which looks like this:
public void SavePersons(List<Person> list, bool IsSelected)
{
}
I am passing it a strongly typed list of Person objects (List<Person>) in my client. However, I am getting a bad request 400 message when calling the service. What am I doing wrong?
May I suggest you create you create a contract to encapsulate the parameters like so:
public void SavePersons(PersonCollectionContract Request)
{
...
}
[DataContract]
public class PersonCollectionContract
{
[DataContract]
public List<Person> People { get; set; }
[DataContract]
public bool IsSelected { get; set; }
}
[DataContract]
public class Person
{
...
}
I was facing a similar problem in passing a List<Health> of class Health type as a parameter to a wcf service method. I created a data contract in wcf service as below:
[DataContract]
public class Health
{
...
}
Defined a method in wcf service class such as:
public string GetData(List<Health> healthValues)
In my client application, while configuring/updating the service, I followed these steps:
Add/Update URL
Under Data Type (in Advanced), selected option, Collection type: System.Collection.Generic.List
And finally, I created a list and added the code in client as follows:
List<WcfService.Health> listHealth = new List<WcfService.Health>();
WcfService.Health h = new WcfService.Health();
.
.
listHealth.Add(h);
WcfService.Service1Client s = new WcfService.Service1Client();
string str = s.GetData(listHealth);
This solved my purpose and I was able to send the data as a list through wcf service.

Silverlight 2, Cannot Update Service Ref with New Service

In Silverlight 2, I am attempting to add a new service which will return an object containing two lists from the WCF Service to the Silverlight app on the client. The svc and interface file already contain two contracts which work and are being used. After adding the new service, I click on the "Update Service Reference" option in the Silverlight app and receive the error:
There was an error downloading "http://localhost:3005/CMS.svc" ...
Metadata contains a reference that cannot be resolved "http://localhost:3005/CMS.svc" ...The client and service bindings may be mismatched...
Even though the web service project rebuilds without error, I think there must be something wrong with the way I have defined the service in the web service project, because when I remove the new service, the remaining two services are updated OK, and if I add a new service which I know is OK, the service reference will update OK. So I don t think it is a problem of endpoints, or the port number, etc.
The new service is supposed to return an object which contains two lists.
Here is the code:
In the interface file:
namespace CMSSilverlight.Web
{
// NOTE: If you change the interface name "ICMS" here, you must also update the reference to "ICMS" in Web.config.
[ServiceContract]
public interface ICMS
{
[OperationContract]
POCollection GetPOCollection(String s);
}
[DataContract]
public class POCollection
{
[DataMember]
public IList<Employee> em;
[DataMember]
public IList<School> sc;
}
public class Employee
{
public string EmpID { get; set; }
public string EmpName { get; set; }
public Employee(string empID, string empName)
{
this.EmpID = empID;
this.EmpName = empName;
}
}
public class School
{
public string SchID { get; set; }
public string SchName { get; set; }
public School(string schID, string schName)
{
this.SchID = schID;
this.SchName = schName;
}
}
}
In the service file:
namespace CMSSilverlight.Web
{
{
public POCollection GetPOCollection(String sParam)
{
IList<Employee> empList = new List<Employee>();
for (int i = 0; i < 5; i++)
{
empList.Add(new Employee(i.ToString(), i.ToString() + " Emp Name"));
}
IList<School> schList = new List<School>();
for (int i = 0; i < 5; i++)
{
schList.Add(new School(i.ToString(), i.ToString() + " Sch Name"));
}
POCollection po = new POCollection()
{
em = empList,
sc = schList
};
return po;
}
}
}
James,
Many thanks - I should have though of that. At any rate below was the error. It was just a matter of adding the [DataContractAttribute] attribute to the Employee and School classes, and everything worked fine. This is a frustrating learning process, but it is nice when a solution is revealed.
An ExceptionDetail, likely created by `IncludeExceptionDetailInFaults=true`, whose value is:
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior
contract: http://tempuri.org/:ICMS ----> System.Runtime.Serialization.InvalidDataContractException: Type 'CMSSilverlight.Web.Employee' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.