?
Solved

Submitting to a REST API via a CLR in C#

Posted on 2016-08-02
12
Medium Priority
?
288 Views
Last Modified: 2016-10-04
Ok so I'm trying to create a CLR to do an HTTP Post for a REST API.  The GET and DELETE methods (which are not included below) work great.  The problem is with the post and necessary parameters.  I've googled till the cows have come home and still no joy.  

Below I have the url hardcoded just to know what I'm passing in.  I continuously get 'The remote server returned an error: (400) Bad Request.' returned.  If I do this through a form it works.  Just not through the CLR so clearly I'm doing something wrong.

One thing that I did notice is that although I'm hardcoding the url as an encoded string, when it is actually sent via request.GetResponse(), it is not encoded.  I'm not sure how it is getting unencoded?  If I could just get it to send in the correct format I think that it would work.  Any thoughts here?

[Microsoft.SqlServer.Server.SqlProcedure]
    public static void AFWSPost2(SqlString weburl, SqlString token, out SqlString returnval)
    {
        string url = Convert.ToString(weburl);
        string feedData = string.Empty;
        HttpWebRequest request = null;
        HttpWebResponse response = null;
        Stream stream = null;
        StreamReader streamReader = null;

        try
        {
            request = (HttpWebRequest)WebRequest.Create("https://restapi.software.com/api/1/logo?imagelink=http%3A%2F%2Fwww.website.org%2FPortals%2F_default%2FSkins%2F2015%2Fimages%2Flogo-full.png&name=OurLogo");
            request.Method = "POST";
            request.Headers.Add("Authorization", "Bearer " + token.ToString());
            request.ContentType = "multipart/form-data";
            response = (HttpWebResponse)request.GetResponse();
            stream = response.GetResponseStream();
            streamReader = new StreamReader(stream);
            feedData = streamReader.ReadToEnd();
        }
        catch (Exception ex)
        {
            SqlContext.Pipe.Send(ex.Message.ToString());
        }
        finally
        {
            if (response != null && stream != null && streamReader != null)
            {
                response.Close();
                stream.Dispose();
                streamReader.Dispose();
            }
        }

        returnval = feedData;
    }

Open in new window

0
Comment
Question by:afacts
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 2
  • 2
  • +1
12 Comments
 
LVL 53

Assisted Solution

by:Ryan Chong
Ryan Chong earned 500 total points
ID: 41740051
>>The remote server returned an error: (400) Bad Request.
make sure the parameters passing in are valid?

also make sure the web service allows POST request.
0
 
LVL 14

Assisted Solution

by:frankhelk
frankhelk earned 1000 total points
ID: 41740369
I'm not that much a geek at programming web requests, but ...

the difference between GET and POST is that the form data (everything following the ? in your example) is encoded in the URL when doing a GET and sent like an attachment (thus allowing voluminous form data) when doing a POST.

MSDN has an example snippet about how to do a POST request here (hard to read in c# and VB .. formatting problem .. but OK in VB.NET).
0
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 500 total points
ID: 41740589
@Ryan Chong
If the server did not allow POST, then he should get back a "Method Not Allowed" error, not a "Bad Request."

@afacts
You should really spend some time reading up on HTTP and how it works. A basic understanding is all you need for what you are trying to accomplish. (Please do not take this as denigration or sarcasm; just giving my point of view.) I'm not sure that "multipart/form-data" is what you need here...but that's just based on what your code is doing. You said that it works when you execute it in the browser. Have you tried running something like Fiddler to see what the browser actually sends? Whatever the browser sends is what you need to emulate in code. If that's a file, then "multipart/form-data" would be correct; otherwise, you'll need the correct MIME type.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 14

Accepted Solution

by:
frankhelk earned 1000 total points
ID: 41740668
1
 

Author Comment

by:afacts
ID: 41740843
Hi käµfm³d,

Thanks for your feedback.  multipart/form-data is what's being used in the documentation for the web service so that's why I set it to that.  Yes I've been reading up quite a bit on doing HTTP posting within C# and have tried different examples but have not been successful.

Yes I did try using fiddler to see what's being sent.  I've hardcoded the parameters as encoded in the code snippet given to make sure that it is sent in the correct format.  The problem is that when it gets to line 17 in the code sample above, it still sends the post data unencoded.  I did a SqlContext.Pipe.Send on the url that is being sent at that point to see what it looks like and although I have it hardcoded one way, it is being sent another way.  I think that this is why its failing but I can't figure out why it is being sent unencoded when I have it hardcoded to be encoded.

This line is the culprit:
response = (HttpWebResponse)request.GetResponse();

Open in new window

I know its sending the request but I don't know why it seems to transform the data before it does ...
0
 

Author Comment

by:afacts
ID: 41740846
Thank you FrankHelk, I'll check out this link ...
0
 

Author Comment

by:afacts
ID: 41740847
Hi Ryan, yes I'm sure that the service allows a POST because it works if I submit the data through a webform ... its just not working from the CLR code ...
0
 
LVL 53

Expert Comment

by:Ryan Chong
ID: 41741640
@käµfm³d,

If the server did not allow POST, then he should get back a "Method Not Allowed" error, not a "Bad Request."
yes, I knew that :)
0
 

Author Comment

by:afacts
ID: 41828454
I wound up using the following app in Chrome, postman:

https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en

It made it very easy to debug the api.
0
 

Author Closing Comment

by:afacts
ID: 41828941
Thanks everyone for your help.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Why is this different from all of the other step by step guides?  Because I make a living as a DBA and not as a writer and I lived through this experience. Defining the name: When I talk to people they say different names on this subject stuff l…
In part one, we reviewed the prerequisites required for installing SQL Server vNext. In this part we will explore how to install Microsoft's SQL Server on Ubuntu 16.04.
Familiarize people with the process of utilizing SQL Server functions from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Microsoft Ac…
Using examples as well as descriptions, and references to Books Online, show the different Recovery Models available in SQL Server and explain, as well as show how full, differential and transaction log backups are performed
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question