passing custom object after serialization to WCF - asp.net

I have a WCF service method with following signature:
public string CTNotification(JSONRecordingCompletedNotification content)
{
I want to create a client and consume it. I have written following code but it gives error:
using (StreamReader sr = new StreamReader(Server.MapPath("~/json.txt")))
{
string serviceBaseUrl = ConfigurationManager.AppSettings["serviceurl"].ToString() + "CTNotification";
string conversationId = ConfigurationManager.AppSettings["conversationId"].ToString();
String line = sr.ReadToEnd();
string jsonText = line;
string body = jsonText;
JSONRecordingCompletedNotification RecordingCompletedNotification = new JavaScriptSerializer().Deserialize<JSONRecordingCompletedNotification>(body);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceBaseUrl);
request.Method = "POST";
request.ContentType = "application/json";
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(RecordingCompletedNotification);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Label1.Text = response.ToString();
}
I get following error:
The remote server returned an error: (400) Bad Request.

i would suggest you to use either of the lib for json serialization and deserialization
json.net
fastjson
and change the content type as
request.ContentType = "application/json; charset=utf-8";

Related

errors running HttpWebRequest.GetResponse - 401 unauthorized

I am using Lymbix client library for sentiment analysis.
When I run the code I am getting an error in (WebResponse)httpRequest.GetResponse(): 401-Unauthorized
(available at https://github.com/lymbix/.NET-Wrapper)
The function containing 401 error is given below:
private static string Post(string url, string data, List<string> headers)
{
HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(url);
httpRequest.Method = "POST";
httpRequest.Accept = "application/json";
httpRequest.ContentType = "application/x-www-form-urlencoded";
if (headers != null)
{
foreach (string header in headers)
{
httpRequest.Headers.Add(header);
}
}
// write request?
byte[] postData = Encoding.UTF8.GetBytes(data.ToString());
httpRequest.ContentLength = postData.Length;
httpRequest.GetRequestStream().Write(postData, 0, postData.Length);
// read response
WebResponse webResponse = (WebResponse)httpRequest.GetResponse();
StreamReader webResponseStream = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8);
return webResponseStream.ReadToEnd();
}
It's saying you're not authorized, so you need to provide credentials.
HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(url);
httpRequest.Method = "POST";
httpRequest.Accept = "application/json";
httpRequest.ContentType = "application/x-www-form-urlencoded";
httpRequest.Credentials = new NetworkCredential("username","password");
httpRequest.UseDefaultCredentials = false; //the default is false, but I included it here just to illustrate that it needs to be false in order to use the specified credentials

Web API Login with Cookie

