I am running a WCF service with these methods,
public string UploadInspections(Inspection[] inspections)
public string UploadInspection(Inspection inspection)
[DataContract]
public partial class Inspection
{
[DataMember]
public DateTime DateTime { get; set; }
[DataMember]
public int Id { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember]
public int Rating { get; set; }
}
From javascript I tried to call a POST on these methods using JSON. The JSON I had for the UploadInspection method was this,
{"Id":10,"Comment":"New One","Rating":3}
The UploadInspection method was called, but the inspection object was set to null.
I wasn't sure how to specify the Date field using JSON, and I thought that perhaps the parser didn't like JSON with no Date field. I removed the Date field from the Inspection object, but the same thing happened.
Also what should the JSON look like for the UploadInspections method which is an array? I had some JSON that I tried,
"inspections": [{"Id":10,"Comment":"New One","Rating":3}]
And also this,
[{"Id":10,"Comment":"New One","Rating":3}, {"Id":11,"Comment":"New Two","Rating":2}]
But I was getting this error,
OperationFormatter encountered an invalid Message body. Expected to find an attribute with name 'type' and value 'object'. Found value 'string'.
The problem is not what I thought it was, in my service definition it initially looked like this,
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
string UploadInspections(Inspection[] inspections);
Once I removed this,
BodyStyle = WebMessageBodyStyle.WrappedRequest
It worked!
Related
I am writing some REST service in WCF. This is my code.
[DataContract]
public class Result
{
[DataMember]
public String ErrorCode { get; set; }
[DataMember]
public Object Data { get; set; }
public Result(String msg, Object data)
{
this.ErrorCode = msg;
this.Data = data;
}
}
And I am calling this like this
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "login",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped
)]
Result Login(string emailAddress, string password);
In my Interface implementation class, I write this.
public Result Login(string emailAddress, string password)
{
return new Result("[0000]",null);
}
It gives me a JSON result like this
{"LoginResult":{"Data":null,"ErrorCode":"[0000]"}}
The weird thing is it has a LoginResult at the root,What I want is simply {"Data":null,"ErrorCode":"[0000]"} without this LoginResult header in JSON response. How can I fix this?
Thank you.
UPDATE
I just noticed that you have two parameters in your method
1. string emailAddress
2. string password
Please add these two parameters as properties in an object and use that object as the parameter.
Then apply the changes as given below. This will work for you.
Please change your the following line:-
BodyStyle = WebMessageBodyStyle.Wrapped
To
BodyStyle = WebMessageBodyStyle.Bare
Using Fiddler I post a JSON message to my WCF service. The service uses System.ServiceModel.Activation.WebServiceHostFactory
[OperationContract]
[WebInvoke
(UriTemplate = "/authenticate",
Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest
)]
String Authorise(String usernamePasswordJson);
When the POST is made, I am able to break into the code, but the parameter usernamePasswordJson is null. Why is this?
Note: Strangly when I set the BodyStyle to Bare, the post doesn't even get to the code for me to debug.
Here's the Fiddler Screen:
You declared your parameter as type String, so it is expecting a JSON string - and you're passing a JSON object to it.
To receive that request, you need to have a contract similar to the one below:
[ServiceContract]
public interface IMyInterface
{
[OperationContract]
[WebInvoke(UriTemplate = "/authenticate",
Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
String Authorise(UserNamePassword usernamePassword);
}
[DataContract]
public class UserNamePassword
{
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Password { get; set; }
}
How can I serialize an object to return a custom type?
//The response is null.
http://localhost:50604/GameService/Getbyid?id=1
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public MyClass GetById(int id)
[DataContract]
[KnownType(typeof(User))]
public partial class MyClass
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public int? CreatedBy { get; set; }
[DataMember]
public virtual User CreatedByUser { get; set; } //How will I serialize this?
}
You are missing UriTemplate for your operation so your Id is probably never passed in and your method works with default value = 0.
Try this:
[WebGet(UriTemplate="Getbyid?id={id}", ResponseFormat = WebMessageFormat.Json)]
public MyClass GetById(int id)
CreatedByUser will be serialized automatically if filled and if User is data contract as well.
I have a datacontract as defined below:
[DataContract(Namespace="",Name="community")]
public class Community {
[DataMember(Name="id")]
public int Id{get; set;}
[DataMember(Name="name")]
public string Name { get; set; }
[DataMember(Name="description")]
public string Description { get; set; }
}
and the service contract goes like this:
[OperationContract]
[WebGet(
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Xml,
UriTemplate = "{id}"
)]
Community GetCommunity(string id);
When I make a rest call to the host, I get data but only Id and Name properties are populated. The Description property is null! I am creating the channel by inheriting from ClientBase.
Does anybody know why WCF serializes Id and Name but not Description? The Transfer Encoding is set to 'Chunked' on the response from the host and I would like to know if that has anything to do with it ?
I found out that some of the properties were not getting serialized because the response xml had the elements in a different order. The solution was to explicitly set serialization order on the datacontract. Here is the datacontract after I added order attribute:
[DataContract(Namespace="",Name="community")]
public class Community
{
[DataMember(Name = "name",Order=2)]
public string Name { get; set; }
[DataMember(Name="id",Order = 1)]
public int Id{get; set;}
[DataMember(Name="description",Order=3)]
public string Description { get; set; }
}
I try to submit a request to a REST API using WCF; here's what I've done:
namespace Sample
{
[ServiceContract]
[XmlSerializerFormat]
public interface ISampleApi
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "users.xml", ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml)]
User CreateUser(User user);
}
}
And this is my User Class:
namespace Sample.Entity
{
[XmlRoot("user")]
public class User
{
[XmlElement("company")]
public string Company { get; set; }
[XmlElement("country-code")]
public string ContryCode { get; set; }
[XmlElement("created-at")]
public DateTime CreatedAt { get; set; }
[XmlElement("email")]
public string Email { get; set; }
[XmlElement("external-identifier")]
public string ExternalIdentifier { get; set; }
[XmlElement("id")]
public int Id { get; set; }
[XmlElement("measurement-system")]
public string MeasurmentSystem { get; set; }
[XmlElement("profile")]
public string Profile { get; set; }
[XmlElement("url")]
public string Url { get; set; }
[XmlElement("username")]
public string Username { get; set; }
[XmlElement("account-type")]
public string AccountType { get; set; }
}
}
But when I call CreateUser method and pass a User object to it I receive this error message:
The remote server returned an error: (422) Unprocessable Entity.
Any idea what causes this?
That exception means that the web server responded with an error code, namely 422. You will need to check with the administrator of the remote site, why that might be. (Or look at the body of the response if any was returned, it might include some hints).
Here is the explanation of error code 422: https://www.rfc-editor.org/rfc/rfc4918#section-11.2
The request you are sending to the server is most likely invalid in some way or another. What the exact error might be, is impossible to tell without knowing which request you are sending against which system.
This error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous XML instructions
Re-check the users.xml for instructions
country-code is string or integer value?