views:

72

answers:

1

If you have the following:

  1. Asp.Net MVC 2 project having object classes that define view models.
  2. Serialize these models to the web browser client using JSON.
  3. Client adds information to the objects, like an Order Line on an Invoice.
  4. Client sends back the object to the server for processing.

Is there any way to share with the client a data contract for the JSON objects? I would really want to have the server create a Order using an Order factory, then send it to the client. The client adds order lines using the data contracts, and sends back the fully populated object as JSON.

I would really like to do the following in JavaScript at the client:

var order = myService.OrderFactory.GetNewClientOrderRequest();
order.description = "Some New Order";
var orderLine = myService.OrderFactory.GetNewClientOrderLine( order);
orderLine.setProductID( 1234);
orderLine.setQty( 1);
order.AddLine( orderLine);
if( order.SubmitOrder() == true) {
    //display confirmation
}

Any examples or web page links to Asp.Net MVC 2 would be very helpful.

+1  A: 

Well, given an example model:

[DataContract]
public class Item
{
  [DataMember]
  public string Title { get; set; }
}

You could create an action filter which deserialises your objects from JSON:

/// <summary>
/// Deserialises a DataContract parameter from its JSON equivalence.
/// </summary>
public class JsonParameterFilter : ActionFilterAttribute
{
  #region Properties
  /// <summary>
  /// Gets or sets the parameter name.
  /// </summary>
  public string Name { get; set; }

  /// <summary>
  /// Gets or sets the type of the parameter.
  /// </summary>
  public Type Type { get; set; }
  #endregion

  #region Methods
  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    var request = filterContext.HttpContext.Request;

    string contentType = request.ContentType;
    if (!string.IsNullOrEmpty(contentType) && contentType.ToLower().Contains("application/json")) 
    {
      var serialiser = new DataContractJsonSerializer(this.Type);
      var @object = serialiser.ReadObject(request.InputStream);

      filterContext.ActionParameters[Name] = @object;
    }
  }
  #endregion
}

And applied to your action:

[JsonParameterFilter(Name = "item", Type = typeof(Item))]
public ActionResult ProcessItem(Item item)
{
  // Do stuff here

  return View();
}

What you need to make sure you do is post the data with the content type of "application/json":

var item = ItemFactory.GetNewItem();
item.Title = "Something";

var json = $.toJSON(item);
$.ajax({
  contentType: "application/json; charset=utf-8"
  data: json,
  dataType: "json",
  type: "post",
  url: "Controller/Action",
});

Obviously your client-side library/script needs to be able to create an instance of a javascript object that can be deserialised as your server-side instance.

Matthew Abbott
Phil Haack eventually did the same thing after reading a friend's post http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx.
Dr. Zim