1

I'm trying to map an incoming URL from an ajax request to a web service method in the Global.asax. The web service is in this path /ajax/BookWebService.asmx, it has 2 methods GetListOfBook and GetListOfAuthor.

I want to use url: /ajax/book/list instead of url: /ajax/BookWebService.asmx/GetListOfBook in the Script tag.

Here's my script and mark-up:

<script type="text/javascript">

  $(function () {
      $("#btnCall").click(function () {

          $.ajax({type: "POST",
              url: "/ajax/book/list",
              data: "{}",
               contentType: "application/json; charset=utf-8",
               dataType: "json",
              success: function (response) {
                  var list = response.d;
                      $('#callResult').html(list);
              },
              error: function (msg) {
                  alert("Oops, something went wrong");
              }
          });

      });
  });

</script>

<div>
  <div id="callResult"></div>
  <input id="btnCall" type="button" value="Call Ajax" />
</div>

Here's the Global.asax :

void Application_BeginRequest(object sender, EventArgs e)
{
    var currentRequest = HttpContext.Current.Request.Url.AbsolutePath;

    if (currentRequest.Contains("ajax/book/list")) {
        HttpContext.Current.RewritePath("/ajax/BookWebService.asmx/GetListOfBook");
    }

}

When I check in FireBug console this is what I get :

"NetworkError: 500 Internal Server Error - localhost:13750/ajax/book/list"

If I change the url: /ajax/book/list to url: /ajax/BookWebService.asmx/GetListOfBook it works as expected.

I'm using VS 2010 and .NET 4.

How do I do ajax call to /ajax/book/list instead of /ajax/BookWebService.asmx/GetListOfBook?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Narazana
  • 1,940
  • 15
  • 57
  • 88
  • Wouldn't the Web API be a more fitting tool for the task? You can post data to the Web API method, with javascript, and by default it will return as JSON (using the content-type). Same for xml etc... An example http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api – Mike Sep 30 '12 at 17:35
  • Yes, indeed. But I have a small project that was built with ASMX that need a way to keep clean callback URL. – Narazana Sep 30 '12 at 17:37
  • If its a small project, shouldn't be difficult to convert over :P – Mike Sep 30 '12 at 17:41
  • Apparently this redirect correctly. Try that the method GetListOfBook returns a List or something, without logic. If redirection fails returns a 404 error – Mate Sep 30 '12 at 21:51
  • @Mate I did. But that method never gets called. It works if I call it directly. – Narazana Oct 01 '12 at 02:27
  • you could catch the error in Global.asax with ... void Application_Error(object sender, EventArgs e) { Console.WriteLine(Server.GetLastError().Message); } – Mate Oct 01 '12 at 03:28
  • Also I did that. But no error at all. I even used RewritePath in the Try and Catch block. but no error. – Narazana Oct 01 '12 at 13:13
  • Application_Error never fires for a web service. http://stackoverflow.com/a/211844/270536 – Narazana Oct 01 '12 at 15:04
  • I understand that the error occurs between RewritePath and before running the method, and not inside the method. Then Application_Error should catch the error. (eg if you invoke a page that does not exist, fires the Application_Error () and Server.GetLastError().Message returns "File does not exist"). I hope I can help ;) – Mate Oct 01 '12 at 23:21

1 Answers1

2

If you can change the ajax call to type: "GET", try this changes:

Ajax call:

    $(function () {
        $("#btnCall").click(function () {

            $.ajax({ type: "GET",  //Change 1
                url: "/ajax/book/list",
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (response) {
                    var list = response.d;
                    $('#callResult').html(list);
                },
                error: function (msg) {
                    alert("Oops, something went wrong");
                }
            });

        });
    });

</script>

Global.asax :

    void Application_BeginRequest(object sender, EventArgs e)
    {
        var currentRequest = HttpContext.Current.Request.Url.AbsolutePath;
        //Change 2
        if (currentRequest.Contains("ajax/book/")) // maybe you can use a generic path to all rewrites...
        {
            IgnoreWebServiceCall(HttpContext.Current);
            return;
        }
    }
    //Change 3
    private void IgnoreWebServiceCall(HttpContext context)
    {
        string svcPath = "/ajax/BookWebService.asmx";

        var currentRequest = HttpContext.Current.Request.Url.AbsolutePath;

        //You can use a switch or....
        if (currentRequest.Contains("ajax/book/list"))
        {
            svcPath += "/list";
        }

        int dotasmx = svcPath.IndexOf(".asmx");
        string path = svcPath.Substring(0, dotasmx + 5);
        string pathInfo = svcPath.Substring(dotasmx + 5);
        context.RewritePath(path, pathInfo, context.Request.Url.Query);
    }

BookWebService.asmx:

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [ScriptService] ///******************* Important
    public class BookWebService : System.Web.Services.WebService
    {

        [WebMethod]

        [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)] ///******************* Important
        public string list()
        {
          return "Hi";

        }

     }

Works for me :)

Mate
  • 4,976
  • 2
  • 32
  • 38
  • Yes, it works. I added IgnoreWebServiceCall to the Global.asax only. Everything else stays the same. Thanks. – Narazana Oct 02 '12 at 11:36