I have an ASP.Net Web API and the documentation states I need to save an Auth Token to a cookie then pass it back for API requests. I can get the Auth Token without a problem. My question is what is the best way to save the cookie and send it back in the request.
I create a cookie in the RequestMessage, but I cannot find a way to send it back when making a request against the API. How do I preserve the state of the Login/cookie.
Any help is greatly appreciated, thanks.
Update
I am now able to obtain the cookie from the response. I am using this tutorial. http://www.asp.net/web-api/overview/working-with-http/http-cookies Let me point out if you want to use this tutorial make sure you update the Web API 4's code base. In the below method i am trying to simply, Login and Logout. However, I am receiving an Error Code 500.
public HttpWebResponse InitializeWebRequest()
{
//HttpResponseMessage logoutMessage = await Logout("bla");
string responseData = string.Empty;
string url = GetServerEndPoint();
string authToken = string.Empty;
string loginInstance = "https://example.com";
// Create request.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginInstance);
request.Method = "POST";
request.ContentType = "application/json";
request.CookieContainer = new CookieContainer();
HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
if (response.StatusCode == HttpStatusCode.OK)
{
using (System.IO.StreamReader responseReader = new System.IO.StreamReader(request.GetResponse().GetResponseStream()))
{
responseData = responseReader.ReadToEnd();
}
IList<string> authHeader = responseData.Split('{', '}').ToList();
authToken = authHeader[2].Substring(13, 25);
string sessionId = response.Headers.Get(8);
var nv = new NameValueCollection();
nv["sid"] = sessionId;
nv["token"] = authToken;
CookieHeaderValue cookieVal = new CookieHeaderValue("session", nv);
// Log out
string loginInstance2 = "https://example.com";
HttpWebRequest request2 = (HttpWebRequest)WebRequest.Create(loginInstance2);
request2.Method = "POST";
request2.ContentType = "application/json";
request2.Headers.Add(nv);
HttpWebResponse response2 = (HttpWebResponse)request2.GetResponseAsync().Result;
}
return response;
}
WOW WHAT A PAIN!
I have no idea why this took me so long to figure out, but after hours and hours and DAYs, of trying to get this stupid auth to work I finally figured it out. Here is the code.
One weird thing is I had to create the header format for the cookie. Which by definition isn't a true cookie, it is a damn header value. I had to create the header title, because when I extracted the JSON object from the file and converted it to string I was unable to keep the format in tact from the file.
public HttpWebResponse InitiliazeWebRequest()
{
string responseData = string.Empty;
string loginInstance = "url + logincreds";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginInstance);
request.Method = "POST";
request.ContentType = "application/json";
request.CookieContainer = new CookieContainer();
HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
if (response.StatusCode == HttpStatusCode.OK)
{
using (System.IO.StreamReader responseReader = new System.IO.StreamReader(request.GetResponse().GetResponseStream()))
{
responseData = responseReader.ReadToEnd();
}
var toke = response.Headers.Get("authToken");
JObject o = JObject.Parse(responseData);
_authToken = (string)o["response"]["authToken"].ToString();
return response;
}
return response;
}
public HttpWebResponse LogOut()
{
string responseData = string.Empty;
string loginInstance = "https://www.example.com/logout";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginInstance);
request.Method = "GET";
request.ContentType = "application/json";
request.Headers.Add("Cookie: authToken=" + _authToken);
HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
if (response.StatusCode == HttpStatusCode.OK)
{
using (System.IO.StreamReader responseReader = new System.IO.StreamReader(request.GetResponse().GetResponseStream()))
{
responseData = responseReader.ReadToEnd();
}
return response;
}
return response;
}

Call external json webservice from asp.net C#

I need to make a call to a json webservice from C# Asp.net. The service returns a json object and the json data that the webservice wants look like this:
"data" : "my data"
This is what I've come up with but I can't understand how I add the data to my request and send it and then parse the json data that I get back.
string data = "test";
Uri address = new Uri("http://localhost/Service.svc/json");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
string postData = "{\"data\":\"" + data + "\"}";
How can I add my json data to my request and then parse the response?
Use the JavaScriptSerializer, to deserialize/parse the data. You can get the data using:
// corrected to WebRequest from HttpWebRequest
WebRequest request = WebRequest.Create("http://localhost/service.svc/json");
request.Method="POST";
request.ContentType = "application/json; charset=utf-8";
string postData = "{\"data\":\"" + data + "\"}"; //encode your data
//using the javascript serializer
//get a reference to the request-stream, and write the postData to it
using(Stream s = request.GetRequestStream())
{
using(StreamWriter sw = new StreamWriter(s))
sw.Write(postData);
}
//get response-stream, and use a streamReader to read the content
using(Stream s = request.GetResponse().GetResponseStream())
{
using(StreamReader sr = new StreamReader(s))
{
var jsonData = sr.ReadToEnd();
//decode jsonData with javascript serializer
}
}

convert HTTP request code to HTTPS request code

