Passing Lambda Expression condition as parameter in the WCF - c#

My ASP.NET MVC application has multiple conditions to fetch the record from the database for different scenarios. In order to implement the same in the WCF with multiple functions for different conditions. I tried to implement the below code,
ASP.NET MVC code:
IEnumerable<WCF.UserApplicationDetails> Search_UserApplicationDetails =
shareGatewayClient.GetUserApplicationDetailsByCondition(x => (x.FirstName == Name)).ToList();
WCF code - basic http binding endpoint:
public IEnumerable<UserApplicationDetails> GetUserApplicationDetailsByCondition(Func<UserApplicationDetails, bool> condition)
{
DBContext databaseEntities = new DBContext();
return databaseEntities.UserApplicationDetails.Where(condition).ToList();
}
It was working properly in the same application, but in WCF I'm getting this error:
Type 'System.DelegateSerializationHolder+DelegateEntry' with data contract name 'DelegateSerializationHolder.DelegateEntry:http://schemas.datacontract.org/2004/07/System' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer 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 the serializer.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Is there any alternative to achieve this?

Related

Devart Error when I return database object with IActionResult

I am trying to return the database object that I get from my service in an IActionResult API Call (c# web API project). Whenever I attempt to do that I get this error:
System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.
Here is my API code that is throwing this:
[HttpGet]
[Route("content")]
public IActionResult GetAllContent()
{
try
{
List<Content> allContent = _contentService.GetAll();
return Ok(allContent);
}
catch (Exception ex)
{
//Log something here
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
I could easily mitigate the error by parsing through the content and creating a dynamic object, but I find it annoying to do whenever I want to return a database object when I'm using the Devart Database Context.
Edit:
Further piece of the error message is this:
$.PortalCodeMappings.Content.PortalCodeMappings.Content.PortalCodeMappings.Content.PortalCodeMappings.Content.PortalCodeMappings.Content.PortalCodeMappings.Content.PortalCodeMappings.Content.PortalCodeMappings.Content.PortalCodeMappings.Content.PortalCodeMappings.Content.ContentId.
And I understand the circular reference here, is there a way to tell devart I only want the Content section of this without doing something like this:
allContent.Select(x => new { ... });
Edit: I am using Devart Entity Devloper to generate my models and the dbcontext. I do not use Visual Studio or any IDE.
There are two alternative ways to solve the issue:
Use System.Text.Json (de)serialization
Add JsonIgnoreAttribute to one of the navigation property ends
You can add a custom attribute via the interface of Entity Developer this way:
a) navigate to Model > Settings > Attributes > select the System.Text.Json.dll assembly and make sure that JsonIgnoreAttribute is checked in the window below, press OK
b) select JsonIgnoreAttribute in the Attributes collection of a particular class property

WCF error when querying using LINQ to Objects

Please excuse me if this is a duplicate question - I have searched but have not found anything that explains my problem.
I created an ASP.NET website. I have 3 layers - Data Access, Business, Presentation. I used shared entities throughout using Entity Framework.
Presentation: UI
Business: WCF Service
Data Access: code to connect to DB (contains the EF context, connection string)
Entities: .edmx - EF Entities. These are shared throughout all 3 layers.
I have come upon some odd behavior in the WCF service which I cannot understand. My original code had a function in the DAL which queried the db for all customers, and returned a List. The service than further queried this list based on what the UI requested and returned a List to the Presentation Layer.
DAL:
public List<Customer> GetCustomers()
{
List<Customer> custList= new List<Customer>();
try
{
using (NorthWindsEntities context = new NorthWindsEntities(connectionString))
{
custList= context.Customers
.Include("Orders")
.Include("OrderDetails")
.ToList();
}
return custList;
}
catch (Exception ex)
{
//handle exception
return custList;
}
}
WCF:
public List<Customer> GetCustomersByState(string state)
{
contextManager contextDAL = new contextManager();
List<Customer> custList = contextDAL.GetCustomers()
.Where(c => c.State == state)
.ToList();
return custList;
}
When I debugged the code, eveything worked fine, but when the service tried to return the custList to the client, I got this error: An error occurred while receiving the HTTP response to localhost/WCF/MyService. 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.
I changed my DAL to inclued the entire query and my WCF Service to this:
public List<customer> GetCustomersByState(string state)
{
contextManager contextDAL = new contextManager();
List<Customer> custList = contextDAL.GetCustomers(state)
return custList;
}
This worked fine. I also tried to put the entire query in the service (the service connected directly to the context and got the list) and that worked fine as well.
So basically, my question is, why can't the WCF service return a list of objetcs that were queried using Linq to Objects (the DAL returns a List of customer so all further querying is linq to objects). It works fine using Linq to Entities (with all the code in the service) and it works fine with no querying at all - just getting a list and returning it.
I'm sorry for the lengthy post, I tried to include all necessary details...Thanks!
After much trial and error, I have found that it is not a querying issue, it is a size issue. Though the WCF service was filtering my data to only return a few records, I guess it retained some sort of reference to the rest of the data because it errored with too much data. If I do a partial filter on the DAL and then continue to filter on WCF layer, coming out the same amount of records as I originally tried to return, it returns the list without a problem.
I cannot explain why this happens, I don't know much about WCF, just explaining what I did to get around it in case anyone else has this problem.

WCF Underlying Connection Error while returning DataTable

I created the webservices method that returns a dataTable.
However, I am getting the error:
The underlying connection was closed: The connection was closed unexpectedly
This is my method in the IWS file
[ServiceContract]
public interface IWsBabyCare
{
[OperationContract]
DataTable GetPurchaseOrderDetails();
[OperationContract]
DataTable GetPurchaseOrders(int PODID);
}
And this is my method in the WS file
public DataTable GetPurchaseOrderDetails()
{
DataTable POD = new DataTable("POD");
PurchaseOrderBLL prodBLL = new PurchaseOrderBLL();
POD = prodBLL.GetPOD();
POD.TableName = "POD";
return POD;
}
public DataTable GetPurchaseOrders(int PODID)
{
PurchaseOrderBLL prodBLL = new PurchaseOrderBLL();
return prodBLL.GetPurchaseOrders(PODID);
}
I read online that adding a name to the datatable will help but I'll just be returning an empty dataTable.
The exception you are getting can have about 500 different causes.
All we can really tell at the moment is that you have a service interface defining some operations and that your have implemented the operations.
We know nothing about the way the service is being hosted (console, IIS?), or the WCF configuration specified on the service and client. You need to supply this information in your question.
Additionally your service operations specify a return type of DataTable which is a big web service no-no. You should be passing types which define exactly the data you need (for example, if your database table contain apples, you should pass a return type of List<Apple>.
This is how I suggest you should proceed.
Create a console-based service and client project.
Create a single service operation which returns some primitive type like string.
Make all code as simple as possible. You should be able to get this working with less than 10 lines of code and about 10 lines of xml config on each of the service and client.
Once you have managed to get this working then gradually add new operations and more complex return types.

MVC Deserialization Error

Okay. This is my company's customer portal, it's an MVC 2 project. We have a back end SAP system that the portal draws data from. But it does not directly hit SAP, it sends an xml request to a VB app that gets the data and sends it back in an xml response. There is an interface IRequest that all the various requests implement examples would be CustomerNumberRequest, CompanyNameRequest, etc. These all implement the method ToXml which as the name suggests simply builds xml to send. All of the existing requests work fine. (Let me preface this by saying that I inherited this project and the guy who wrote it is no longer with us) I am now trying to send a request to get the Rep Groups from SAP. I basically copied one of the other requests verbatim, making the necessary tweaks to send the appropriate request. But it keeps failing with error messages that I don't understand:
The formatter threw an exception while
trying to deserialize the message:
There was an error while trying to
deserialize parameter
http://tempuri.org/:request. The
InnerException message was 'The
deserializer cannot load the type to
deserialize because type
'XXXXX.CustomerPortal.Domain.RepGroupRequest'
could not be found in assembly
'XXXXX.CustomerPortal.Domain,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'. Check that the
type being serialized has the same
contract as the type being
deserialized and the same assembly is
used.'. Please see InnerException for
more details.
This error happens right at _communicationService.ProcessRequest(request); (shown below) It does not enter the ProcessRequest method it just tries to create a NetDataContractSerializer here:
public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
{
return new NetDataContractSerializer();
}
and then it dies. These are the methods being called:
private void PopulateRepGroups()
{
List<string> repGroups = new List<string>();
RepGroupRequest request = new RepGroupRequest();
foreach (RepGroup repGroup in _repService.GetRepGroups(request))
repGroups.Add(repGroup.RepGroupName);
ViewData["RepGroups"] = new SelectList(repGroups);
}
public List<RepGroup> GetRepGroups(RepGroupRequest request)
{
string response = _communicationService.ProcessRequest(request);
return RepGroupResponseFactory.GetRepGroupResponse(response);
}
Can anybody tell me what this error message is telling me? It says the type cannot be found but the type should be IRequest (that's what it says when the CreateSerializer is hit) which is used all over this. I'm clearly lost, please help!
Quoting your exception
Check that the type being serialized has the same contract as the type being deserialized and the same assembly is used
Check the version of the library on both ends that CustomerPortal.Domain.RepGroupRequest resides in to make sure they are the same version exactly.

Problem with c# webservice, referencing a method and a type

I have run into a bit of a problem, well not sure if it is a problem, but would like some advice.
I have developed a c# webservice in vs2010 and when I debug the service i get this error in my browser
The XML element 'VoucherResponse' from namespace 'http://test.org/' references a method and a type. Change the method's message name using WebMethodAttribute or change the type's root element using the XmlRootAttribute.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The XML element 'VoucherResponse' from namespace 'test.org' references a method and a type. Change the method's message name using WebMethodAttribute or change the type's root element using the XmlRootAttribute.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Now looking at my code in at the actual class "VoucherResponse" i have,
public class VoucherResponse : AResponse
{
public Voucher Voucher { get; set; }
}
And the Voucher object looks like this
public class Voucher
{
public string PIN { get; set; }
public string Serial { get; set; }
public string Batch { get; set; }
}
Now in one of my web methods I return the VoucherResponse and I am assuming that this error occurs when it is reflected through and checked.
Has anyone had a similar problem with this before, or can anyone give me some advice on this?
Thanks
I found another case that raises the error! Here's my code:
[WebMethod]
public CheckUpdateResponse CheckUpdate()
{
...
}
Ok, let me explain: CheckUpdateResponse is a structure I defined in my code, CheckUpdate() is a method. So, in the WSDL .NET add automatically a Response suffix to the method name CheckUpdate.
Et voilĂ : it finds a duplicate element and gives the error "Change the method's message name using WebMethodAttribute..."
Solution? I renamed the returned type from CheckUpdateResponse to CheckUpdateResult and now everything works fine!
I hope this will help someone! I lost a lot of time on this...
Apparently, SOAP cannot handle methods that have the same name as their return type.
You can fix it by reading the error, and acting accordingly:
public class VoucherResponse
{
[WebMethod(MessageName="TheVoucher")]
public Voucher Voucher{get; set;}
}
I had the same issue, but in my case; the application that I developed is web service client, so I don't have control on changing the WSDL\Schema.
The problem was that I had one web service with 17 operations, all of them are returning the same complex type, I got the mentioned error due to deserialization of the return type, because .Net is wrapping the return type for each output, and the serializer is throwing error:
The XML element 'XYZ' from namespace 'ABC' references a method and a type. Change the method's message name using WebMethodAttribute or change the type's root element using the XmlRootAttribute.
Solution:
I opened Reference.cs file, removed all wappered return type generated classes, and kept only one, then changed its class name to be generic, not related to the operation, it worked for me.

Categories