skip to Main Content

I want to upload a .json file to a server as a file. I am building a UWP app using C#. I make the POST request using Windows.Web.Http.HttpClient. The post request returns 200, but the file didn’t upload. The URL links to a folder on the company’s web hosting platform. If I check the page or the bluehost cpanel page, there are no recent file uploads to correspond with the app’s supposedly successful request. How do I upload a file to the server? Do I need to provide login credentials? Does Microsoft UWP even support FTP anymore? It really only wants me to use HttpClient.

I’ve tried various methods, but this one (which I mostly translated from Microsoft’s example C++ code for uploading a simple file) is the first time it hasn’t returned a 405 or just dumped the contents of the url. I have tried using the HttpWebRequest format and the System.Net.Http prefix.

fileOpenPicker.FileTypeFilter.Add(".json");
IStorageFile jsonFile = await fileOpenPicker.PickSingleFileAsync();
IRandomAccessStream stream = await jsonFile.OpenAsync(FileAccessMode.Read);
Windows.Web.Http.HttpStreamContent jsonContent = new HttpStreamContent(stream);

jsonContent.Headers.Append("Content-Type", "application/json");

Windows.Web.Http.Headers.HttpContentDispositionHeaderValue disposition = new Windows.Web.Http.Headers.HttpContentDispositionHeaderValue("form-data");
jsonContent.Headers.ContentDisposition = disposition;

disposition.Name ="fileForUpload";
disposition.FileName = "testSurveyFile.json";

Windows.Web.Http.HttpMultipartFormDataContent postContent = new HttpMultipartFormDataContent();
postContent.Add(jsonContent); // Add the binary data content as a part of the form data content.

Windows.Web.Http.HttpResponseMessage httpResponseMessage;
string httpResponseBody;

try
{

    // Send the POST request.
    Uri requestUri = new Uri(uploadurl);
    Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient();
    httpResponseMessage = await httpClient.PostAsync(requestUri, postContent);
    httpResponseMessage.EnsureSuccessStatusCode();
    Debug.WriteLine(httpResponseMessage);
    httpResponseBody = httpResponseMessage.Content.ReadAsStringAsync().GetResults();
}
catch (Exception ex)
{
    Debug.WriteLine(ex);
}

This is what httpResponseMessage returns:

StatusCode: 200, 
ReasonPhrase: '', 
Version: 3, 
Content: Windows.Web.Http.HttpStreamContent, 
Headers:
{
  server: nginx/1.14.1
  cache-control: no-store, no-cache, must-revalidate
  set-cookie: PHPSESSID=4f21dec8695cea2b75d009c47d9b94bb; path=/
  date: Fri, 02 Aug 2019 15:28:34 GMT
  pragma: no-cache
}{
  content-type: text/html; charset=UTF-8
  expires: Thu, 19 Nov 1981 08:52:00 GMT
}

but there is no new file at the location.

