覆盖 WebResource javascript 方法 - WebForm_InitCallback()
Override WebResource javascript method - WebForm_InitCallback()
我受困于 ASP.NET 中的回调和多 select select 控件。正如我所注意到的,Microsoft 自 2006 年以来就有一个错误(!),当我对 select 离子为 1,2,3 的 multiselect 执行回调时,回发数据为 1,1,1 .
我已经确定了问题,它在以下方法中:
function WebForm_InitCallback() {
var formElements = theForm.elements,
count = formElements.length,
element;
for (var i = 0; i < count; i++) {
element = formElements[i];
var tagName = element.tagName.toLowerCase();
if (tagName == "input") {
var type = element.type;
if ((__callbackTextTypes.test(type) || ((type == "checkbox" || type == "radio") && element.checked))
&& (element.id != "__EVENTVALIDATION")) {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
else if (tagName == "select") {
var selectCount = element.options.length;
for (var j = 0; j < selectCount; j++) {
var selectChild = element.options[j];
if (selectChild.selected == true) {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
}
else if (tagName == "textarea") {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
}
element.value
没有传递正确的值,但是 selectedChild.value
在 "select" 标签中。
尽管我已经找到问题所在,而且我知道如何重写此方法,但我不确定这是否会奏效。覆盖来自资源的 JavaScript 方法是否正确?你建议我这样做吗?
谢谢。
该代码被 Microsoft 视为遗留代码,除非他们认为这是一个关键问题,否则不会修复。
他们的解决方法是实现一个自定义的 http 模块,以便在将代码发送到浏览器之前更正代码。
- 创建自定义 http 模块
- 实施 ReleaseRequestState 事件
在其中输入以下代码:
void context_ReleaseRequestState(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
if (application != null)
{
if (application.Request.Url.ToString().Contains("WebResource.axd"))
{
#region Set private value of HttpWriter so we can write to output stream
//See http://daniel-richardson.blogspot.com/2008/11/how-to-apply-filter-to-content-returned.html
var response = application.Context.Response;
var httpWriterField = typeof(HttpResponse).GetField("_httpWriter",
BindingFlags.NonPublic | BindingFlags.Instance);
var ignoringFurtherWritesField = typeof(HttpWriter).GetField("_ignoringFurtherWrites",
BindingFlags.NonPublic | BindingFlags.Instance);
var httpWriter = httpWriterField.GetValue(response);
ignoringFurtherWritesField.SetValue(httpWriter, false);
#endregion
//We need to read filter property first or we get exception
var f = application.Response.Filter;
application.Response.Filter = new ResponseFilter(application.Response.OutputStream);
}
}
}
- 创建 class ResponseFilter 继承自 Stream class.
构造函数:
public ResponseFilter(Stream responseStream)
{
ResponseStream = responseStream;
}
写入方法:
public override void Write(byte[] buffer, int offset, int count)
{
string output = Encoding.UTF8.GetString(buffer, offset, count);
string fixedOutput = output.Replace(@"if (selectChild.selected == true) {
WebForm_InitCallbackAddField(element.name, element.value);", "if (selectChild.selected == true) {WebForm_InitCallbackAddField(element.name, selectChild.value);");
byte[] fixedBuffer = Encoding.UTF8.GetBytes(fixedOutput);
ResponseStream.Write(fixedBuffer, 0, fixedBuffer.Length);
}
- 实现其他抽象方法时只需调用 ResponseStream 的方法
我受困于 ASP.NET 中的回调和多 select select 控件。正如我所注意到的,Microsoft 自 2006 年以来就有一个错误(!),当我对 select 离子为 1,2,3 的 multiselect 执行回调时,回发数据为 1,1,1 . 我已经确定了问题,它在以下方法中:
function WebForm_InitCallback() {
var formElements = theForm.elements,
count = formElements.length,
element;
for (var i = 0; i < count; i++) {
element = formElements[i];
var tagName = element.tagName.toLowerCase();
if (tagName == "input") {
var type = element.type;
if ((__callbackTextTypes.test(type) || ((type == "checkbox" || type == "radio") && element.checked))
&& (element.id != "__EVENTVALIDATION")) {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
else if (tagName == "select") {
var selectCount = element.options.length;
for (var j = 0; j < selectCount; j++) {
var selectChild = element.options[j];
if (selectChild.selected == true) {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
}
else if (tagName == "textarea") {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
}
element.value
没有传递正确的值,但是 selectedChild.value
在 "select" 标签中。
尽管我已经找到问题所在,而且我知道如何重写此方法,但我不确定这是否会奏效。覆盖来自资源的 JavaScript 方法是否正确?你建议我这样做吗?
谢谢。
该代码被 Microsoft 视为遗留代码,除非他们认为这是一个关键问题,否则不会修复。
他们的解决方法是实现一个自定义的 http 模块,以便在将代码发送到浏览器之前更正代码。
- 创建自定义 http 模块
- 实施 ReleaseRequestState 事件
在其中输入以下代码:
void context_ReleaseRequestState(object sender, EventArgs e) { HttpApplication application = sender as HttpApplication; if (application != null) { if (application.Request.Url.ToString().Contains("WebResource.axd")) { #region Set private value of HttpWriter so we can write to output stream //See http://daniel-richardson.blogspot.com/2008/11/how-to-apply-filter-to-content-returned.html var response = application.Context.Response; var httpWriterField = typeof(HttpResponse).GetField("_httpWriter", BindingFlags.NonPublic | BindingFlags.Instance); var ignoringFurtherWritesField = typeof(HttpWriter).GetField("_ignoringFurtherWrites", BindingFlags.NonPublic | BindingFlags.Instance); var httpWriter = httpWriterField.GetValue(response); ignoringFurtherWritesField.SetValue(httpWriter, false); #endregion //We need to read filter property first or we get exception var f = application.Response.Filter; application.Response.Filter = new ResponseFilter(application.Response.OutputStream); } } }
- 创建 class ResponseFilter 继承自 Stream class.
构造函数:
public ResponseFilter(Stream responseStream)
{
ResponseStream = responseStream;
}
写入方法:
public override void Write(byte[] buffer, int offset, int count)
{
string output = Encoding.UTF8.GetString(buffer, offset, count);
string fixedOutput = output.Replace(@"if (selectChild.selected == true) {
WebForm_InitCallbackAddField(element.name, element.value);", "if (selectChild.selected == true) {WebForm_InitCallbackAddField(element.name, selectChild.value);");
byte[] fixedBuffer = Encoding.UTF8.GetBytes(fixedOutput);
ResponseStream.Write(fixedBuffer, 0, fixedBuffer.Length);
}
- 实现其他抽象方法时只需调用 ResponseStream 的方法