Solved

Submitting to a REST API via a CLR in C#

Posted on 2016-08-02
12
131 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
  • 5
  • 2
  • 2
  • +1
12 Comments
 
LVL 50

Assisted Solution

by:Ryan Chong
Ryan Chong earned 125 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 250 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 125 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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 14

Accepted Solution

by:
frankhelk earned 250 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 50

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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Suggested Solutions

This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
Slowly Changing Dimension Transformation component in data task flow is very useful for us to manage and control how data changes in SSIS.
Using examples as well as descriptions, and references to Books Online, show the documentation available for date manipulation functions and by using a select few of these functions, show how date based data can be manipulated with these functions.
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.

785 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