RESTful web service returning XML not JSON - c#

I have this simple web service, right now it just looks to see if the part number is A123456789 and then it returns a model number. This will be replaced by logic that will be connecting into a database to check the partno against and then return the actual model number. But at this point I just need it to return some dummy JSON data. However when I use Fiddler and look at the call in the web broswer of http://localhost:PORT/Scan/Model/A123456789 it returns this
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Model: CVS-1679</string>
But when I do a GET in fiddler of the same URI I get
"Model: CVS-1679"
Only under the textview tab.
Why is it being returned in XML (in the browser and text in Fiddler) and not JSON, when I have setup my ResponseFormat to be JSON?
My Code:
[WebGet(UriTemplate = "Model/{partno}", ResponseFormat = WebMessageFormat.Json)]
public string Model(string partno)
{
if (partno == "A123456789")
{
string modelno = "CVS-1679";
return "Model: " + modelno;
}
else
{
string modelno = "CVS-1601";
return "Model: " + modelno;
}
}

ASP.NET webservice return XML / SOAP message by default. In case you want to return Json string, you would need to decorate the Webservice with [ScriptService] attribute. This inform the IIS that this service would be used by ASP.NET AJAX calls. These attribute are part of System.Web.Extensions.
You can define the web method response format by decorating the webmethod with ScriptMethod attribute.
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
However even after decorating the webservice and webmethod by these attribute, the response can still be in XML format. This behaviour happen when the client which makes the request does not set the Request Header content type as “application/json”.
Before return the method call from webmethod serialize to Json string using JavaScriptSerializer
Debugging WebService using Fiddler
It is quite easy to use fiddler to test webservice. Following figure is an example of how to call a Webservice which returns a json string. Note that the request content type is set to application/json. The parameters expected by webserivce is mentioed in the Request Body section.
Note that the request content type is set to application/json.

It is being returned in Json if you look at the format of the data you get...
key: value
or in your case
string Model = "CVS-1679"
When you view it in fiddler your seeing the raw serialization transport from one MS endpoint to the other. The serialisation & De-serialisation elements in the .NET framework take care of transporting it across the wire, so that when you get the object back into your .NET app at the calling end, you get a variable called Model with the value you expect.
If you try to send an entire class you'll see a lot of nested XML tags, but when you get the object in your code, you'll see a first class citizen in the object hierarchy.
The reason it appears in your browser is because, the browser doesn't know how to de-serialise it, and so just displays the text

Related

URL to call the JSON WebService produced into ASP.NET

