简体   繁体   English

从JavaScript调用代码隐藏函数,该函数可能返回另一个JavaScript函数

[英]Calling a code-behind function from JavaScript that may return another JavaScript function

I have a problem with this that works for one button and not for another. 我对此有一个问题,该问题适用于一个按钮而不适用于另一个按钮。

The one that works is a button that calls a ModalPopup to add a new row to a GridView inside an UpdatePanel. 一个有效的按钮是一个调用ModalPopup的按钮,用于在UpdatePanel内的GridView中添加新行。 If it's successful, it pops up an alert with a message, else another alert with the Exception message. 如果成功,它会弹出一条带有消息的警报,否则会弹出另一条带有Exception消息的警报。 The code is very similar to the other one's, except it's in a ModalPopupExtender. 除了在ModalPopupExtender中,该代码与其他代码非常相似。

The button that throws the known exception about the EventValidation goes as follow: 引发有关EventValidation的已知异常的按钮如下:

Web: 网页:

<asp:Button ID="btnAlquilar" runat="server" Text="Alquilar" CssClass="AdminButtons"
                                 OnClientClick="Click_Alquilar(); return false"/>

The JavaScript function it calls 它调用的JavaScript函数

function Click_Alquilar() {
        if (index == '') {
            alert("Debe elegir una película para alquilar");
        }
        else {

            if (confirm("¿Quiere alquilar la película '" + selected.childNodes[2].innerText + "'?")) {
                __doPostBack('<%= btnAlquilar.UniqueID %>', index);
            }
        }
    }

Where index is the index of the selected row in the GridView (done with a similar architecture, and works fine). 其中index是GridView中选定行的索引(具有相似的体系结构,并且工作正常)。

The code-behind starts in the Page_Load method, and calls the function I'm having trouble with: 后面的代码从Page_Load方法开始,并调用我遇到问题的函数:

 protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {...}
            else
            {
                ProcessAjaxPostBack(sender, e);
            }
        }
private void ProcessAjaxPostBack(object sender, EventArgs e)
        {
            if ((Request.Params["__EVENTTARGET"] != null) && (Request.Params["__EVENTARGUMENT"] != null))
            {
                ...

                if (Request.Params["__EVENTTARGET"] == this.btnAlquilar.UniqueID)
                {
                    index = Convert.ToInt32(Request.Params.Get("__EVENTARGUMENT").TrimStart('r', 'o', 'w'));
                    btnAlquilar_Click(Request.Params.Get("__EVENTARGUMENT"));
                }    

            }
        }

protected void btnAlquilar_Click(string id)
        {
            string message = "";
            if (BAC.BAC.CheckUserAge(lblUserId.Text) < Convert.ToInt32(dgvPeliculas.Rows[index].Cells[7].Text))
            {
                btnBorrar.Visible = false;
                btnEditar.Visible = false;
                btnNuevo.Visible = false;
                System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), Guid.NewGuid().ToString(), "alert('No tiene la edad mínima para alquilar la película.')", true);
            }
            else
            {
                try
                {
                    BAC.BAC.NewAlquiler(lblUserId.Text, dgvPeliculas.Rows[index].Cells[0].Text, dgvPeliculas.Rows[index].Cells[9].Text);
                }
                catch (Exception ex)
                {
                    message = Change_ExceptionMessage(ex.Message);
                    System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), Guid.NewGuid().ToString(), "alert('No se pudo alquilar la película: " + message + "')", true);
                }
            }

        }

The RegisterClientScriptBlock method is THE SAME I use for the other button (which doesn't do anything more complex than this one: if things are wrong, it changes the text of a label in the Popup and shows the alert; if it's right, it loads the GridView and shows the success alert), and works there. RegisterClientScriptBlock方法与我在其他按钮上使用的方法相同(该按钮的功能比该按钮更复杂:如果发生错误,它将更改弹出窗口中标签的文本并显示警报;如果正确,则将其显示出来)。加载GridView并显示成功警报),并在那里工作。 Here, it throws the exception "EnableEventValidation is true so...". 在这里,它将引发异常“ EnableEventValidation为true,所以...”。 I have this button registered for Event Validation on Render: 我已将此按钮注册为“渲染时的事件验证”:

protected override void Render(HtmlTextWriter writer)
        {
            this.Page.ClientScript.RegisterForEventValidation(btnAlquilar.UniqueID);
            base.Render(writer);
        }

So why does this happen here? 那么,为什么会在这里发生呢? Why it doesn't work this time? 为什么这次不起作用?

EDIT: Now that I check, the label changed by the working button in the ModalPopup is wrapped in an UpdatePanel. 编辑:现在,我检查,由ModalPopup中的工作按钮更改的标签包装在UpdatePanel中。 I don't know if it matters, but just to note it. 我不知道这是否重要,只是要注意一下。

EDIT2: The page also works within a Master page. EDIT2:该页面也可以在母版页中使用。 Don't know if it's of any use. 不知道这有什么用。 I have tried wrapping both the Edit button and the GridView with UpdatePanels and using AsyncPostBackTrigger, but still I get the same exception. 我试过用UpdatePanels包裹Edit按钮和GridView并使用AsyncPostBackTrigger,但是我仍然遇到同样的异常。

OK, for those who are interested in it, the problem was with the _ doPostBack calls. 好的,对于那些对此感兴趣的人,问题出在_ doPostBack调用上。 Since the arguments I passed ( _EVENTARGUMENT) were dynamic, I could never register those events through the RegisterForEventValidation method, becuase it asks for two constant strings (AFAIK): the control's UniqueID and the argument it will be passed with it. 由于我传递的参数( _EVENTARGUMENT)是动态的,因此我永远无法通过RegisterForEventValidation方法注册这些事件,因为它要求两个常量字符串(AFAIK):控件的UniqueID和将随其传递的参数。

So, I stopped passing arguments to the doPostBack other than the button's UniqueID, and passed the variables I was interested in through other media (cheifly, hidden fields values to global variables inside the Page class). 因此,我停止了将参数传递给doPostBack而不是按钮的UniqueID,并通过其他媒体传递了我感兴趣的变量(例如,将隐藏字段值传递给了Page类中的全局变量)。

That solved the problem and made the program work as intended. 那解决了问题,并使程序按预期工作。 I wrapped the buttons inside the same update panel than the GridView so as to not generate an AutoPostBack and change the Grid's values without having to refresh. 我将按钮包装在与GridView相同的更新面板中,以便不生成AutoPostBack并无需刷新即可更改Grid的值。

If anybody is interested in the code, I can provide. 如果有人对代码感兴趣,我可以提供。

OnClientClick="Click_Alquilar(); return false"
instead of this use
OnClientClick="return Click_Alquilar();


and in javascript
use return false;
in functions like

function Click_Alquilar() {
        if (index == '') {
            alert("Debe elegir una película para alquilar");
return false;
        }
        else {

            if (confirm("¿Quiere alquilar la película '" + selected.childNodes[2].innerText + "'?")) {
                __doPostBack('<%= btnAlquilar.UniqueID %>', index);
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM