I got a web-service and want to return this "string" as a bare string, without the extra serialization by WCF, because it's already serialized.How do I do it?
[OperationContract]
[FaultContract(typeof(Exception))]
[WebGet(ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json)]
string Get_Json();
I have found the solution for this on this page. The following should work:
[OperationContract]
public Stream Get_Json() {
return new MemoryStream(Encoding.UTF8.GetBytes("This is a string"));
}
add a servic/operation behavior that overrides the serializer.. and do nothing in it... just return the result as is
A much better and cleaner solution seems to be this well documented and cleanly designed project https://github.com/mikeobrien/WcfRestContrib which aims to plug some of the existing holes in the WCF REST solution space. This package is available also through NuGet with:
PM> Install-Package wcfrestcontrib
Related
I have a big problem.
I created a WCF service.My POST declaration looks like this:
[OperationContract]
[WebInvoke(UriTemplate = "json/put",
Method = "POST",
BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
string PutData(string jsonText);
I was expecting that when I'm sending data (I'm using fiddler2 to test it) that it will automaticly "put" into the jsonText variable.
The service works, but there is no data :(.
Can anybody help? The whole project
WCF expects the JSON payload to be deserialized into a type. Try creating a class that is shaped like your JSON payload and use that as the parameter type.
Why is it possible to send in a WCF DataService the following JSON string:
{ SomeElement: 'val1', SomeOtherElement: 'val2' }
whilest you have to send in an normal WCF Service like
[OperationContract,
WebInvoke (Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped)]
public string SomeMehtod(string SomeElement, string SomeOtherElement)
the following JSON string
{ "SomeElement": "val1", "SomeOtherElement": "val2" }
This inconsistency is not clear to me. Why do I have to use double quotes in the normal web serive whilest I can omit the quotes for the element name in WCF data services?
Maybe somone knows an answer to this....
I am very familiar with the internal plumbing behind WCF's JSON parsing infrastructure, and essentially, the plumbing that takes care of the second situation is really designed to support "strict" standards-complaint JSON.
It's just a coincidence that the first situation works with non-compliant JSON. Don't read into it. It was not a conscious design decision. Hope this clears up confusion!
For more details, you can just explore DataContractJsonSerializerOperationFormatter, DataContractJsonSerializerOperationBehavior, and DataContractJsonSerializer using Reflector.
Is it possible to override the default WCF DataContractSerializer behaviour when Serialize/DeSerialize entities and use JSON.NET instead?
I have the following service contract for handling the City entity. For design reasons the City entity has IsReference=true, and therefore the default DataContractSerializer raise errors.
For the "GET" methods I can handle the situation with JsonConvert.DeserializeObject, but with "PUT,POST,DELETE" methods DataContractSerializer takes precedence and fails complaining for the IsReference entities cannot be serialized.
I have find this Post to implement IOperationBehavior and provide my own Serializer but I do not know how to integrate Json.NET with this. and I believe there should be more straight forward approach for this.
I’d appreciate any help or guidance regarding this scenario, or advice to other approaches.
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class CityService
{
[Description("Get all Cities")]
[WebGet(UriTemplate = "")]
public Message Cities()
{
}
[Description("Allows the details of a single City to be updated.")]
[WebInvoke(UriTemplate = "{code}", Method = "PUT")]
public Message UpdateCity(string code, City city)
{
}
}
Many thanks
Hossam
The usage of Extending Encoders and Serializers (see http://msdn.microsoft.com/en-us/library/ms733092.aspx) or other methods of Extending WCF like usage of DataContractSerializerOperationBehavior is very interesting, but for your special problem there are easier solution ways.
If you already use Message type to return the results an use WCF4 you can do something like following:
public Message UpdateCity(string code, City city)
{
MyResponseDataClass message = CreateMyResponse();
// use JSON.NET to serialize the response data
string myResponseBody = JsonConvert.Serialize(message);
return WebOperationContext.Current.CreateTextResponse (myResponseBody,
"application/json; charset=utf-8",
Encoding.UTF8);
}
In case of errors (like HttpStatusCode.Unauthorized or HttpStatusCode.Conflict) or in other situations when you need to set a HTTP status code (like HttpStatusCode.Created) you can continue to use WebOperationContext.Current.OutgoingResponse.StatusCode.
As an alternative you can also return a Stream (see Link and http://msdn.microsoft.com/en-us/library/ms732038.aspx) instead of Message to return any data without additional default processing by Microsoft JSON serializer. In case of WCF4 you can use CreateStreamResponse (see http://msdn.microsoft.com/en-us/library/dd782273.aspx) instead of CreateTextResponse. Don't forget to set stream position to 0 after writing in the stream if you will use this technique to produce the response.
Is there some reason why you want to use the Json.NET library specifically. If you want to return JSON, why not just use the ResponseFormat property from the WebGet and WebInvoke attributes?
[WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]
That should for most cases. What version of WCF are you running? Any reason you're returning a Message type rather than the actual type?
Define it in your service web config on service behaviors:
<endpointBehaviors>
<behavior name="restfulBehavior">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
<!--<enableWebScript />-->
</behavior>
</endpointBehaviors>
or in your operation contract of your Interface
[OperationContract]
[WebInvoke(Method = "GET",
UriTemplate = "/advertisements/{app_id}/{access_token}/{genero}/{age}",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped)]
When using the following interface to talk to PHP from .NET, .NET builds the request body XML with parameter names barcode and branch. The parameter names should be Barcode and Branch. Yes, the PHP server is case sensitive.
Am I forced to capitalise my parameter names? or can I specify names using attributes?
Many Thanks
Neil
[ServiceContract]
public interface IStockEnquiryService
{
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "")]
Branches GetStockInfo(string barcode, string branch);
}
Try applying the MessageParameterattribute to the method arguments and specify the right case in its Name property.
I am using RESTful WFC's WebInvoke and WebGet attribute classes. In the UriTemplate parameter I want to capture a variable which includes the period character. How do I do so?
So
[WebInvoke(Method = "PUT", UriTemplate = "{id}")]
[OperationContract]
TItem UpdateItemInXml(string id, TItem newValue);
I would like it to match the url:
http://service.svc/A.1
I couldn't find a way to do so. The solution I implemented was to base64 encode the id in the URL.