LisaSnyder
asked on
RESTful Service - POST (format XML) passing Object
I am trying to consume a Web Service I have written in VS2012 C#. The operation takes a Transaction object and returns a Transaction object.
I need to consume the web service and am having trouble writing the code for the HttpWebRequest and HttpWebResponse.
I do not know who to pass the Transaction Object to the service method and get the results back and deserialize it back into the Transaction object. It is a POST (adding a record).
All the examples I find, do not show me enough detail on how to do this.
Can someone please give me a straight forward example of how to write the client HttpWebRequest/Response and how to pass the object and then how to get the returned data back into the object.
Thank you,
Lisa
I need to consume the web service and am having trouble writing the code for the HttpWebRequest and HttpWebResponse.
I do not know who to pass the Transaction Object to the service method and get the results back and deserialize it back into the Transaction object. It is a POST (adding a record).
All the examples I find, do not show me enough detail on how to do this.
Can someone please give me a straight forward example of how to write the client HttpWebRequest/Response and how to pass the object and then how to get the returned data back into the object.
Thank you,
Lisa
what kind of transaction are u talking about ?
What u need to do is to serialize the object u want in this case binary serialization ll be better i guess cuz i dont know what u carry in this "transaction object" and deserialize on the client and postback server side..
If u can tell more details about what u want to do we can help u more
What u need to do is to serialize the object u want in this case binary serialization ll be better i guess cuz i dont know what u carry in this "transaction object" and deserialize on the client and postback server side..
If u can tell more details about what u want to do we can help u more
ASKER
I have a Book Store web service that has 3 operations. 1st 1 returns all books, 2nd operation returns book when passing a ISBN # in. Those work fine. The 3rd operation is to add a new book to the books table using POST. I serialized the book object into XML and then included in HttpWebRequest. When I try to get response back, I get 404 Error.
Code to consume web service followed by IbuyBooks operations and buyBooks.svc.cs below: Thank you for your help.
try
{
byte[] bytes = Encoding.UTF8.GetBytes(xml );
HttpWebRequest request = (HttpWebRequest)WebRequest .Create
("http://localhost:24885/buyBooks.svc/NewBook/");
request.Method = "POST";
request.ContentLength = bytes.Length;
request.ContentType = "text/xml";
using (Stream requestStream = request.GetRequestStream() )
{
requestStream.Write(bytes, 0, bytes.Length);
}
HttpWebResponse response = (HttpWebResponse)request.G etResponse ();
Stream resStream = response.GetResponseStream ();
StreamReader rdStreamRdr = new StreamReader(resStream);
if (response.StatusCode != HttpStatusCode.OK)
{
string message = String.Format("POST Failed. Received HTTP {0}",
response.StatusCode);
throw new ApplicationException(messa ge);
}
else
{
string message = rdStreamRdr.ReadToEnd();
Response.Write(message);
}
}
catch (Exception ex)
{
Response.Write(ex.Message. ToString() );
}
Here is the operations from the web service (AddBook method is the one I am having issues with):
IbuyBooks
[OperationContract]
[WebInvoke(Method = "GET",
UriTemplate = "/Books")]
List<Book> AllBooks();
[OperationContract]
[WebInvoke(Method = "GET",
UriTemplate = "/Book/{ISBN}")]
Book GetBook(string isbn);
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "/NewBook")]
Book AddBook(Book book);
buyBooks.svc.cs
public Book AddBook(Book b)
{
dc.Books.InsertOnSubmit(b) ;
dc.SubmitChanges();
var bookdetail = from book in dc.Books
where book.ISBN == book.ISBN
select book;
Book addedBook = new Book();
foreach (var item in bookdetail)
{
addedBook.ISBN = item.ISBN;
addedBook.Title = item.Title;
addedBook.Author = item.Author;
addedBook.Publisher = item.Publisher;
addedBook.PublishDate = item.PublishDate;
addedBook.Price = item.Price;
addedBook.QOH = item.QOH;
}
return addedBook;
}
Code to consume web service followed by IbuyBooks operations and buyBooks.svc.cs below: Thank you for your help.
try
{
byte[] bytes = Encoding.UTF8.GetBytes(xml
HttpWebRequest request = (HttpWebRequest)WebRequest
("http://localhost:24885/buyBooks.svc/NewBook/");
request.Method = "POST";
request.ContentLength = bytes.Length;
request.ContentType = "text/xml";
using (Stream requestStream = request.GetRequestStream()
{
requestStream.Write(bytes,
}
HttpWebResponse response = (HttpWebResponse)request.G
Stream resStream = response.GetResponseStream
StreamReader rdStreamRdr = new StreamReader(resStream);
if (response.StatusCode != HttpStatusCode.OK)
{
string message = String.Format("POST Failed. Received HTTP {0}",
response.StatusCode);
throw new ApplicationException(messa
}
else
{
string message = rdStreamRdr.ReadToEnd();
Response.Write(message);
}
}
catch (Exception ex)
{
Response.Write(ex.Message.
}
Here is the operations from the web service (AddBook method is the one I am having issues with):
IbuyBooks
[OperationContract]
[WebInvoke(Method = "GET",
UriTemplate = "/Books")]
List<Book> AllBooks();
[OperationContract]
[WebInvoke(Method = "GET",
UriTemplate = "/Book/{ISBN}")]
Book GetBook(string isbn);
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "/NewBook")]
Book AddBook(Book book);
buyBooks.svc.cs
public Book AddBook(Book b)
{
dc.Books.InsertOnSubmit(b)
dc.SubmitChanges();
var bookdetail = from book in dc.Books
where book.ISBN == book.ISBN
select book;
Book addedBook = new Book();
foreach (var item in bookdetail)
{
addedBook.ISBN = item.ISBN;
addedBook.Title = item.Title;
addedBook.Author = item.Author;
addedBook.Publisher = item.Publisher;
addedBook.PublishDate = item.PublishDate;
addedBook.Price = item.Price;
addedBook.QOH = item.QOH;
}
return addedBook;
}
ASKER
Forgot to include the method that I used to do serialization in case there is something wrong there. I pass the book object in and return xml to use in HttpWebRequest. Method below:
public string CreateXML(Book book)
{
XmlDocument xmlDoc = new XmlDocument();
XmlSerializer xmlSerializer = new XmlSerializer(book.GetType ());
using (MemoryStream xmlStream = new MemoryStream())
{
xmlSerializer.Serialize(xm lStream, book);
xmlStream.Position = 0;
xmlDoc.Load(xmlStream);
return xmlDoc.InnerXml;
}
}
public string CreateXML(Book book)
{
XmlDocument xmlDoc = new XmlDocument();
XmlSerializer xmlSerializer = new XmlSerializer(book.GetType
using (MemoryStream xmlStream = new MemoryStream())
{
xmlSerializer.Serialize(xm
xmlStream.Position = 0;
xmlDoc.Load(xmlStream);
return xmlDoc.InnerXml;
}
}
its seems like flushing the requeststream.
after a write try flush to force the data to be send to the stream.
if this dont work. what did u get when debug the add operation on the service file ? do u get any objects, i mean the book object is null or has a value ?
after a write try flush to force the data to be send to the stream.
if this dont work. what did u get when debug the add operation on the service file ? do u get any objects, i mean the book object is null or has a value ?
ASKER
I am not sure exactly how to debug. Used Fiddler and am getting 404 error. I will try the flush and see what happens.
ASKER
Can you tell me how to check to see if object is null?
Run both your client and service at the same machine. Let client point to the url of your local server url. If this setup is done, if the client makes a request, using breakpoint in svc file you can debug.
how do u call the service ? 404 is not found error
ASKER
I posted the HttpWebRequest and HttpWebResponse above. That is the code I use to call the service.
can u post the calling code of the books? for the list of the books
and try to change the url without / at the end..
ASKER
Here is where I call the operations to return the list of books. The status that comes back is OK. I will post the code and the string that is displayed, so you can see. I only see 1 xml tag in the string. Not sure why.
Code to Display List of Books
HttpWebRequest request = (HttpWebRequest)WebRequest .Create("http://localhost:27601/buyBooks.svc/Books" );
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.G etResponse ();
Stream receiveStream = response.GetResponseStream ();
Encoding encode = System.Text.Encoding.GetEn coding("ut f-8");
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader(receiveStream , encode);
Response.Write("");
Char[] read = new Char[256];
// Reads 256 characters at a time.
int count = readStream.Read(read, 0, 256);
while (count > 0)
{
// Dumps the 256 characters on a string and displays the string to the console.
String str = new String(read, 0, count);
Response.Write(str +", ");
count = readStream.Read(read, 0, 256);
}
// Releases the resources of the response.
response.Close();
// Releases the resources of the Stream.
readStream.Close();
The string that I display from results. The only tag that shows is <Author>.
Barry123-3232008-02-17T00: 00:00Hall2 Jerry344-1 122011-01- 01T00:00:0 0Prentice5 < Author>Bob454-3942009-05-0 1T00:00:00 Prentice10
It should look like"
<books>
<book/>
<ISBN/>
<Title/>
<Author/>
<Publisher/>
<PublishDate/>
<Price/>
<QOH/>
</book>
</books>
<
Code to Display List of Books
HttpWebRequest request = (HttpWebRequest)WebRequest
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.G
Stream receiveStream = response.GetResponseStream
Encoding encode = System.Text.Encoding.GetEn
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader(receiveStream
Response.Write("");
Char[] read = new Char[256];
// Reads 256 characters at a time.
int count = readStream.Read(read, 0, 256);
while (count > 0)
{
// Dumps the 256 characters on a string and displays the string to the console.
String str = new String(read, 0, count);
Response.Write(str +", ");
count = readStream.Read(read, 0, 256);
}
// Releases the resources of the response.
response.Close();
// Releases the resources of the Stream.
readStream.Close();
The string that I display from results. The only tag that shows is <Author>.
Barry123-3232008-02-17T00:
It should look like"
<books>
<book/>
<ISBN/>
<Title/>
<Author/>
<Publisher/>
<PublishDate/>
<Price/>
<QOH/>
</book>
</books>
<
ASKER
As requested previously, I called the flush, but it did not change the results. I tried to debug. I see the request has the XML, but the response is NULL. When it gets to the HttpWebResponse, it skips right to the 404 Exception.
Also, something interesting. I started Fiddler. Outside of the client, I called browse on the webservice and successfully returned the list of books and it displayed in XML. The line returned in Fiddler was 200. However, it was immediately followed by a 404 Result. Can someone tell me what is happening? Could it be related to my issue with calling the operation in Webservice POST that is getting the 404?
# Result Protocol Host URL Body Caching Content-Type Process Comments Custom
1 200 HTTP localhost:27601 /buyBooks.svc 1,321 text/html; charset=UTF-8 iexplore:10040
2 404 HTTP localhost:27601 /favicon.ico 4,958 private text/html; charset=utf-8 iexplore:10040
Also, something interesting. I started Fiddler. Outside of the client, I called browse on the webservice and successfully returned the list of books and it displayed in XML. The line returned in Fiddler was 200. However, it was immediately followed by a 404 Result. Can someone tell me what is happening? Could it be related to my issue with calling the operation in Webservice POST that is getting the 404?
# Result Protocol Host URL Body Caching Content-Type Process Comments Custom
1 200 HTTP localhost:27601 /buyBooks.svc 1,321 text/html; charset=UTF-8 iexplore:10040
2 404 HTTP localhost:27601 /favicon.ico 4,958 private text/html; charset=utf-8 iexplore:10040
Internet explorer searches for favicon.ico as default behaviour.
dont think about it.
dont think about it.
ASKER
Thank you Melih. I can then focus on my POST for add book that is still getting 404 Exception.
did u try to call service without / at the end..
http://localhost:24885/buyBooks.svc/NewBook
and also what i realise is.
ur add bok url port and getbook url port is different
one is 24885 other is 27601.
are they different services? or the same service with misstype ports?
http://localhost:24885/buyBooks.svc/NewBook
and also what i realise is.
ur add bok url port and getbook url port is different
one is 24885 other is 27601.
are they different services? or the same service with misstype ports?
ASKER
Melih - The previous code with call with port 24885 was a different project. I created a new solution with new projects and the calls are all to 27601. No, I did not try to call without the / at the end. I can try that. Since I am changing that, can you tell me how the UriTemplate should look for that? Right now it looks like the following:
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "/NewBook")]
Book AddBook(Book book);
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "/NewBook")]
Book AddBook(Book book);
thats seems like ok..
when u get 404 while calling a service its almost the URL that u call gives the error
when u get 404 while calling a service its almost the URL that u call gives the error
ASKER
I changed the call to remove the trailing /. Now I get a Exception 400 Bad request.
This is the Xml that is being put into byte[] array:
"<?xml version=\"1.0\"?>
<Book xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
<ISBN>111-111</ISBN>
<Title>Test Title</Title>
<Author>Pat</Author>
<Publisher>aaa</Publisher>
<PublishDate>2011-01-11T00 :00:00
<Price>15.11</Price>
<QOH>17</QOH>
</Book>"
This is the Xml that is being put into byte[] array:
"<?xml version=\"1.0\"?>
<Book xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
<ISBN>111-111</ISBN>
<Title>Test Title</Title>
<Author>Pat</Author>
<Publisher>aaa</Publisher>
<PublishDate>2011-01-11T00
<Price>15.11</Price>
<QOH>17</QOH>
</Book>"
<Publisher>aaa</Publisher>
<PublishDate>2011-01-11T00 :00:00
<Price>15.11</Price>
Publish date XMLElement is not correct.. must ave endelement
<Publisher>aaa</Publisher>
<PublishDate>2011-01-11T00 :00:00</Pu blishDate>
<Price>15.11</Price>
<PublishDate>2011-01-11T00
<Price>15.11</Price>
Publish date XMLElement is not correct.. must ave endelement
<Publisher>aaa</Publisher>
<PublishDate>2011-01-11T00
<Price>15.11</Price>
ASKER
That was a cut/paste error on my part. The </PublishDate> is there. That, unfortunately, is not the issue.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I was very pleased at the amount of support that I received. This was my first time asking a question, usually I just browse for answers. But I could not find a solution to this problem. Some experts referred me to links, which I had already investigated without resolution. I also received some suggestions for code modifications, but unfortunately none resolved the issue. I kept searching this morning and finally found an article that stepped through the service and test app. It finally made clear where I had the issue. I revised my code based on the article (in my comment) and it worked.
Also had a chance to look into asp.net web api ? http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api