Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have a WebPostRequest class which looks like this:

public class WebPostRequest
{
    public const string Success = "OK";

    private WebRequest _webRequest;
    private List<string> _paramsList;

    public WebPostRequest(string url)
    {
        try
        {
            _webRequest = WebRequest.Create(url);
        }
        catch (Exception)
        {
            throw;
        }
        _webRequest.Method = "POST";
        _webRequest.ContentType = "application/x-www-form-urlencoded";
        _paramsList = new List<string>();
    }

    public void Add(string key, string value)
    {
        _paramsList.Add(String.Format("{0}={1}", key, HttpUtility.UrlEncode(value)));
    }

    public void UploadPdf(string postKey, string name, params UserControl[] userControls)
    {
        string fileName = FileHelper.GetTimestampedName(name, "pdf");
        string filePath = PdfHelper.Save(fileName, userControls);
        FtpHelper.UploadFile(filePath);
        this.Add(postKey, fileName);
    }

    public void UploadImage(string postKey, string name, Image image)
    {
        if (image != null)
        {
            string fileName = FileHelper.GetTimestampedName(name, "jpg");
            FtpHelper.UploadFile(fileName, image.ToByteArray());
            this.Add(postKey, fileName);
        }
    }

    public string GetResponse()
    {
        // Build a string containing all the parameters
        string parameters = String.Join("&", _paramsList.ToArray());
        _webRequest.ContentLength = parameters.Length;

        try
        {
            // Write the parameters into the request
            using (StreamWriter streamWriter = new StreamWriter(_webRequest.GetRequestStream()))
            {
                streamWriter.Write(parameters);
            }

            // Execute the query
            HttpWebResponse httpWebResponse = (HttpWebResponse)_webRequest.GetResponse();
            StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
            return streamReader.ReadToEnd();
        }
        catch (Exception)
        {
            throw;
        }
    }
}

The WebPostRequest class uses a WebRequest object to POST to a web server and get the response.

The class is used like this:

bool success = false;
try
{
    WebPostRequest webPostRequest = new WebPostRequest(url);

    webPostRequest.Add("key_1", "value_1");
    webPostRequest.Add("key_2", "value_2");

    webPostRequest.UploadPdf("key_3", "pdf_name_1", userControl1);
    webPostRequest.UploadPdf("key_4", "pdf_name_2", userControl2);

    webPostRequest.UploadImage("key_5", "picture_name_1", image1);
    webPostRequest.UploadImage("key_6", "picture_name_1", image2);

    string response = webPostRequest.GetResponse();
    if (response != WebPostRequest.Success)
    {
        throw new Exception(response);
    }
    success = true;
}
catch (Exception ex)
{
    //display error messaage
}
if (success)
{
    //display success message
}

What i would like to do is add a window to display a status message and a progress bar (with marquee style). The window needs to be displayed from the WebPostRequest class, because this class is used in multiple locations in the app. The uploading tasks which may take a long time need to be executed on a different thread so that the UI thread remains responsive. Note that all the files need to be uploaded before the POST is made, so the GetResponse method needs to wait for the uploading tasks to finish. Note also that the helper methods can throw errors which are handled outside the WebPostRequest class.

What tips/suggestions can you give me? Any idea is appreciated.

share|improve this question

closed as off-topic by Jamal May 24 at 2:21

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." – Jamal
If this question can be reworded to fit the rules in the help center, please edit the question.

1 Answer 1

up vote 1 down vote accepted

I would not show any UI from WebPostRequest. For a fast solution you can just wrap the whole upload part and provide some sort of a listener whose methods will be called to notify about progress.

Thus WebPostRequest will not know nothing about UI layer. UI will not be blocked and be able to track upload progress.

Here's a C#-like pseudo code that illustrates what I mean:

class ProgressListener
{
    public void OnProgress(OperationContext)
    {
        //notiy UI in the thread-safe way -> use Control.Invoke for Windows Forms
    }

    public void OnFinish(OperationContext)
    {
        //show success message in UI
    }

    public void OnError(OperationContext)
    {
        //show detailed error message in UI
    }
}

//on UI class
void PerformUpload()
{

    ProgressListener listener = new ProgressListener(Form f);

    Thread thread = new Thread(() =>
    {
        try
        {
            try
            {
                WebPostRequest webPostRequest = new WebPostRequest(url);
                webPostRequest.Add("key_1", "value_1");
                webPostRequest.Add("key_2", "value_2");

                webPostRequest.UploadPdf("key_3", "pdf_name_1", userControl1);

                listener.OnProgress( /*operaton context*/)

                webPostRequest.UploadPdf("key_4", "pdf_name_2", userControl2);

                listener.OnProgress( /*operaton context*/)
                webPostRequest.UploadImage("key_5", "picture_name_1", image1);

                listener.OnProgress( /*operaton context*/)
                webPostRequest.UploadImage("key_6", "picture_name_1", image2);

                listener.OnProgress( /*operaton context*/)

                string response = webPostRequest.GetResponse();
                if (response != WebPostRequest.Success)
                {
                    listener.OnProgress( /*operaton context*/)

                    throw new Exception(response);
                }
                success = true;

                listener.OnFinish( /*operaton context*/)
            }
            catch (Exception ex)
            {
                listener.OnError( /*operaton context*/)
                //display error messaage
            }       
        }
        catch(Exception ex)
        {
            listener.OnError( /*operaton context*/)
            //logging
        }
    });

    thread.Name = "uploader";
    thread.Start();
}
share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.