I have done a web service using Visual Studio 2012 into C#.
I'm usually use SOAP but now I need to use JSON.
So I've used this code to create a SOAP method:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string test()
{
var testArray = new List<clienti>();
testArray.Add(new clienti() {nome = "Mark", cognome = "Reed", email = "mark.reed#test.com"});
var serializer = new JavaScriptSerializer();
return serializer.Serialize(testArray);
}
Can I call this method directly from an URL?
(that is the real goal that I want to obtain)
A stuff like this: http://ws.mysite.com/serice1.asmx/test.
If I try to type the URL with the name of the method after the slash not return data but an error on the URL format!!!
In debug mode all works perfectly if I click the button method
So the answer to your question is Yes I believe, but let's start for sure with an Ajax scenario that 100% works.
Something I want to clarify for you though, your "test()" method in service1.asmx is not a "Soap method" as you called it. Its a "Web Service method" and it returns JSON. It is callable using HTTP protocol or SOAP protocol. Because you added the [ScriptMethod] to the Web Method you can now call it using an HTTP Get request. If you remove the [ScriptMethod] attribute, you can only call "test()" with an HTTP POST request or a SOAP request.
The following jQuery Ajax call will work with service1.asmx/test:
$.ajax({
type: "POST",
url: "Service1.asmx/test",
data: "{ ifTestHadAParameter: 'hello world'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var myData = JSON.parse(data.d); // data.d is a JSON formatted string, to turn it into a JSON object
// we use JSON.parse
// now that myData is a JSON object we can access its properties like normal
}
});
If you are using ASP.NET 3.5 or below, ASP.NET Web Services wrap JSON responses to HTTP Get and Post requests in an outer JSON {} to project against a certain type of hacking. Hence the data.d in my jQuery Ajax code snippet. If you using ASP.NET > 4.0 then, in your success function data contains your response from service1.asmx/test, no data.d required.
Now to call http://ws.mysite.com/serice1.asmx/test, this will not work in a "browser" as you say but you probably ultimately do not want to use the URL in a browser, that is just how you stated your question for simplicity.
You need to format your Get request correctly with http://ws.mysite.com/serice1.asmx/test.. So in C#, using the HTTPRequest .NET lib you should be able to prepare a proper HTTP Get Request to call your Web Services URL, basically simulating a browser request in your C# code if you have the right contentType in your Get request header.
A great tool to use for this problem is called Fiddler, you can easily create HTTP Get requests and change the content type.
No as asmx webservices have no router's like webapi or MVC best create a webapi project, add a controller with empty read write methods and return your array in there it will serialize automatically in JSON,XML or BSON default JSON (you can change this in the accept header in you client request) example method
public class mycontroller: ApiController
{
public string Get()
{
var testArray = new List<clienti>();
testArray.Add(new clienti() {nome = "Mark", cognome = "Reed", email = "mark.reed#test.com"});
return testArray ;
}
you can access the url like this site/api/controller

Insert JSON from URL string

I have created a REST web service that should get a JSON string and convert it to an object in C#. I have created my classes and used the deserialization:
RootObject test = JsonConvert.DeserializeObject<RootObject>("id");
So far so good, I need to call my function :
public string JSONData(string id)
Is there a way to insert my JSON in the URL so I can trigger my function, or am I missing something fundamental?
http://localhost/RestSrv/Json/....
What should I put in the ... that will give value to my id string and call my JSONData function that will deserialize the JSON after? Should I use an online JSON convert to URL tool?
I can think of two ways to do this
Send JSON via HTTP POST with Content-Type: application/json header
Send HTTP Query String with the required data. For example
?object[type]=person&children_names[]=Mia&children_names[]=Anna
Would convert to JSON (https://www.convertonline.io/convert/query-string-to-json)
{"object":{"type":"person"},"children_names":["Mia","Anna"]}
Option 1 is better since URL string can be long and have a length limitation.

REST Webservice for HTML5 Server Side Events

At the moment I have an C# console application that exposes Web Services through WebServiceHost those web services are being used by an website but now I'm trying to add SSE to the site.
The code at the client is:
var source = new EventSource(server+'eventSource');
source.onmessage = function (event) {
alert(event.data);
};
But on the server side, when I try to define the contract:
[OperationContract]
[WebGet]
String EventSource();
What the service is returning service is a xml with a String.
What should I do on the server side to create a document available for SSE?
Thanks in advace
If you have an OperationContract, the return Type is always serialized as XML or optionaly as JSON. If you do not want the return value to be serialized define it as Stream.
[OperationContract]
[WebGet]
Stream EventSource();
// Implementation Example for returning an unserialized string.
Stream EventSource()
{
// These 4 lines are optional but can spare you a lot of trouble ;)
OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse;
context.Headers.Clear();
context.Headers.Add("cache-control", "no-cache");
context.ContentType = "text/event-stream"; // change to whatever content type you want to serve.
return new System.IO.MemoryStream(Encoding.ASCII.GetBytes("Some String you want to return without the WCF serializer interfering."));
}
If you build the stream yourself remember to exectute .Seek(0, SeekOrigin.Begin); before you return it.
EDIT:
Changed the command order to set the ContentType AFTER the Header gets cleard. Otherwise you would clear the freshly set ContentType too ;)

WCF deserialization trying to convert xml parameter to object when I just want the string

I am writing a WCF service stub to 'mimic' an existing VB6 service that exists. The stub needs to accept a single parameter which is a string, perform some logic and return a string.
The issue I am having is given the following method on the service contract
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "lookup")]
string LookupItem(string requestXml);
When I post a message in fiddler I get the error
The server encountered an error
processing the request. The exception
message is 'Unable to deserialize XML
body with root name 'XmlRoot' and
root namespace '' (for operation
'LookupItem' and contract
('IServiceStub',
'http://tempuri.org/')) using
DataContractSerializer. Ensure that
the type corresponding to the XML is
added to the known types collection of
the service.'.
Is WCF trying to deserialize my XML into an object, even though I don't want it to? The string is being sent as text/xml because the service it's mimicking has to receive the POST as text/xml. Is there something I'm missing?
Overcame this with the following:
public Stream LookupItem(Message requestXml)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
string responseXml = "<whatever />";
return new MemoryStream(Encoding.UTF8.GetBytes(responseXml ));
}

ASMX Returning a pure string

I have an ASP.NET web service (.asmx). My service is defined like the following:
[System.Web.Services.WebService(Namespace = "http://tempuri.org/")]
[System.Web.Services.WebServiceBinding(ConformsTo = System.Web.Services.WsiProfiles.BasicProfile1_1)]
public class MyService : System.Web.Services.WebService
{
[System.Web.Services.WebMethod]
public string GetResult()
{
string result = "";
int day = System.DateTime.UtcNow.Day;
if ((day % 1) == 1)
result = "odd";
else
result = "even";
return result;
}
}
Currently, if I call this service method, I get the following result:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">even</string>
My issue is, I need to return just the string part. I do NOT want to return the wrapping XML. How do I do this with an .asmx?
Thanks!
Does it need to be an .asmx web service for this? I mean, by excluding the SOAP envelope you're essentially saying "this is not a SOAP web service" as it is, so why not take it a step further and make it a regular .aspx page instead of an .asmx web service.
As a page, what you're trying to do would be trivial. Remove all mark-up from the page, use Response.Headers to edit the response headers accordingly, Response.Write() to output your raw text, and Response.End() to close the response.
Use json
add the required attribute to your web service and your web method and you get what you want.
Web Service Attribute:[ScriptService]
Web Method Attribute:[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
Read a sample Here
Why do you want to get rid of the XML part? The code which is generated by the proxy needs a common format so it can understand and read the data that is being returned. Stripping the XML essentially makes your return data unreadable by the client proxy.

Categories