jpeg to byte array, while conversion logic is inside if statement

I'm sure this is a very simple issue that even inexperienced developers would be able to do, but I'm just starting out.

I've put an if statement round the logic to convert a jpeg into a byte array so that the conversion doesn't happen unless there is a file selected. But this makes the variable logoBytes invisible to the data parameter. A colleague told me I would have to put the logic for the conversion into a method, and then reference that method somewhere, but I'm still rather confused.

        protected void btnSubmit_Click(object sender, EventArgs e)
    {
        Div1.Visible = true;

if (logoPrvw.Value != null)
{ 
    System.Drawing.Image img = System.Drawing.Image.FromFile(logoPrvw.Value);
    byte[] logoBytes;
    using (MemoryStream ms = new MemoryStream())
    {
        img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        logoBytes = ms.ToArray();
    }
}
TemplateData data = new TemplateData(txtSchemeCode.Text, txtVersion.Text, txtComment.Text, txtTemplateId.Text, logoBytes);

                if (ddSchemeCode.SelectedIndex == 0)
                {
                    lblCreated.Visible = true;
                    lblUpdated.Visible = false;
                    DataClass.addNewSchemeCode(data);
                }

                if (ddSchemeCode.SelectedIndex == 0 && ddVersion.SelectedIndex != 0)
                {
                    lblCreated.Visible = true;
                    lblUpdated.Visible = false;
                    DataClass.addNewVersion(data);
                }

                if (ddSchemeCode.SelectedIndex != 0 && ddVersion.SelectedIndex == 0)
                {
                    lblUpdated.Visible = true;
                    lblCreated.Visible = false;
                    DataClass.UpdateData(data);
                }

Here is the TemplateData class

    public class TemplateData
{
    public byte[] Logo { get; set; }
    public string TemplateId { get; set; }
    public string SchemeCode { get; set; }
    public string Version { get; set; }
    public string Comment { get; set; }

    public TemplateData(string schemeCode, string version, string comment, string templateID, byte[] logo)
    {
        SchemeCode = schemeCode;
        Version = version;
        Comment = comment;
        TemplateId = templateID;
        Logo = logo;

    }

    public TemplateData(SqlDataReader dr)
    {
        initialiseData();
        if (dr.HasRows)
        {
                Version = dr["Version"].ToString();
                Logo = (byte[])dr["Logo"];                 
                TemplateId = dr["TemplateId"].ToString();
                Comment = dr["Comment"].ToString();
                SchemeCode = dr["SchemeCode"].ToString();
        }
    }
Jon Skeet
people
quotationmark

Well, you need to declare the logoBytes variable outside the if statement so that it's still in scope when you create the TemplateData. You need to decide what value it should have if there isn't a file provided. For example, you might want it to be null, or maybe an empty array. You could either give the variable an initial value, or use an else clause. Examples:

byte[] logoBytes = null;
if (logoPrvw.Value != null)
{
    ...
    // Code that assigns a different value to logoBytes
}
TemplateData data = new TemplateData(..., logoBytes);

or:

byte[] logoBytes;
if (logoPrvw.Value != null)
{
    ...
    // Code that assigns a value to logoBytes
}
else
{
    logoBytes = new byte[0];
}
TemplateData data = new TemplateData(..., logoBytes);

I would then recommend refactoring the "work out logoBytes" code into a separate method, so you'd have:

byte[] logoBytes = GetLogoBytes(logoPrvw);
TemplateData data = new TemplateData(...);

Then your GetLogoBytes method can just be something like:

byte[] GetLogoBytes(HtmlInputFile logoPrvw)
{
    if (logoPrvw.Value == null)
    {
        return null; // Or an empty array, or whatever
    }
    using (Image img = ...)
    {
        using (MemoryStream ms = new MemoryStream())
        {
           img.Save(ms, ImageFormat.Jpeg);
           return ms.ToArray();
        }
    }
}

Note that you don't want to use Image.FromFile - you want to use the data which is in the posted file, so probably Image.FromStream(logoPrvw.PostedFile.InputStream)

people

See more on this question at Stackoverflow