views:

639

answers:

2

Is it possible to add a new ServiceReference instance to the ScriptManager on the Page during an asynchronous postback so that subsequently I can use the referenced web service through client side script?

I'm trying to do this inside a UserControl that sits inside a Repeater, that's why adding the ScriptReference programmatically during Page_Load does not work here.

EDIT 2: This is the code I call from my UserControl which does not do what I expect (adding the ServiceReference to the ScriptManager during the async postback):

private void RegisterWebservice(Type webserviceType)
{
    var scm = ScriptManager.GetCurrent(Page);
    if (scm == null)
        throw new InvalidOperationException("ScriptManager needed on the Page!");

    scm.Services.Add(new ServiceReference("~/" + webserviceType.Name + ".asmx"));
}

My goal is for my my UserControl to be as unobtrusive to the surrounding application as possible; otherwise I would have to statically define the ServiceReference in a ScriptManagerProxy on the containing Page, which is not what I want.

EDIT:

I must have been tired when I wrote this post... because I meant to write ServiceReference not ScriptReference. Updated the text above accordingly.

Now I have:

<asp:ScriptManagerProxy runat="server" ID="scmProxy">
    <Services>
        <asp:ServiceReference Path="~/UsefulnessWebService.asmx" />
    </Services>
</asp:ScriptManagerProxy>

but I want to register the webservice in the CodeBehind.

+2  A: 

Try something like this...

if (ScriptManager.GetCurrent(this).IsInAsyncPostBack)
{
    ScriptManager.RegisterClientScriptInclude(this, this.GetType(), "script1", "~/js/myjs.js");
}
Krunal
Thanks for the example, Krunal, but actually I'm trying to add a ServiceReference to the ScriptManager. Sorry! Updated the post above.
Oliver
+2  A: 

Edit:

After checking your issue, Here is the reason why it is not working: When you add ServiceReference to ScriptManager > Services section manually in page. It adds 1 client script include directive.

e.g:

<script src="TestService.asmx/jsdebug" type="text/javascript"></script>

or

<script src="TestService.asmx/js" type="text/javascript"></script>

which provide you to accessibility to your Frontend.Web.YourScriptMethods,

Now when you add ServiceReference in async postback - It is not adding this client script inclue. So you get client script error - method is undefined.

But i figured out a workaround for this; (do not know it is right way to do it)

    if (ScriptManager.GetCurrent(this).IsInAsyncPostBack)
    {
        ScriptManager.RegisterClientScriptInclude(this, this.GetType(), "testservice", "TestService.asmx/js");
    }

You can replace the "TestService.asmx" path according to your project/web service.

This way you can achieve what you want.

Hope this helps,

Krunal Mevada


Old Ans:

Use following:

    if (ScriptManager.GetCurrent(this).IsInAsyncPostBack)
    {
        ScriptManager.GetCurrent(this).Services.Add(new ServiceReference("~/Service.asmx"));
    }
Krunal
This is what I am already doing (see my second EDIT note above). Unfortunately, for me it does not work as expected.
Oliver
@Oliver - How you are using service in the client side?? can you explain that?
Krunal
@Krunal - My webservice lives in the namespace Frontend.Web and carries the [ScriptService] attribute, and the method I call, Submit, carries [ScriptMethod(ResponseFormat = ResponseFormat.Json)]. Then in the client-side JavaScript I call 'Frontend.Web.Submit(arguments);' - that's it. Just that Frontend.Web.Submit is not defined on the client-side if I add the ServiceReference during async postback..
Oliver
@oliver have u tried this one?
Krunal
Hi Krunal, sorry for the delay ;) Finally tried your idea - unfortunately it didn't work bc the first line in the script ("Type.registerNamespace('Frontend.Web');") needs the Ajax scripts to be loaded. So I tried to use "ScriptManager.RegisterStartupScript(this, GetType(), "webservice", script, false);" where "var script = @"<script src=""/" + webserviceType.Name + @".asmx/js""></script>";" which works the first time it is loaded but throws "Sys.InvalidOperationException: Type Frontend.Web.UsefulnessWebService has already been registered." the next time. I'll leave it at that for now.
Oliver