I have got following code witch are sending xml file on HTTP protocol and getting response back as xml file from webserver and its working fine with HTTP protocol, but now i need to send such a XML file to HTTPS protocol (not http) and need to get response as xml file from it. the code to send xml file and get response from HTTP is :
string targetUri = "http://www.hostelspoint.com/xml/xml.php"; /*this will be like: "https://www.hostelspoint.com/xml/xml.php"*/
System.Xml.XmlDocument reqDoc = new System.Xml.XmlDocument();
reqDoc.Load(Server.MapPath("~\\getdetail.xml"));
string formParameterName = "OTA_request";
string xmlData = reqDoc.InnerXml;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(targetUri);
string sendString = formParameterName + "=" + HttpUtility.UrlEncode(xmlData);
//string sendString = HttpUtility.UrlEncode(xmlData);
byte[] byteStream;
byteStream = System.Text.Encoding.UTF8.GetBytes(sendString);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteStream.LongLength;
using (Stream writer = request.GetRequestStream())
{
writer.Write(byteStream, 0, (int)request.ContentLength);
writer.Flush();
}
HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
string respStr = "";
if (request.HaveResponse)
{
if (resp.StatusCode == HttpStatusCode.OK || resp.StatusCode == HttpStatusCode.Accepted)
{
StreamReader respReader = new StreamReader(resp.GetResponseStream());
respStr = respReader.ReadToEnd(); // get the xml result in the string object
XmlDocument doc = new XmlDocument();
doc.LoadXml(respStr);
Label1.Text = doc.InnerXml.ToString();
}
}
There shouldn't be much difference in your code, as HTTP or HTTPS differs only in transport level, not in application level.
What may become a problem here is, if the server certificate used in the targetUri is trusted on your server. In this case the HTTPS identity cannot be verified.

How to dynamically invoke Web Services in .Net

I am writing a Web service client in C# which takes the URL of the web Service, and a web method name.
I want to check if thew Web method actually receives an int and returns a DataTable, and if this is true, it should call it and return the DataTable.
I have found a couple of posts where this is accomplished compiling dynamically the Proxy class.
But for my case this'd be too expensive, because the client is actually a WSS WebPart, and I don't want to do this every time the page is rendered; only when the properties are changed.
In the end of the day web service description is just an XML file. You can grab it by requesting service.asmx?WSDL:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:1753/Service1.asmx?WSDL");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string xml = reader.ReadToEnd();
Once you have service description you can parse it and check method signature. Then, you can invoke the method using HTTP POST:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:1753/Service1.asmx?HelloWorld");
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=utf-8";
byte[] data = Encoding.UTF8.GetBytes(
#"<?xml version='1.0' encoding='utf-8'?>
<soap12:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'>
<soap12:Body>
<HelloWorld xmlns='http://tempuri.org/' />
</soap12:Body>
</soap12:Envelope>");
request.ContentLength = data.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string xml = reader.ReadToEnd();
If the Web Service is always the same (i.e. the method is the same as well as what it returns) and uit's just the url that might change, then just add a web reference to the project with the webpart in it, the set the Url of the proxy like so:
using (var serviceProxy = new ServiceProxy())
{
serviceProxy.Url = somepropertysetbythewebpart;
// make call to method here
}
After a lot of resarching I found out how to do it. The code of the selected answer is almost there, but I had to add the SOAPAction in the header and also change the ContentType.
Here is the entire code:
var strRequest = #"<soap12:Envelope>
...
</soap12:Envelope>";
string webServiceUrl = "http://localhost:8080/AccontService.svc";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(webServiceUrl);
request.Method = "POST";
request.ContentType = "text/xml;charset=UTF-8";
request.Accept = "text/xml";
request.Headers.Add("SOAPAction", "http://tempuri.org/IAccountService/UpdateAccount");
byte[] data = Encoding.UTF8.GetBytes(strRequest);
request.ContentLength = data.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string responseXmlString = reader.ReadToEnd();
return new HttpResponseMessage()
{
Content = new StringContent(responseXmlString, Encoding.UTF8, "application/xml")
};

Resources