Search code examples
c#methodspropertiesftpinvalidoperationexception

Change WebRequest's Method property (C#)


Is there a better way for changing the Method property of WebRequests after uploading a file than mine?

My way looks like this:

WebRequest request = WebRequest.Create("ftp://.../...txt");
request.Credentials = new NetworkCredential("...", "...");
request.Method = WebRequestMethods.Ftp.UploadFile;

// Then I write to the request stream with StreamWriter

// Try reading
request.Method = WebRequestMethods.Ftp.DownloadFile;
    // If I only change the Method property, the next line throws an InvalidOperationException

StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream(), true);

Solution

  • Objects created by WebRequest.Create can be used only once, so you need to create new one to send another request.

    var someLocation = "ftp://.../...txt";
    WebRequest request = WebRequest.Create(someLocation);
    request.Credentials = new NetworkCredential("...", "...");
    request.Method = WebRequestMethods.Ftp.UploadFile;
    // Then I write to the request stream with StreamWriter
    
    // Create new request with the same parameters:
    WebRequest request = WebRequest.Create(someLocation);
    request.Credentials = new NetworkCredential("...", "...");
    request.Method = WebRequestMethods.Ftp.DownloadFile;
    using(StreamReader reader = 
       new StreamReader(request.GetResponse().GetResponseStream(), true))...
    

    Note that each request contains a other one-time objects like request stream and response stream (both are NetworkStream and don't support seek). If one would allow reuse of request created by WebRequest.Create it will require some resetting of all related object which essentially the same as creating new one but with downside of being implicit result of changing Method (or Url, or headers or pretty much any other property on the object). Design of .Net classes prefer explicit actions over implicit. You'll find other examples like disposed objects like FileStream can't be magically restored back to original state y changing file location property.