Editing extension source code
You might say – editing source code is easy. Just open Visual Studio and start typing. Not so fast – what if I want to do it online, the way WordPress plug-in manager does it? Let’s say I uploaded extension and it seems to have a bug or I want to make a quick change and I don’t have access to do it over FTP. Is this even possible remotely change code for compiled assembly, save your changes and make application use new code? Let’ try it.
I added new “Edit” link to each extension in the list (if you don’t know what I’m talking about see previous post on Extension Manager). Then I created user control inside “User controls/xmanager” folder named “SourceEditor.ascx”. This is a simple control that have a multi-line text box and a save button. When “Edit” link clicked, page will load this control and fill it up from the source file. It will look inside “~/App_code/extensions” for the file with the same name as extension name. It is not required to put your extensions there, but it is a common convention. If source for extension in some other place – we won’t bother, just show relevant message and disable save button.
When source file found, it will show up in the text box and you can edit it and click save button. One catch here is that you need to disable validation on the page; otherwise ASP will not let you submit control to prevent code injection. Once validation knows that we are good guys and not sending evil things to the server, it all works as a charm. Here is entire code for control that let you easily edit source code for extension from admin panel. It is pretty short and self-explanatory. And you don’t even have to reload application this time; because we changed file in the app_code folder, IIS automatically will kick in jitter to re-compile assembly and start using modified extension.
protected void Page_Load(object sender, EventArgs e)
{
btnSave.Enabled = true;
txtEditor.Text = ReadFile(GetExtFileName());
}
protected void btnSave_Click(object sender, EventArgs e)
{
string ext = Request.QueryString["ext"];
WriteFile(GetExtFileName(), txtEditor.Text);
Response.Redirect("Default.aspx");
}
string GetExtFileName()
{
string ext = Request.QueryString["ext"];
string fileName = HttpContext.Current.Request.PhysicalApplicationPath;
fileName += "App_Code\\Extensions\\" + ext + ".cs";
return fileName;
}
string ReadFile(string fileName)
{
string val = "Source for [" + fileName + "] not found";
try
{
val = File.ReadAllText(fileName);
}
catch (Exception)
{
btnSave.Enabled = false;
}
return val;
}
static bool WriteFile(string fileName, string val)
{
try
{
StreamWriter sw = File.CreateText(fileName);
sw.Write(val);
sw.Close();
}
catch (Exception)
{
return false;
}
return true;
}