Send large JSON data to WCF Rest Service - wcf

I have a client web page that is sending a large json object to a proxy service on the same domain as the web page.
The proxy (an ashx handler) then forwards the request to a WCF Rest Service. Using a WebClient object (standard .net object for making a http request)
The JSON successfully arrives at the proxy via a jQuery POST on the client webpage.
However, when the proxy forwards this to the WCF service I get a Bad Request - Error 400
This doesn't happen when the size of the json data is small
The WCF service contract looks like this
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
CarConfiguration CreateConfiguration(CarConfiguration configuration);
And the DataContract like this
[DataContract(Namespace = "")]
public class CarConfiguration
{
[DataMember(Order = 1)]
public int CarConfigurationId { get; set; }
[DataMember(Order = 2)]
public int UserId { get; set; }
[DataMember(Order = 3)]
public string Model { get; set; }
[DataMember(Order = 4)]
public string Colour { get; set; }
[DataMember(Order = 5)]
public string Trim { get; set; }
[DataMember(Order = 6)]
public string ThumbnailByteData { get; set; }
[DataMember(Order = 6)]
public string Wheel { get; set; }
[DataMember(Order = 7)]
public DateTime Date { get; set; }
[DataMember(Order = 8)]
public List<string> Accessories { get; set; }
[DataMember(Order = 9)]
public string Vehicle { get; set; }
[DataMember(Order = 10)]
public Decimal Price { get; set; }
}
When the ThumbnailByteData field is small, all is OK. When it is large I get the 400 error
What are my options here?
I've tried increasing the MaxBytesRecived config setting but that is not enough
Any ideas?

I would also tweak maxStringContentLength and maxBytesPerRead. Also make sure that whatever binding configuration you set up, you're actually using it in all the right places.
This thread captures pretty well all the things that can go wrong when you are dealing with a large string in WCF message input, so I'd follow the guidance here: Sending large strings to a WCF web service

Related

Unable to send image file as part Datacontract

I am developing a Wcf Restful Service which contains data contract "User" shown below
[DataContract]
public class User
{
public User()
{
}
[DataMember(Name = "Name")]
public string Name { get; set; }
[DataMember(Name = "Mobile")]
public string Mobile { get; set; }
[DataMember(Name = "Email")]
public string Email { get; set; }
[DataMember(Name = "IsImageUpdated")]
public bool IsImageUpdated { get; set; }
}
Now i would like to add one mode data member of type Image,When i try to add Image with type Stream it showing exception
[DataMember(Name = "Iamge")]
public Stream Image { get; set; }
"The InnerException message was 'Type 'System.IO.FileStream' with data contract name 'FileStream:http://schemas.datacontract.org/2004/07/System.IO' 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."
The service i am developing having many Data contract's,I read some posts which saying the issue can be resolved by changing the Datacontract to message contract,Does a service supports different contract types(like Data,Message).
i need a solution.
This is not possible when using a WebHttpBinding.
Combining streamed and buffered Content is only possible when the binding has a SOAP message Format and you use MessageContract instead of DataContract.
Using a byte[] or returning the stream directly is supported.
[DataMember(Name = "Iamge")]
public byte[] Image { get; set; }
or
[OperationContract]
[WebGet(UriTemplate = "/Image")]
Stream GetImage();
or when using NetTcpBinding, WsHttpBinding, BasicHttpBinding, ...
[MessageContract]
public class ImageData
{
[MessageBodyMember]
public Stream Image { get; set; }
[MessageHeader]
public string Name { get; set; }
}

Consuming WCF Service with DataContract

I do have a simple WCF service in which If I put the method with simple Data Type then I can access that service in the MVC project which is in same Solution. But if I change the Data Type of the Service method even to array or list of string or any other simple Data Type, I cannot access the service. Do I need to make any config changes.
[DataContract]
public class Property
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string PropertyPost { get; set; }
[DataMember]
public string PropertyType { get; set; }
[DataMember]
public string DealType { get; set; }
[DataMember]
public string Department { get; set; }
[DataMember]
public string ProjectName { get; set; }
}
I actually want to return the List from the WCF service for which I have created the Datacontract, but it is not working even with simple List Type.
Do we need to specify anything in Service like WebInvoke?
Can any one help?

How to get json response of a custom object using wcf REST services?

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.

WCF Rest client and Transfer Encoding Chunked: Is it supported?

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; }
}

What causes this error message? The remote server returned an error: (422) Unprocessable Entity

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?