3

I have a class Person in c#.

I want to be able to do in my js :

var p = new Person();

Later Im sending p object to an ashx via jQuery Ajax

What are the libraries ( jQuery ? xxx ?) which can help me do that ?

I know that Ajaxtookit has a attribute : ScriptService

But Im not sure HOw good this solution.

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • Are you using WebForms or MVC? – M.Babcock Jan 07 '12 at 15:00
  • You don't do this. You can't just port a C# class to JavaScript. You redefine the "class" in JavaScript – Raynos Jan 07 '12 at 15:12
  • @Raynos you are wrong . there are libraries which do that. I saw it - e.g : scriptService attribute. – Royi Namir Jan 07 '12 at 15:16
  • @RoyiNamir auto generating javascript from C# is a great way to generate mediocre code that will leak around the edges. Do it properly. – Raynos Jan 07 '12 at 15:18
  • @RoyiNamir - What version of .NET are you using? If you're using .NET 4, you could utilize the new `dynamic` keyword using something like [this](http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx). – M.Babcock Jan 07 '12 at 15:33
  • @M.Babcock ver 4. How do i take the object from the request.form and use dynamic with it ? ( can you please post an answer ?) – Royi Namir Jan 07 '12 at 15:36

3 Answers3

7

You could use ASPX PageMethods with jQuery. So start working on the server by defining a model:

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

then you could define a page method in some aspx page (/foo.aspx):

public partial class _Foo : System.Web.UI.Page
{
    [WebMethod]
    public static string SavePerson(Person p)
    {
        // do some processing with the person
        return "Hello World";
    }
}

and finally invoke this page method:

var p = {
    firstName: 'John',
    lastName: 'Smith'
};
$.ajax({
    url: '/foo.aspx/SavePerson',
    type: 'POST',
    contentType: 'application/javascript; charset=utf-8',
    data: JSON.stringify(p),
    success: function(result) {
        alert(result.d);
    }
});

The JSON.stringify method illustrated here is built in modern browsers. If you need to support legacy browsers you could include the json2.js script to your page.


UPDATE:

As requested in the comments section here's how you could design a generic ASHX handler that will receive this request, do some processing and return a JSON response:

public class Foo : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        var serializer = new JavaScriptSerializer();
        using (var reader = new StreamReader(context.Request.InputStream))
        {
            Person person = (Person)serializer.Deserialize<Person>(reader.ReadToEnd());
            // do some processing with the person

        }
        context.Response.ContentType = "application/json";

        var result = serializer.Serialize(new { data = "Hello World" });
        context.Response.Write(result);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

and the request:

var p = {
    firstName: 'John',
    lastName: 'Smith'
};
$.ajax({
    url: '/foo.ashx',
    type: 'POST',
    data: JSON.stringify(p),
    success: function(result) {
        alert(result.data);
    }
});
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I dont use aspx jus ashx so i dont have webmethod attr. How can i change your code to work with ASHX file ? – Royi Namir Jan 07 '12 at 16:03
  • @RoyiNamir, answer updated with an example using a generic ASHX handler. – Darin Dimitrov Jan 07 '12 at 16:09
  • How come I cant see the values in the Request.form but only in context.Request.InputStream ? ( you sent it as post so why it aint show you in request.form ?) – Royi Namir Jan 07 '12 at 16:46
  • @RoyiNamir, in this example we are sending a JSON request into the stream directly. There is no Request.Form. You cannot use this if you want to send a JSON request. If you don't want to send a JSON request, remove the `JSON.stringify` call. Then you can use `Request["FirstName"]` inside the handler to fetch individual properties. But why would you need this if you already have the entire object? – Darin Dimitrov Jan 07 '12 at 16:47
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/6509/discussion-between-royi-namir-and-darin-dimitrov) – Royi Namir Jan 07 '12 at 16:53
2

use json, convert your c# object to json using Json.NET Library

  • That just converts the data to the JSON format, that doesn't allow for using C# written classes in javascript in any way. It doesn't allow sending, but that's only part. – Dykam Jan 07 '12 at 15:00
2

The correct thing to do is define a person prototype in JavaScript

var Person = {
  someMethod: function () {

  },
  someMoreMethods: function () {

  }
};

Then you get your C# server to send a serialized version of it's Person instance as JSON and on the client you just have an xhr handler

xhr.addEventListener("load", function () {
  var personJSON = JSON.parse(this.responseText);
  var personInstance = Object.create(Person);
  var person = extend(personInstance, personJSON);
});

Here you take the json data for the person which are all the attributes. You create a new prototypical instance of the Person "class" so the instance has all the methods. You then extend the instance with the data / attributes you got over JSON.

note you have to implement extend, a naive implementation would be

function extend(target, source) {
  Object.getOwnPropertyNames(source).forEach(function (name) {
    var pd = Object.getOwnPropertyDescriptor(source, name);
    Object.defineProperty(target, name, pd);
  });
  return target;
}

Disclaimer: example code uses ES5, deal with legacy browser engines in a sensible manner yourself.

Raynos
  • 166,823
  • 56
  • 351
  • 396