WCF REST Starter Kit not filling base class members on POST - c#

I have a WCF REST Starter Kit service. The type handled by the service is a subclass of a base class. For POST requests, the base class members are not correctly populated.
The class hierarchy looks like this:
[DataContract]
public class BaseTreeItem
{
[DataMember]
public String Id { get; set; }
[DataMember]
public String Description { get; set; }
}
[DataContract]
public class Discipline : BaseTreeItem
{
...
}
The service definition looks like:
[WebHelp(Comment = "Retrieve a Discipline")]
[WebGet(UriTemplate = "discipline?id={id}")]
[OperationContract]
public Discipline getDiscipline(String id)
{
...
}
[WebHelp(Comment = "Create/Update/Delete a Discipline")]
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "discipline")]
public WCF_Result DisciplineMaintenance(Discipline discipline)
{
...
}
Problem: While the GET works fine (returns the base class Id and Description), the POST does not populate Id and Description even though the XML contains the fields.
Sample XML:
<?xml version="1.0" encoding="utf-8"?>
<Discipline xmlns="http://schemas.datacontract.org/2004/07/xxx.yyy.zzz">
<DeleteFlag>7</DeleteFlag>
<Description>2</Description>
<Id>5</Id>
<DisciplineName>1</DisciplineName>
<DisciplineOwnerId>4</DisciplineOwnerId>
<DisciplineOwnerLoginName>3</DisciplineOwnerLoginName>
</Discipline>
Thanks for any assistance.

I could not solve the problem using a DataContractSerializer. I switched to using the XMLSerializerFormat and everything worked fine. In fact, the capabilities of the XMLSerializer are so much better that for purely XML work, it is probably better to use the XMLSerializer in all cases.

Related

Json.Net serialize/deserialize Class Name attribute C#

Sorry for the (maybe) trivial question but, I'm trying to consume a web service where the entities and my data model classes are named different.
I want to keep my model .Net Class name and use a Json Attribute name to map, serializer/deserializer, with the corresponding web service entity.
For example:
Web Service Entity:
"People"
My Model Class:
"Employee"
What I've already do:
[JsonObject(Title="People")]
public class Employee
{
[JsonProperty("DifferentPropertyName")]
string propertyName1 { get; set; }
}
But the json serializer/Deserializer continues to use the .Net class name and I need to set the jsonObject Title.
There is a way to achieve it?
EDIT
I'm working on a Xamarin Forms app, using Simple.OData.Client to consume an OData Service
Thanks
DataContractAttribute may be your solution.
public class RichFilter
{
public Trolo item { get; set; }
}
[DataContract(Name = "item")]
public class Trolo
{
public string connector { get; set; }
}
If you serialize a RichFilter object, here is the output :
{"item":{"connector":"AND"}}

WCF Webservice not seeing parameter

I have a WCF webservice that validates XML data using a file path as a parameter. However when I call it it totally ignores the parameter.
Webservice:
namespace MyApp.Validation.WebServices
{
public class ValidateSurveyData : IValidateSurveyData
{
private ValidateSurveyDataResponse response = new ValidateSurveyDataResponse();
public ValidateSurveyDataResponse ValidateXMLSurveyData(string XMLFile)
{
//Validation Code
return response;
}
}
}
Interface:
namespace MyApp.Validation.WebServices
{
[ServiceContract]
public interface IValidateSurveyData
{
[OperationContract]
ValidateSurveyDataResponse ValidateXMLSurveyData(string XMLFile);
}
[DataContract]
public class ValidateSurveyDataResponse
{
[DataMember]
[Description("XML Data Validation Errors")]
public List<SurveyValidationError> DataValidationErrors { get; set; }
public ValidateSurveyDataResponse()
{
DataValidationErrors = new List<SurveyValidationError>();
}
}
}
In the Test Client:
When I debug the code XMLFile is always null. In desperation I have tried C:\MyFile.xml, #C:\MyFile.xml, #"C:\MyFile.xml", "C:\MyFile.xml" as parameters but I always get the same, XMLFile is null. What am I missing?
Update
Ok feeling slightly embarrassed! the problem was not with the service at all its with the data I am passing. C:\XmlFile.xml give a null parameter but C:\\XmlFile.xml gives correct results.
I think you are missing the parameter in ValidateSurveyDataResponse() method, the signature should be like this
public ValidateSurveyDataResponse(string XMLFile)
add following line above ValidateXMLSurveyData function in Interface.
[WebInvoke(Method = "POST", UriTemplate = "ValidateXMLSurveyData?value={XMLFile}")]
sample call
http://localhost:5647/ValidateSurveyData.svc/ValidateXMLSurveyData?value="C:\MyFile.xml"

