SORU
12 Kasım 2010, Cuma


ASP.NET MVC JSON Veri gönderme

İm olsun istiyorum, bir listenin satır öğeleri için bir web sayfası kullanarak JSON, daha sonra manipüle ve geri gönderdi sunucu tarafından ajax isteği kullanarak aynı JSON yapısı geldi (dışında olan bir alan değerleri değişti).

Sunucudan veri almak kolaydır, manipülasyon daha kolay! ama veri kurtarmak için sunucuya geri gönderme JSON... intihar vakti! Birisi yardımcı olabilir LÜTFEN!

Javascript

var lineitems;

// get data from server
$.ajax({
    url: '/Controller/GetData/',
    success: function(data){
        lineitems = data;
    }
});

// post data to server
$.ajax({
    url: '/Controller/SaveData/',
    data: { incoming: lineitems }
});

# - C Nesneleri

public class LineItem{
    public string reference;
    public int quantity;
    public decimal amount;
}

# - C Denetleyicisi

public JsonResult GetData()
{
    IEnumerable<LineItem> lineItems = ... ; // a whole bunch of line items
    return Json(lineItems);
}

public JsonResult SaveData(IEnumerable<LineItem> incoming){
    foreach(LineItem item in incoming){
        // save some stuff
    }
    return Json(new { success = true, message = "Some message" });
}

Veri sonrası veri seri olarak sunucu varır. Otomatik model Cilt 11* *bağlamaya çalışır ve şaşırtıcı IEnumerable LineItems - sadece bakmıyor veri ile doldurmak doğru sayıda var sonuç alır.

ÇÖZÜM

Kaynaklar, öncelikle başka bir stackoverflow sonrası djch BeRecursive bir dizi yanıtlarını kullanarak, benim sorunum iki ana yöntem kullanarak çözdüm.

Sunucu Tarafı

Bu deserialiser aşağıda System.Runtime.Serialization using System.Runtime.Serialization.Json için başvuru gerektirir

    private T Deserialise<T>(string json)
    {
        using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
        {
            var serialiser = new DataContractJsonSerializer(typeof(T));
            return (T)serialiser.ReadObject(ms);
        }
    }

    public void Action(int id, string items){
        IEnumerable<LineItem> lineitems = Deserialise<IEnumerable<LineItem>>(items);
        // do whatever needs to be done - create, update, delete etc.
    }

İstemci Tarafı

Json.org'nin yöntemi, 23* *Bu dependecy mevcut minified zaman 2.5 kb) stringify . kullanır

        $.ajax({
            type: 'POST',
            url: '/Controller/Action',
            data: { 'items': JSON.stringify(lineItems), 'id': documentId }
        });

CEVAP
12 Kasım 2010, Cuma


model binding JSON data Phil Haack sonrası bir göz atın. Sorun varsayılan model binder JSON seri hale getirmek doğru değil. ValueProvider bir yer lazım YA da özel model binder yazabilirsiniz:

using System.IO;
using System.Web.Script.Serialization;

public class JsonModelBinder : DefaultModelBinder {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
            if(!IsJSONRequest(controllerContext)) {
                return base.BindModel(controllerContext, bindingContext);
            }

            // Get the JSON data that's been posted
            var request = controllerContext.HttpContext.Request;
            //in some setups there is something that already reads the input stream if content type = 'application/json', so seek to the begining
            request.InputStream.Seek(0, SeekOrigin.Begin);
            var jsonStringData = new StreamReader(request.InputStream).ReadToEnd();

            // Use the built-in serializer to do the work for us
            return new JavaScriptSerializer()
                .Deserialize(jsonStringData, bindingContext.ModelMetadata.ModelType);

            // -- REQUIRES .NET4
            // If you want to use the .NET4 version of this, change the target framework and uncomment the line below
            // and comment out the above return statement
            //return new JavaScriptSerializer().Deserialize(jsonStringData, bindingContext.ModelMetadata.ModelType);
        }

        private static bool IsJSONRequest(ControllerContext controllerContext) {
            var contentType = controllerContext.HttpContext.Request.ContentType;
            return contentType.Contains("application/json");
        }
    }

public static class JavaScriptSerializerExt {
        public static object Deserialize(this JavaScriptSerializer serializer, string input, Type objType) {
            var deserializerMethod = serializer.GetType().GetMethod("Deserialize", BindingFlags.NonPublic | BindingFlags.Static);

            // internal static method to do the work for us
            //Deserialize(this, input, null, this.RecursionLimit);

            return deserializerMethod.Invoke(serializer,
                new object[] { serializer, input, objType, serializer.RecursionLimit });
        }
    }

Ve söyle senin Genel olarak kullanmak için MVC.asax dosya:

ModelBinders.Binders.DefaultBinder = new JsonModelBinder();

Ayrıca, bu kod içerik türünü kullanır = 'application/json', bu yüzden gibi bir WordPress kullanmak o kurmak emin olun:

$.ajax({
    dataType: "json",
    contentType: "application/json",            
    type: 'POST',
    url: '/Controller/Action',
    data: { 'items': JSON.stringify(lineItems), 'id': documentId }
});

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Joseph Herscher

    Joseph Hersc

    14 Mart 2007
  • laptopmag

    laptopmag

    25 Ocak 2008
  • RealPapaPit

    RealPapaPit

    16 Mart 2009