Rectangle 27 5

First off, do not use, as a general rule of thumb, static variables in an web application. These act as global variables and are not instantiated with each request.

I wouldn't also suggest you using DataTables all the way up to your UI layer. Instead, work with strongly-typed objects.

  • Make a Model of the object you are trying to bind.

Like for example if you have a table called person that has the following fields.

Id | first_name | last_name | audit_ts

You can create an object as such:

public class Person
{
    public int Id {get;set;}
    public string FirstName {get;set;}
    public string LastName {get;set;}
}

c# - Can we use same datatable for pagemethod and webmethod in ASP.NET...

c# asp.net .net static webmethod
Rectangle 27 3

I found the solution to my problem: What prevented the WebMethod was called was the reference to "System.Web.Optimization". Not sure how he does it, but as I will not use it at the time, decided to remove:

"System.Web.Optimization" and "Microsoft.AspNet.Web.Optimization.WebForms"

It is also necessary to remove the web.config as follows:

<namespaces>
    <add namespace="System.Web.Optimization" />
</namespaces>

<add assembly="Microsoft.AspNet.Web.Optimization.WebForms" 

namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt" />

<dependentAssembly>
        <assemblyIdentity name="WebGrease" culture="neutral" 

publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>

All ok now! Thanks to everyone who helped me with the problem! :)

I tried the above but that made the ScriptManager stop working and I can't use the webopt tag.

asp.net - WebMethod not called (triggered) by PageMethod in Visual Stu...

asp.net vb.net visual-studio-2013 webmethod pagemethods
Rectangle 27 24

In classic ASP.NET you get a 401 http response code when calling a WebMethod with Ajax. I hope they'll change it in future versions of ASP.NET MVC. Right now I'm using this hack:

