Программно изменить встроенный ресурс перед регистрацией / ссылкой на него на странице
Во-первых, "изменение" может быть неправильным термином, я вижу, что несколько человек разместили в Интернете только вопрос, могут ли они действительно изменить встроенный ресурс. То, что я хочу, это использовать ресурс в моей сборке как своего рода шаблон, который я бы нашел и заменил до регистрации на странице - возможно ли это?
Например; скажем, у меня есть несколько строк jQuery в качестве встроенного ресурса в моей сборке, и в этом сценарии я ссылаюсь на имя класса CSS, которое может быть задано программистом интерфейса. Поскольку я не знаю, каким будет класс CSS до реализации, есть ли способ пройти через встроенный ресурс и заменить, скажем, $myclass$ на ThisClassName.
Буду признателен за любую помощь, если это невозможно, по крайней мере, скажите мне, чтобы я мог перестать преследовать свой хвост.
2 ответа
Я решил свою маленькую проблему, создав HTTP-обработчик. В этом случае он называется DynamicClientScript.axd.
Я взял несколько фрагментов из своего кода, чтобы дать вам идею. Приведенный ниже код получает стандартный URL-адрес встроенного ресурса и берет из него строку запроса для добавления к пути к моему обработчику.
/// <summary>
/// Gets the dynamic web resource URL to reference on the page.
/// </summary>
/// <param name="type">The type of the resource.</param>
/// <param name="resourceName">Name of the resource.</param>
/// <returns>Path to the web resource.</returns>
public string GetScriptResourceUrl(Type type, string resourceName)
{
this.scriptResourceUrl = this.currentPage.ClientScript.GetWebResourceUrl(type, resourceName);
string resourceQueryString = this.scriptResourceUrl.Substring(this.scriptResourceUrl.IndexOf("d="));
DynamicScriptSessionManager sessMngr = new DynamicScriptSessionManager();
Guid paramGuid = sessMngr.StoreScriptParameters(this.Parameters);
return string.Format("/DynamicScriptResource.axd?{0}¶mGuid={1}", resourceQueryString, paramGuid.ToString());
}
/// <summary>
/// Registers the client script include.
/// </summary>
/// <param name="key">The key of the client script include to register.</param>
/// <param name="type">The type of the resource.</param>
/// <param name="resourceName">Name of the resource.</param>
public void RegisterClientScriptInclude(string key, Type type, string resourceName)
{
this.currentPage.ClientScript.RegisterClientScriptInclude(key, this.GetScriptResourceUrl(type, resourceName));
}
Затем обработчик берет свою строку запроса для построения URL-адреса стандартного ресурса. Читает ресурс и заменяет каждый ключ его значением в коллекции словарей (DynamicClientScriptParameters).
ParamGuid - это идентификатор, используемый для получения правильной коллекции параметров скрипта.
Что делает обработчик...
public void ProcessRequest(HttpContext context)
{
string d = HttpContext.Current.Request.QueryString["d"];
string t = HttpContext.Current.Request.QueryString["t"];
string paramGuid = HttpContext.Current.Request.QueryString["paramGuid"];
string urlFormatter = "http://" + HttpContext.Current.Request.Url.Host + "/WebResource.axd?d={0}&t={1)";
// URL to resource.
string url = string.Format(urlFormatter, d, t);
string strResult = string.Empty;
WebResponse objResponse;
WebRequest objRequest = System.Net.HttpWebRequest.Create(url);
objResponse = objRequest.GetResponse();
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
strResult = sr.ReadToEnd();
// Close and clean up the StreamReader
sr.Close();
}
DynamicScriptSessionManager sessionManager = (DynamicScriptSessionManager)HttpContext.Current.Application["DynamicScriptSessionManager"];
DynamicClientScriptParameters parameters = null;
foreach (var item in sessionManager)
{
Guid guid = new Guid(paramGuid);
if (item.SessionID == guid)
{
parameters = item.DynamicScriptParameters;
}
}
foreach (var item in parameters)
{
strResult = strResult.Replace("$" + item.Key + "$", item.Value);
}
// Display results to a webpage
context.Response.Write(strResult);
}
Затем в своем коде, где я хочу сослаться на свой ресурс, я использую следующее.
DynamicClientScript dcs = new DynamicClientScript(this.GetType(), "MyNamespace.MyScriptResource.js");
dcs.Parameters.Add("myParam", "myValue");
dcs.RegisterClientScriptInclude("scriptKey");
Тогда скажите, что мой ресурс сценария содержит:
alert('$myParam$');
Он выведет, как если бы это было:
alert('myValue');
Мой код также выполняет некоторое кэширование (используя DynamicScriptSessionManager), но вы поняли идею...
ура
В своем коде вы можете читать содержимое встроенного ресурса, выключать все, что хотите, а затем записывать новое содержимое в ответ. Что-то вроде этого:
protected void Page_Load(object sender, EventArgs e)
{
string contents = ReadEmbeddedResource("ClassLibrary1", "ClassLibrary1.TestJavaScript.js");
//replace part of contents
//write new contents to response
Response.Write(String.Format("<script>{0}</script>", contents));
}
private string ReadEmbeddedResource(string assemblyName, string resouceName)
{
var assembly = Assembly.Load(assemblyName);
using (var stream = assembly.GetManifestResourceStream(resouceName))
using(var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}