To clarify, the files are hosted on bluehost. If I can’t POST to bluehost regularly (like I can with this site: http://ptsv2.com/t/gizn2-1564768263/d/373971039#) then how do I get around that? It is an https:// prefix, does the s mean I need credentials or certifications for ssl? Where or how could I find that out?

This is the output of httpResponseBody, the testSurveyFile.json file is an old one this upload is meant to replace or overwrite. This is the correct index. I hope this information clears some things up.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /npjTest/SurveyStuff</title>
 </head>
 <body>
<h1>Index of /npjTest/SurveyStuff</h1>
  <table>
   <tr><th valign="top">&nbsp;</th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top">&nbsp;</td><td><a href="/npjTest/">Parent Directory</a>       </td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="TestSurvey0/">TestSurvey0/</a>           </td><td align="right">2019-07-26 11:51  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="blankHTMLPage.html">blankHTMLPage.html</a>     </td><td align="right">2019-07-22 10:25  </td><td align="right">4.7K</td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="composer.json">composer.json</a>          </td><td align="right">2019-07-15 08:00  </td><td align="right"> 60 </td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="composer.lock">composer.lock</a>          </td><td align="right">2019-07-15 08:00  </td><td align="right">2.2K</td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="error_log">error_log</a>              </td><td align="right">2019-07-31 09:19  </td><td align="right">9.5K</td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="surveyConfig.php">surveyConfig.php</a>       </td><td align="right">2019-07-30 10:12  </td><td align="right">675 </td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="surveyFinalPage.php">surveyFinalPage.php</a>    </td><td align="right">2019-07-31 14:35  </td><td align="right"> 12K</td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="surveyLogic.php">surveyLogic.php</a>        </td><td align="right">2019-07-31 14:34  </td><td align="right">9.8K</td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="testSurveyFile.json">testSurveyFile.json</a>    </td><td align="right">2019-07-31 14:37  </td><td align="right">4.0K</td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="testSurveyPage.html">testSurveyPage.html</a>    </td><td align="right">2019-07-22 12:18  </td><td align="right">4.7K</td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="vendor/">vendor/</a>                </td><td align="right">2019-07-15 07:59  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top">&nbsp;</td><td><a href="vendorZIP2.zip">vendorZIP2.zip</a>         </td><td align="right">2019-07-15 07:58  </td><td align="right">2.6M</td><td>&nbsp;</td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
<address>Apache Server at ___________.com Port 443</address>
</body></html>

It seems like I should be doing an HTTP PUT request instead of a POST. I had considered it and tried running PutAsync instead, but I’m getting errors related to redirects. Specifically, if I turn AllowAutoRedirect to false (to bypass an error stating that ‘The HTTP redirect request must be confirmed by the user’) it comes back with a 301 response code. I’m not sure why it’s redirecting. When I send the uri, should that uri go to the index (/SurveyStuff) or the file I want it to overwrite (/SurveyStuff/testSurveyFile.json)?

If I use the uri ending in /SurveyStuff/testSurveyFile.json for a PUT request I get a 405 (Not Allowed) response. I realize this what I should have been doing from the beginning, though I did try it before coming here. This response is returned from both Postman and my app. Is it bluehost that’s blocking the request for security purposes? I’ve tried various FTP and site credentials, but they haven’t made a difference.

2

Answers


  1. Chosen as BEST ANSWER

    I spoke with bluehost support for a second time, and this time they said bluehost does not support HTTP POST requests from any external source, including Postman. It seems I'll need to find another place to host this file. I apologize for my confusion on this point. I appreciate the help, as it improved my understanding of HTTP requests and web programming in general. Thank you very much.


  2. Disclaimer: I must admit I know very little about Windows.Web.Http.HttpClient. Here are some potential fixes, and if those don’t work, some other solutions.

    405 Issue:

    • If you were receiving a 405 error, I would double check the url that
      you are sending it to and make sure it’s correct, and can accept POST
      requests.
    • I would also check to see if you require a VPN connection to use that
      url or not (try to hit it from a web browser).

    Credential Issue:
    Although this would be odd, because usually you would receive a 401 (unauthorized) error code, you might want to include credentials just to be safe.

    For System.Net.Http.HttpClient Credentials:

    var httpClientHandler = new HttpClientHandler()
    {
        Credentials = new NetworkCredential(username, password, domainName),
    };
    
    var httpClient = new HttpClient(httpClientHandler);
    

    Solution #1: System.Net.Http.HttpClient multipart-form data (this).

    IInputStream inputStream = await file.OpenAsync(FileAccessMode.Read);
    
    HttpMultipartFormDataContent multipartContent = new HttpMultipartFormDataContent();
    
    multipartContent.Add(new HttpStreamContent(inputStream),"myFile",file.Name);
    
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.PostAsync(uri,multipartContent);
    

    Solution #2 System.Net.Http.HttpClient multipart-form data (this).

    You’ll have to tweak this a bit as he is uploading an image as a byte array, and I would suggest using more Using statements as they automatically dispose the object.

    You could convert your file to a byte array if you wish:

    byte[] bytes = System.IO.File.ReadAllBytes(filename);
    

    Solution #3 If those do not work, you can try some alternative methods:

    I hope this at least puts you on the right track :).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search