protected void Application_EndRequest()
{
    if (Context.Response.StatusCode == 302 && Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
    {
        Context.Response.Clear();
        Context.Response.StatusCode = 401;
    }
}

This is a really good stop-gap solution if you need something fast that works. Otherwise I'd would try to implement @troethom answer.

401 response code for json requests with ASP.NET MVC - Stack Overflow

asp.net-mvc
Rectangle 27 4

In ASP.NET WebForms i would use a ScriptService:

GenerateScriptType
[WebService(Namespace = "http://msdnmagazine.com/ws")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[GenerateScriptType(typeof(Object1))]
[GenerateScriptType(typeof(Object2))]
[ScriptService]
public class StockQuoteService : WebService
{
    static Random _rand = new Random(Environment.TickCount);

    [WebMethod]
    public int GetStockQuote(string symbol)
    {
        return _rand.Next(0, 120);
    }
}

Your sample shows how to call a web service and pass a single value, however it does not show how to pass an object (including properties).

c# - Can I send an object from client-side javascript to server-side c...

c# javascript asp.net vb.net
Rectangle 27 2

You are using the OnChange event to call the code behind method from javascript. To access the code behind method you need to convert that method to the WebMethod. For that below is something you can try (Just an example)

<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
     <asp:TextBox ID="txtLastName" runat="server"></asp:TextBox>
     <asp:TextBox ID="txtMsg" runat="server"></asp:TextBox>
<script type="text/javascript">
    function greet(txtN, txtLastN, txtMsg){
     var ctrlN = document.getElementById(txtN);
     var ctrlLastN = document.getElementById(txtLastN);
     var fullName = ctrlN.value + '  ' + ctrlLastN.value;
     PageMethods.greetUser(fullName, greetSuccess, greetFailed, txtMsg);
   }
  function greetSuccess(res, txtMsg) {
    var ctrlTxtMsg = document.getElementById(txtMsg);
    ctrlTxtMsg.value = res;
   }
  function greetFailed(res, dst) {
    alert(res.get_message());
   }
 </script>
<System.Web.Services.WebMethod()> _
      Public Shared Function greetUser(ByVal fullName As String) As String
         Return "Welcome " & fullName & "!"
     End Function

Now you can call your javascript function greet from wherever you want and it will trigger the code behind method greetUser. More on this is available here.

asp.net - How to call sub onchange of a dropdownlist while using AJAX?...

asp.net vb.net asp.net-ajax ajax.net
Rectangle 27 4

Notice that the method you are using as WebMethod is static, this should be the first hint to the fact that Page object is not created at all.

Page Methods is a simple alternative to full blown web services, and as such, its life cycle is more similar to web service than to page. That is, request goes through the general ASP.NET pipeline, with objects like HttpContext, Request and such. But then the difference happens: for page requests and postbacks page object is created and the whole series of page events happens, whereas for page methods page object is not created, and method is simply called as Server.AjaxAccessibleMethod().

There is really no way to mix the two, because this would unnecessarily complicate processing of calls to page methods. So the only path forward for you here is duplicate necessary code:

protected void Page_Load(object sender, EventArgs e)
{
    // code to set up DB connections
    ExternalLibrary.SetupDB(); 
}

[WebMethod]
public static string AjaxAccessibleMethod()
{
    ExternalLibrary.SetupDB();
    ...
}

how about adding "ExternalLibrary.SetupDB();" in a static constructor ? That way i think code duplication can be avoided.

@Boney, I wouldn't recommend using static constructor. The problem here is that you have absolutely no control on when it is going to be called. So it can happen too early for OP's needs. Besides, current code calls it once per request, and at least in case of page methods you cannot be certain this is going to happen with static c'tor

Thanks Andrei, What your saying makes perfect sense. But it still leaves me scratching my head over why this did work... and whats worrying me is that I have used this pattern elsewhere (and it works) - is there any mechanism that you are aware of that might allow this to happen, eg calling the page (rather than a [WebMethod]) and then subsequently calling the [WebMethod]?

@Morvael, I am not aware of such mechanism, and I'd love to see the case when it is happening - the explanation might be a bit different.

@Andrei, I've just been digging a bit deeper into the ExternalLibrary. It seems that the SetupDB() stuff is all static, and can persist between page calls. So it looks like, in this case, calling it once will be OK until the website re-compiles (i'm guessing), which explains why it sometimes works. Calling it each time seems to be the only reliable solution. Thanks again.

c# - ASPX Page Life Cycle when calling [WebMethod]s - Stack Overflow

c# asp.net ajax page-lifecycle
Rectangle 27 1

When you say that you have static methods on the page code-behind marked with WebMethod and you say that you use $.ajax, that sounds just wrong. But I'll give the benefit of the doubt, as I don't know the particularities of you system.

<asp:ScriptManager ID="smPageManager"
        runat="server"
        EnablePageMethods="true" 
        ScriptMode="Release" 
        LoadScriptsBeforeUI="true"> 
</asp:ScriptManager>
PageMethods.LeWebMethod("hero", 1024, function(response){
    alert(response);
}, function(error){
    alert(error);
});

Know using ASP.NET Ajax Library the proper way, give it a test, and see if the error reports back to you properly.

P.S: Sorry for the bookmark style notation, but SO, seems be experiencing some malfunction right now.

Reading this post, seems to explain the problem you are facing:

After the method has been called, the CompleteRequest method is called, bypassing all pipeline events and executing the EndRequest method. This allows MS AJAX to be able to call a method on a page instead of having to create a web service to call a method

Try to use the ASP.NET JavaScript Proxies, to check if you can capture the error using Microsoft Generated Code.

ajax - Catching errors from calling ASP.NET WebMethod with malformed J...

asp.net ajax error-handling webmethod
Rectangle 27 1

When you say that you have static methods on the page code-behind marked with WebMethod and you say that you use $.ajax, that sounds just wrong. But I'll give the benefit of the doubt, as I don't know the particularities of you system.

<asp:ScriptManager ID="smPageManager"
        runat="server"
        EnablePageMethods="true" 
        ScriptMode="Release" 
        LoadScriptsBeforeUI="true"> 
</asp:ScriptManager>
PageMethods.LeWebMethod("hero", 1024, function(response){
    alert(response);
}, function(error){
    alert(error);
});

Know using ASP.NET Ajax Library the proper way, give it a test, and see if the error reports back to you properly.

P.S: Sorry for the bookmark style notation, but SO, seems be experiencing some malfunction right now.

Reading this post, seems to explain the problem you are facing:

After the method has been called, the CompleteRequest method is called, bypassing all pipeline events and executing the EndRequest method. This allows MS AJAX to be able to call a method on a page instead of having to create a web service to call a method

Try to use the ASP.NET JavaScript Proxies, to check if you can capture the error using Microsoft Generated Code.

ajax - Catching errors from calling ASP.NET WebMethod with malformed J...

asp.net ajax error-handling webmethod
Rectangle 27 6

No, this is not the correct method. Since you have declared the DataTable as static (a static variable has application scope and cannot be instantiated) all

users will get the same result (last updated values).

You can realize this in concurrency testing.

Please check the following scenario:

Consider dtbl is the static dataTable which is initialized on the home page, and you create another instance instance of `datatable on the index page (both are in page load as given below).

public static DataTable dtbl;
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        dtbl = new DataTable();
        dtbl.Columns.Add("id");
        dtbl.Columns.Add("name");
        for (int i = 0; i < 10; i++)
        {
            DataRow dr = dtbl.NewRow();
            dr["id"] = i.ToString();
            dr["name"] = i + 1;
            dtbl.Rows.Add(dr);
        }
    }
}

Now put a breakpoint in each page load and run the application,

  • Open both the pages in separate tab.
  • Refresh the home page and check whether the columns are showing
  • Now go to next tab (index) and refresh it (a new instance is created for dt). It will affect the datatable now you will get the new datatable in home also.
  • So if these two processes/pages are concurrently executed the latest value will get for both the pages. That's why I am saying it will realize this in concurrency testing.

You can make use of a session in this case. Consider the following code:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        dtbl = new DataTable();
        dtbl.Columns.Add("id");
        dtbl.Columns.Add("name");
        for (int i = 0; i < 10; i++)
        {
            DataRow dr = dtbl.NewRow();
            dr["id"] = i.ToString();
            dr["name"] = i + 1;
            dtbl.Rows.Add(dr);
        }
        if (((DataTable)Session["MyDatatable"]).Columns.Count < 0)
        {
            Session["MyDatatable"] = dtbl;
        }
        else
        {
            dtbl = (DataTable)Session["MyDatatable"];
        }
    }
}

then how can i improve performance?any other way?

no separate datatable is created for individual users, All are sharing the same so will get the last updated value for all.

Report1 = new DataTable(); this won't work properly?say user1 access the page grid and graph shown.then user2 access new grid and graph will show right?

:Thanks for the detailed explanation.Is there any other way to sync the data between two?

Of course, you could use the same base data for all users via the Cache object (see my answer below), and perform your filter on the Cached results based on date, and return those filtered results to the client. You may get a performance gain by saving the round trip to the database on every call if you have enough server memory AND the datasets are large.

c# - Can we use same datatable for pagemethod and webmethod in ASP.NET...

c# asp.net .net static webmethod
Rectangle 27 1

You're just calling list.ToString(). That usually just results in the type name.

Instead, it's best to serialize to JSON. In my experience, ASMX/[WebMethod] doesn't handle that very well. You'll need to use a library to serialize it, the usual recommendation is Json.NET. Once you have that library and add the appropriate using statement using Newtonsoft.Json; to the top of your class, try changing your function to this:

[WebMethod]
    public static void TestAjax(string sEcho)
    {
        var list = new FormatedList();

        list.sEcho = sEcho;
        list.iTotalRecords = 1;
        list.iTotalDisplayRecords = 1;

        var item = new List<string>();
        item.Add("Gecko");
        list.aaData = new List<List<string>>();
        list.aaData.Add(item);
        string json=JsonConvert.SerializeObject(list);
        Response.ContentType= "application/json";
        Response.Write(json);
    }

By the way, have you thought about Web API? That's a better route to go down rather than ASMX/[WebMethod]. With a Web API function you can return list; and the framework will take care of converting the list to JSON (using Json.NET!) or XML depending on the content type requested.

Thanks for the answer. I'm used to MVC3+ and there things happen a lot more easier. I thought about the Web API but there are several legacy issues, including what the other people are familiar with so at the end it should be done by doing something like this. Thanks again for the help!

How to use Ajax calls from datatable in ASP.NET Web Forms project - St...

asp.net ajax webforms datatable
Rectangle 27 3

Yes. One way could be, to use a web method; for instance:

  • Create a service
DataService.Push(yourObject)
function btnGenerate_onclick(result) {
    DataService.Push(getDataFromSomeDiv(), onGenerateReportComplete /*callback method*/);
    //or
    //DataService.Push(document.getElementById("myDiv").innerHTML, onGenerateReportComplete /*callback method*/);

}

function onGenerateReportComplete(result) {
            alert("Success:" + result);
}
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class DataService : System.Web.Services.WebService
{

    [WebMethod(EnableSession = true)] //If you want?
    public bool Push(object someObject)
    {
        //var v = someObject as MyObjectClass;//Process object 
        return true;
    }
}

How would javascript know what is server-side DataService?

This will require reference of web service in the markup. For instance like following:

<asp:ScriptManager ID="sm" runat="server">
            <Services>
            <asp:ServiceReference Path="DataService.asmx" />
        </Services>
</asp:ScriptManager>

Or you can use callbacks/page methods.

You something missed. How would javascript know what is server-side DataService?

c# - Can I send an object from client-side javascript to server-side c...

c# javascript asp.net vb.net
Rectangle 27 2

Looking at the code sample that you have given (and the parameters date_from and date_to that you are passing to GetReportGraph()) I assume:

I'm not sure what functionality of grid view you are using. Is it used only to show read only tabular data? If yes, you can consider the approach given by @Nabin Karki Thapa. If not check the alternate approach below:

After you have got the data table and bound it to grid view, immediately serialize it to JSON and register it as a script block (define a JS variable and assign the serialized JSON as it's value).

On the client side, while charting, instead of invoking webmethod, to get the JSON object use the JS variable that you have registered. This way you will avoid the call to web method (AJAX) and extra stored procedure call altogether.

c# - Can we use same datatable for pagemethod and webmethod in ASP.NET...

c# asp.net .net static webmethod
Rectangle 27 2

This is a good use case for the little used Cache Object Many users understand ViewState and SessionState, however the Cache object is not as widely utilized, and although the concept is very similar, it is much more flexible.

If your page is calling 10 stored procedures twice (once for your grids and a second time for your charts) then lets improve the performance by roughly 100% by eliminating the extra calls with the Cache Object

Have one call to the stored procedures in a separate method that populate your data tables cache object, which is then reused throughout your application.

private void loadReport1IntoCache()
{
  //...load your data from DB into the Report1 variable here


  //this line is new, and it saves your data into a global Cache variable
  //with an absolute expiration of 10 minutes
  Cache.Insert("Report1", Report1, null,
  DateTime.Now.AddMinutes(10d), 
  System.Web.Caching.Cache.NoSlidingExpiration);


}

Then, when you are inside your other methods, you can use the Cache variable instead of calling stored procedures again. For example:

[System.Web.Services.WebMethod]
public static string GetDataReport1()
{
   //first load the application variable before performing your other work
   DataTable myCachedReport1Data = (DataTable)Cache["Report1"];
   //did the Cache expire?
   if (myCachedReport1Data == null)
   {
   //if so refresh it
   loadReport1IntoCache();
   //and then assign the variable the contents of the refresh and proceed
   myCachedReport1Data = (DataTable)Cache["Report1"];
   }

   //other work here, utilizing the myCachedReport1Data variable
}

and for your grid binding:

private void gvbindReport1()
{
    try
    {            
        DataTable myCachedReport1Data = (DataTable)Cache["Report1"];
        //did the Cache expire?
        if (myCachedReport1Data == null)
        {
          //if so refresh it
          loadReport1IntoCache();
          //and then assign the variable the contents of the refresh
          myCachedReport1Data = (DataTable)Cache["Report1"];
        }

        GdReport.DataSource = myCachedReport1Data ;
        GdReport.DataBind();
    }
    catch (Exception ex)
    {
        Log.Errlog("Error Occured in  gvbindReport1 : " +  ex.Message.ToString());
    }

}

Now, you will have to do a few things not mentioned here. You should consider when you want your Cache data to expire (the example given is 10 minutes). Also you should consider if you want it to be an Absolute Number of minutes (Absolute Expiry) or a number of minutes since last access (Sliding Expiry). In your case, probably absolute expiry, but only you know that. Then you will set the expiration when you are setting the variable contents.

c# - Can we use same datatable for pagemethod and webmethod in ASP.NET...

c# asp.net .net static webmethod
Rectangle 27 2

How I use Ajax within ASP.NET is just like PHP, the only thing is I call a webmethod. This way the Ajax call does not have to go through the whole process with all the init, load, prerender, etc. This is way faster then doing a call to a normal ASP.NET page.

My experience with Telerik is that it's really slow and bad for your performance if you want a simple Ajax call.

Below I give a simple example how you can do it:

public partial class _Default : Page 
{
  [WebMethod]
  public static string GetDate()
  {
    return DateTime.Now.ToString();
  }
}
Imports System.Web.Services

Partial Class Default
    Inherits System.Web.UI.Page

    <Script.Services.ScriptMethod()> _
    <WebMethod()> _
    Public Shared Function getDate() As String
        return DateTime.Now.ToString()
    End Function

End Class
$.ajax({
    url : "Default.aspx/getDate",
    data : null, // Needs to be a String!, see URL below
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success : function(data){
        var result = data.d; // ASP.NET gives a .d object to the client
        // result = your date, but if you return a SortedList, you can use result.date, or result.html or whatever.
    }
});

If I will put a json string into data field, in ajax, how I will retrive the json in C#? Thanks a lot!

ASP.NET Ajax with and without Telerik - Stack Overflow

asp.net ajax telerik webforms
Rectangle 27 2

How I use Ajax within ASP.NET is just like PHP, the only thing is I call a webmethod. This way the Ajax call does not have to go through the whole process with all the init, load, prerender, etc. This is way faster then doing a call to a normal ASP.NET page.

My experience with Telerik is that it's really slow and bad for your performance if you want a simple Ajax call.

Below I give a simple example how you can do it:

public partial class _Default : Page 
{
  [WebMethod]
  public static string GetDate()
  {
    return DateTime.Now.ToString();
  }
}
Imports System.Web.Services

Partial Class Default
    Inherits System.Web.UI.Page

    <Script.Services.ScriptMethod()> _
    <WebMethod()> _
    Public Shared Function getDate() As String
        return DateTime.Now.ToString()
    End Function

End Class
$.ajax({
    url : "Default.aspx/getDate",
    data : null, // Needs to be a String!, see URL below
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success : function(data){
        var result = data.d; // ASP.NET gives a .d object to the client
        // result = your date, but if you return a SortedList, you can use result.date, or result.html or whatever.
    }
});

If I will put a json string into data field, in ajax, how I will retrive the json in C#? Thanks a lot!

ASP.NET Ajax with and without Telerik - Stack Overflow

asp.net ajax telerik webforms
Rectangle 27 1

Webmethods in code behind are used for AJAX calls. If you are using jquery or similar and you need to implement an ajax functionality on your page then you will have to define you method with WebMethod attribute and have to make it public static. Then only it will work.

WebMethod's concept I feel has been taken from web services. Since asp.net didn't have any defined way of handling ajax requests to method of page behind, they have extended this feature to be used for code behind methods.

Keep a watch that being public static methods you may not be able to use your page class' internal properties here. so, you will need to deal with that.

If we really want AJAX, why not just write some asmx Web Service or use WCF and let Javascript to call that? Why do we have to include the crippled static methods in our page class?

There can be multiple reasons. 1) The functionality is very small that you dont wanna have a service call. Because when you expose a service call you have to add a new web method / operation contract. 2) The service call is expensive and will take more time to return (assuming we have to same logic) because of the layers involved in service communications. Also a code behind web method resides in the same app pool there for the call is really quick. - Thats what I feel. Others may have different opinion.

asp.net - "WebMethod" attribute in the aspx and asmx files, difference...

asp.net web-services asmx
Rectangle 27 1

Ben Dotnet is right about using a ScriptService in asp.net WebForms. In addition to using the ScriptService decorator the GenerateScriptType decorator is important in order to make sure that the complex type you're wanting to use is included. I found the articles Ben linked to be useful in addition to this one: http://www.webreference.com/programming/asp-net-ajax/complex-data-types/index.html

Here is how I was able to do exactly what you're trying. First I defined the custom type I wanted to use in my code behind file.

namespace TestProject
{
    public class SampleData
        {
            public int id { get; set; }
            public string StartDate { get; set; }
            public string EndDate { get; set; }

            public SampleData()
            { }
    }
    public partial class SamplePage : System.Web.UI.Page
    {
        /* The rest of the SamplePage.aspx.cs file goes here */
    }
}
[WebMethod]
[ScriptMethod]
[GenerateScriptType(typeof(SampleData))]
public static bool EditReminder(SampleData data)
{
    /* Server side code goes here */
    return true;
}

Then, on the client-side page I was able to create an object of type SampleData and pass that using the PageMethods like this. Don't forget to include the namespace, this is necessary.

function some_javascript_function () {
    var sample_data = new TestProject.SampleData()
    sample_data.id = 1;
    sample_data.StartDate = '6/24/1976';
    sample_data.EndDate = '3/20/2012';
    PageMethods.EditReminder(sample_data, OnEditReminderComplete)
}

function OnEditReminderComplete () {
    if (result) alert("Success!");
    else alert("Failure!");
}

Also, don't forget to include the script manager and enable page methods like this somewhere on your page:

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />

c# - Can I send an object from client-side javascript to server-side c...

c# javascript asp.net vb.net
Rectangle 27 1

This can be done without any library, by using the JavaScript FileReader API. With it, modern browsers can read the content of the file using JavaScript once it has been selected by the user, and then you could proceed as you were doing (encoding it as a string, and sending it over to the server).

The code would be like this (using the one above as a reference):

// NEW CODE
// set up the FileReader and the variable that will hold the file's content
var reader = new FileReader();
var fileContent = "";

// when the file is passed to the FileReader, store its content in a variable
reader.onload = function(e) {
  fileContent = reader.result;
  
  // for testing purposes, show content of the file on console
  console.log("The file content is: " + fileContent);
}

// Read the content of the file each time that the user selects one
document.getElementById("myFile").addEventListener("change", function(e) {
  var selectedFile = document.getElementById('myFile').files[0];
  reader.readAsText(selectedFile);
})
// END NEW CODE

var btn;
var span;

$(document).ready(function (e) {
  $('#btnsave').on('click', function (event) {
    Submit();
    event.preventDefault();
  });
})

function Submit() {

  $.ajax({
    type: "POST",
    url: "SupplierMst.aspx/RegisterSupplier",
    // changed this line too!
    data: {
              'file': btoa(fileContent), 
              'biddername': document.getElementById("txtsuppliername").value 
          },
    async: true,
    contentType: "application/json; charset=utf-8",
    success: function (data, status) {
      console.log("CallWM");
      alert(data.d);
    },
    failure: function (data) {
      alert(data.d);
    },
    error: function (data) {
      alert(data.d);
    }
  });

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="txtsuppliername" type="text" /><br />
<input type="file" id="myFile">

You can run the code above, select a file (use a plain text file for testing so it's readable), and check the console to see its content. Then the rest of the code would be the same (I made a slight change to fix the parameters in the AJAX call).

Notice that sending the file like this has limits: if you use the GET method, you'll have a shorter parameter size limit, and with POST it will depend on the server settings... but I guess that you had those limits even for a file.

TypeError: document.getElementById(...) is null

Where are you getting that error? Could you share your code?

document.getElementById("myFile").addEventListener("change", function(e) {   var selectedFile = document.getElementById('myFile').files[0];   reader.readAsText(selectedFile); })
input type="file"

And where have you placed that code within your page?

javascript - How to post webform with file to webmethod using Jquery/A...

javascript jquery asp.net ajax webforms
Rectangle 27 8

I think I was getting confused with the "type" parameter in JQuery's $.post command. After talking to some folks, it seems that the return type for calling a WebMethod MUST be "json". I was trying to use "html". Once I changed it to "json" and then everything worked like normal. So apparently, a method decorated with [WebMethod] returns JSON only, and that's where my hangup was.

Yeah, this was getting me as well. Thanks for the info!

Jquery AJAX with ASP.NET WebMethod Returning Entire Page - Stack Overf...

asp.net jquery ajax
Rectangle 27 22

Before all I could say, that you choose not the easiest way. ScriptMethods is easy to use together with ASP.NET ScriptManager and not with jQuery. Ill recommend you better use JSON-enabled WCF HTTP Services (better as RESTfull Service) instead of ASMX Webservice which you try to use now. Nevertheless, one can makes you code working without using any Microsoft technologies on the client side.

First of all verify Server side.

  • Verify that you placed Inside of \ and a httpHandlers for asmx extension (ScriptHandlerFactory) also exist in the config: <configuration> <!-- ... --> <system.web> <webServices> <protocols> <add name="HttpGet"/> </protocols> </webServices> <httpHandlers> <!-- ... --> <add verb="*" path="*.asmx" type="System.Web.Script.Services.ScriptHandlerFactory" validate="false"/> </httpHandlers></system.web></configuration>

Verify that [ScriptService] attribute ([System.Web.Script.Services.ScriptService] if you like full names) set for your class inherited from System.Web.Services.WebService.

<?xml version="1.0" encoding="utf-8" ?>
<string xmlns="http://tempuri.org/">li1234</string>

You can be sure that you service part works fine.

Remark: Independ on ResponseFormat = System.Web.Script.Services.ResponseFormat.Json attribute the service answer with XML responses if Content-Type:application/json; not set in the request.

Now well fix the client code. I hope that comments which I placed in the following code explain all.

[WebMethod]
[ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public OutputData AjaxGetMore (InputData input) {
    return new OutputData () {
        id = input.id,
        message = "it's work!",
        myInt = input.myInt+1
    };
}
public class OutputData {
    public string id { get; set; }
    public string message { get; set; }
    public int myInt { get; set; }
}
public class InputData {
    public string id { get; set; }
    public int myInt { get; set; }
}

Now only JavaScript code which use in some places JSON plugin, which could be replaced with Crockford's json2.js, if somebody prefer it.

var id = "li1234";
// version 1 - works
var idAsJson = '"' + id + '"';  // string serializes in JSON format
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet?id=" + idAsJson,
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});

// version 2 with respect of JSON plugin
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet?id=" + $.toJSON(id),
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});
// version 3 where jQuery will construct URL for us
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet",
    data: {id: $.toJSON(id)},
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});
// version 4. We set "Content-Type: application/json" about our data, but we use no 
//            not 'dataType: "json"' parameter. Then we have "Accept: */*" in the request
//            instead of "Accept: application/json, text/javascript, */*" before.
//            Everithing work OK like before.
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet",
    data: {id: $.toJSON(id)},
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});
// version 5. If we don't place "Content-Type: application/json" in our reqest we
//            receive back XML (!!!) response with "HTTP/1.1 200 OK" header and 
//            "Content-Type: text/xml; charset=utf-8" which will be placed.
//            How one can read in
// http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx),
//             ASP.NET AJAX will not make JSON serialized of response data for
//             security reasons.
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGet",
    data: {id: $.toJSON(id)},
    dataType: "json",
    //contentType: "application/json; charset=utf-8",
    success: function(msg) {
        alert(msg.d);   // var msg = {d: "li1234"} 
    },
    error: function (res, status, ex) {
        // the code here will be works because of error in parsing server response
        if (res.status !== 200) {   // if not OK
            // we receive exception in the next line, be
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        } else {
            alert("status=" + status + "\nex=" + ex + "\nres.status=" + res.status + "\nres.statusText=" + res.statusText +
                    "\nres.responseText=" + res.responseText);
        }
    }
});
// version 6. Send more komplex data to/from the service
var myData = { id: "li1234", myInt: 100}
$.ajax({
    type: "GET",
    url: "/webmethods.asmx/AjaxGetMore",
    data: {input:$.toJSON(myData)},
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        // var msg = {__type: "Testportal.OutputData", id: "li1234", message: "it's work!", myInt:101}
        alert("message=" + msg.d.message + ", id=" + msg.d.id + ", myInt=" + msg.d.myInt); 
    },
    error: function(res, status) {
        if (status ==="error") {
            // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
            var errorMessage = $.parseJSON(res.responseText);
            alert(errorMessage.Message);
        }
    }
});

Your solution to this works for asmx web services, but is it possible to make this work if the WebMethod is inside an aspx file?

@MattRoberts: Everything is possible, but I don't full understand the reason of that. aspx are used for general HTML pagers or for web forms. So the corresponding Handler will be used to process the request to the URL. So usage of file extension is really practical. You can use ASHX to create general handles which process common HTTP request and which do not have a UI or HTML markup.

JQuery ajax call to httpget webmethod (c#) not working - Stack Overflo...

c# jquery get