How to get the request object from wcf message?

I have a WCf service with Contracts shown below.
[MessageContract]
public class ServiceRequest
{
[MessageBodyMember]
public int RequestId { get; set; }
[MessageBodyMember]
public OrderDetails OrderDetails { get; set; }
}
[DataContract]
public class OrderDetails
{
[IsLogRequired]
public int OrderId { get; set; }
[IsLogRequired]
public int Quantity { get; set; }
public string CustomerName { get; set; }
}
[IsLogRequired] is custom Attribute.
We need to get all properties in the request which have "[IsLogRequired]" attribute when the request is received. We want to do it as generic solution so that it can be plugged into all services.
We thought of using "MessageInspector" to do this implementing "IDispatchMessageInspector".
How do i get the actual request object from "System.ServiceModel.Channels.Message" parameter of IDispatchMessageInspector.AfterReceiveRequest() method?
Please correct me if i am using a wrong interface or wrong method. Any other solution to this?
I am assuming that "[IsLogRequired] is custom property." means a custom attribute...
Simple answer is that there is no solution to transfer custom attributes that are decorating the data contract as you described it.
Data contracts should be pure and not encumbered by business logic. The know how about the what should be done with various fields belongs to a service implementation.
Possible approach could look like this:
public class OrderService : IOrderService
{
private void ProcessOrder(Order order)
{
var ra = new AuditMetadataResourceAccess();
MethodInfo[] fieldsToLog = ra.GetLoggingFields(typeof(OrderDetal));
if (fieldsToLog.Any())
{
var logger = new LogingEngine();
logger.Log(fieldsToLog, order.OrderDetails);
}
}
}
You could move this implementation inside message inspector or operation invoker. Carlos Figueira has extensive description of each WCF extensibility point.
"How do i get the actual request object from "System.ServiceModel.Channels.Message" parameter of IDispatchMessageInspector.AfterReceiveRequest() method?"
I am assuming you are referring to Web request. WebOperationContext.Current but you need to have ASP.NET Compatibility Mode turned on.

How to create a URI template in WCF?

I'm new to wcf services development. I have the following problem:
I'm creating wcf-service with URI template like this:
[OperationContract, WebGet(UriTemplate = "/EmpDetails/command/?command=SaveDetails&id={id}&data{empid:{EmpID},EmpName:{EmpName},EmpAge:{EmpAge}}"
How can I access these values to save details?
another thing is i want this URL to be used to save details.
http://12.154.21.23:8888/EmpDetails/command/?command=SaveDetails&data={empid:Test,EmpName:TestName,EmpAge:26}
You need to create a class somewhere in service:
[DataContract]
public class Data
{
[DataMember]
public int EmpID {get;set;}
[DataMember]
public string EmpName{get;set;}
[DataMember]
public string EmpAge {get;set;}
}
Next, add this to your wcf service interface:
[OperationContract]
[WebGet(UriTemplate = "/EmpDetails/command/?command=SaveDetails&id={id}&data{EmpID:{EmpID},EmpName:{EmpName},EmpAge:{EmpAge}}")]
void SaveDetails(int id, Data data);
and finally, add code below to class implementing wcf service interface:
public void SaveDetails(int id, Data data)
{
//do smt
}

How to rename xml serialization on web service?

I have a web service written in C# and on this project I added a model called ProjectDTO. I have a web service that returns some objects of this class and I would like that my web service return a node called Project in my xml result and not ProjectDTO, how can I do this?
I tried to add some attributes on my ProjectDTO class like XmlRoot, XmlElement but it does not work.
Thanks
Edits
public class ProjectDTO {
//some properties
}
my web service (.asmx file.. it's a simple webservice from asp.net 2.0) method:
[WebMethod]
public ProjectDTO[] GetProjects();
My output xml:
<ArrayOfProjectDTO ...>
<ProjectDTO>
<Id>...</Id>
<Nome>...</Nome>
</ProjectDTO>
</ArrayOfProjectDTO>
I would like to rename all places where is 'ProjectDTO' to 'Project' on this xml output, is that possible?
Thanks
I knew I had programmed something similar before, it just took me a while to remember.
Here is the format you're looking for:
public class WebService : System.Web.Services.WebService {
[WebMethod]
[return: XmlRoot(ElementName = "Projects")]
public ProjectDTO[] HelloWorld()
{
return new ProjectDTO[] { new ProjectDTO(), new ProjectDTO(), new ProjectDTO(), };
}
}
[XmlType(TypeName = "Project")]
public class ProjectDTO
{
public string Blah { get; set; }
}
The key is the XmlRootAttribute and the XmlTypeAttribute.

Categories