วิธีที่เหมาะสมในการใช้ AJAX Post ใน jquery เพื่อส่งผ่านโมเดลจากมุมมอง MVC3 ที่พิมพ์มาก


101

ฉันเป็นมือใหม่หัดเขียนโปรแกรมเว็บดังนั้นโปรดยกโทษให้ฉันด้วยหาก "ศัพท์แสง" บางคำไม่ถูกต้อง ฉันมีโครงการที่ใช้ ASP.NET โดยใช้เฟรมเวิร์ก MVC3

ฉันกำลังดำเนินการเกี่ยวกับมุมมองของผู้ดูแลระบบซึ่งผู้ดูแลระบบจะแก้ไขรายการอุปกรณ์ หนึ่งในฟังก์ชันคือปุ่ม "อัปเดต" ที่ฉันต้องการใช้ jquery เพื่อแก้ไขรายการบนหน้าเว็บแบบไดนามิกหลังจากส่งโพสต์ไปยังตัวควบคุม MVC

ฉันคิดว่าวิธีนี้ "ปลอดภัย" ในการตั้งค่าผู้ดูแลระบบเดียวซึ่งมีข้อกังวลน้อยที่สุดเกี่ยวกับการไม่ซิงค์กับฐานข้อมูลของหน้าเว็บ

ฉันได้สร้างข้อมูลพร็อพเพอร์ตี้ที่พิมพ์อย่างชัดเจนและหวังว่าจะส่งต่อข้อมูลโมเดลไปยังตัวควบคุม MVC โดยใช้โพสต์ AJAX

ในโพสต์ต่อไปนี้ฉันพบสิ่งที่คล้ายกับสิ่งที่ฉันกำลังทำอยู่: JQuery Ajax และ ASP.NET MVC3 ทำให้เกิดพารามิเตอร์ null

ฉันจะใช้ตัวอย่างโค้ดจากโพสต์ด้านบน

รุ่น:

public class AddressInfo 
{
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
}

ตัวควบคุม:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Check(AddressInfo addressInfo)
    {
        return Json(new { success = true });
    }
}

สคริปต์ในมุมมอง:

<script type="text/javascript">
var ai = {
    Address1: "423 Judy Road",
    Address2: "1001",
    City: "New York",
    State: "NY",
    ZipCode: "10301",
    Country: "USA"
};

$.ajax({
    url: '/home/check',
    type: 'POST',
    data: JSON.stringify(ai),
    contentType: 'application/json; charset=utf-8',
    success: function (data.success) {
        alert(data);
    },
    error: function () {
        alert("error");
    }
});
</script>

ฉันยังไม่ได้มีโอกาสใช้ข้างต้นเลย แต่ฉันสงสัยว่านี่เป็นวิธีที่ "ดีที่สุด" ในการส่งผ่านข้อมูลแบบจำลองกลับไปยังการควบคุม MVC โดยใช้ AJAX หรือไม่?

ฉันควรกังวลเกี่ยวกับการเปิดเผยข้อมูลรุ่นหรือไม่?

คำตอบ:


72

คุณสามารถข้ามการประกาศ var และ stringify ได้ มิฉะนั้นจะได้ผลดี

$.ajax({
    url: '/home/check',
    type: 'POST',
    data: {
        Address1: "423 Judy Road",
        Address2: "1001",
        City: "New York",
        State: "NY",
        ZipCode: "10301",
        Country: "USA"
    },
    contentType: 'application/json; charset=utf-8',
    success: function (data) {
        alert(data.success);
    },
    error: function () {
        alert("error");
    }
});

ขอขอบคุณที่ชี้ให้เห็นการปรับเปลี่ยนเล็กน้อย มีความกังวลเกี่ยวกับการเปิดเผยโครงสร้างแบบจำลองจากจุดยืนด้านความปลอดภัยหรือไม่?
John Stone

ไม่มีสิ่งใดที่โดดเด่นเป็นปัญหาด้านความปลอดภัยสำหรับฉัน หากคุณกังวลจริงๆคุณสามารถสร้าง Binder แบบกำหนดเองที่ด้าน mvc ได้ตลอดเวลา
Craig M

8
สิ่งนี้ล้มเหลวสำหรับฉัน ฉันต้องใช้ JSON.stringify ({... }) เพื่อให้การโทรทำงานใน MVC5
Johncl

ฉันสังเกตเห็นว่าฉันต้องทำเช่นเดียวกันเมื่อทำงานกับตัวควบคุม API คำตอบนี้เขียนขึ้นเมื่อ 4 ปีที่แล้วก่อนที่ตัวควบคุม API จะมีอยู่
Craig M

1
พระเจ้าฉันมี dataType แทน contentType สิ่งนั้นมักจะทำให้ฉันเสมอ !!
ฟิล

175

ฉันพบ 3 วิธีในการใช้สิ่งนี้:

คลาส C #:

public class AddressInfo {
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
}

หนังบู๊:

[HttpPost]
public ActionResult Check(AddressInfo addressInfo)
{
    return Json(new { success = true });
}

JavaScriptคุณสามารถทำได้สามวิธี:

1) สตริงการค้นหา:

$.ajax({
    url: '/en/Home/Check',
    data: $('#form').serialize(),
    type: 'POST',
});

ข้อมูลในที่นี้คือสตริง

"Address1=blah&Address2=blah&City=blah&State=blah&ZipCode=blah&Country=blah"

2) อาร์เรย์วัตถุ:

$.ajax({
    url: '/en/Home/Check',
    data: $('#form').serializeArray(),
    type: 'POST',
});

ข้อมูลที่นี่คืออาร์เรย์ของคู่คีย์ / ค่า:

=[{name: 'Address1', value: 'blah'}, {name: 'Address2', value: 'blah'}, {name: 'City', value: 'blah'}, {name: 'State', value: 'blah'}, {name: 'ZipCode', value: 'blah'}, {name: 'Country', value: 'blah'}]

3) JSON:

$.ajax({
      url: '/en/Home/Check',
      data: JSON.stringify({ addressInfo:{//missing brackets
          Address1: $('#address1').val(),
          Address2: $('#address2').val(),
          City: $('#City').val(),
          State: $('#State').val(),
          ZipCode: $('#ZipCode').val()}}),
      type: 'POST',
      contentType: 'application/json; charset=utf-8'
});

ข้อมูลในที่นี้คือสตริง JSON ที่ทำให้เป็นอนุกรม โปรดทราบว่าชื่อต้องตรงกับชื่อพารามิเตอร์ในเซิร์ฟเวอร์ !!

='{"addressInfo":{"Address1":"blah","Address2":"blah","City":"blah","State":"blah", "ZipCode", "blah", "Country", "blah"}}'

1
เพิ่งเจอคำตอบที่ยอดเยี่ยมและละเอียดถี่ถ้วนซึ่งสามารถแก้ไขคำถามที่ฉันยังไม่รู้ได้ +1 ขอบคุณ!
SeanKilleen

# 2 คือสิ่งที่ฉันกำลังมองหา นี่น่าจะเป็นคำตอบ
TheGeekZn

แก้ไข: ต้องใช้data: $('input, textarea, select').serialize(),ให้ฉันทำงาน
TheGeekZn

เฮ้จาซาเร็ต !! จะส่งต่อวันที่ไปยังรุ่นด้วยแนวทางที่ 3 ได้อย่างไร ??
Guruprasad Rao

1
ขออภัยในความล่าช้า @GuruprasadRao ในการส่งวันที่คุณสามารถกำหนดวันที่และเวลาเป็นสตริงในรหัสจาวาสคริปต์และ MVC จะแปลเป็นออบเจ็กต์ DateTime
Jazaret

12

นี่คือวิธีที่ได้ผลสำหรับฉัน:

$.post("/Controller/Action", $("#form").serialize(), function(json) {       
        // handle response
}, "json");

[HttpPost]
public ActionResult TV(MyModel id)
{
    return Json(new { success = true });
}

8

สิ่งที่คุณมีดี - อย่างไรก็ตามเพื่อประหยัดการพิมพ์คุณสามารถใช้สำหรับข้อมูลของคุณได้

ข้อมูล: $ ('# formId'). serialize ()

โปรดดูhttp://www.ryancoughlin.com/2009/05/04/how-to-use-jquery-to-serialize-ajax-forms/สำหรับรายละเอียดไวยากรณ์นั้นค่อนข้างพื้นฐาน


ในการใช้ฟังก์ชันซีเรียลไลซ์ความเข้าใจของฉันคือสมาชิกแต่ละคนของคลาสจำเป็นต้องใช้ในอ็อบเจ็กต์ฟอร์ม ถ้าถูกต้องฉันอาจจะเป็น SOL
John Stone

1
อ๊ายยย.. ถ้าไม่ใช้ซีเรียลไลซ์ คุณสามารถจัดการ DOM ได้ตลอดเวลาและสร้างแบบฟอร์มด้วยองค์ประกอบเหล่านั้นและทำให้เป็นอนุกรม - แต่ ... มันน่าจะดีกว่าที่จะพิมพ์ฟิลด์ด้วยตนเอง
Adam Tuliper - MSFT

@TahaRehmanSiddiqui serialize ใช้งานได้จริงใน IE ไม่ทำงานอะไร คุณได้รับข้อผิดพลาดหรือไม่?
Adam Tuliper - MSFT

คุณสมบัติทุกอย่างของแบบจำลองของฉันกำลังออกมาเป็นโมฆะ
Taha Rehman Siddiqui

@TahaRehmanSiddiqui 'ชื่อ' ของฟิลด์แบบฟอร์มของคุณตรงกับชื่อคุณสมบัติของโมเดลของคุณหรือไม่?
MongooseNX

0

หากใช้ MVC 5 อ่านวิธีนี้!

ฉันรู้ว่าคำถามที่เรียกร้องโดยเฉพาะสำหรับ MVC 3 แต่ฉันสะดุดกับหน้านี้ที่มี MVC 5 และต้องการโพสต์วิธีแก้ปัญหาสำหรับคนอื่นในสถานการณ์ของฉัน ฉันลองวิธีแก้ปัญหาข้างต้นแล้ว แต่มันไม่ได้ผลสำหรับฉันตัวกรองการดำเนินการไม่สามารถเข้าถึงได้และฉันไม่สามารถหาสาเหตุได้ ฉันใช้เวอร์ชัน 5 ในโครงการของฉันและลงเอยด้วยตัวกรองการดำเนินการต่อไปนี้:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Filters;

namespace SydHeller.Filters
{
    public class ValidateJSONAntiForgeryHeader : FilterAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            string clientToken = filterContext.RequestContext.HttpContext.Request.Headers.Get(KEY_NAME);
            if (clientToken == null)
            {
                throw new HttpAntiForgeryException(string.Format("Header does not contain {0}", KEY_NAME));
            }

            string serverToken = filterContext.HttpContext.Request.Cookies.Get(KEY_NAME).Value;
            if (serverToken == null)
            {
                throw new HttpAntiForgeryException(string.Format("Cookies does not contain {0}", KEY_NAME));
            }

            System.Web.Helpers.AntiForgery.Validate(serverToken, clientToken);
        }

        private const string KEY_NAME = "__RequestVerificationToken";
    }
}

- จดบันทึกusing System.Web.Mvcและusing System.Web.Mvc.Filtersไม่ใช่httpไลบรารี (ฉันคิดว่านั่นเป็นหนึ่งในสิ่งที่เปลี่ยนไปกับ MVC v5 -

จากนั้นใช้ตัวกรอง[ValidateJSONAntiForgeryHeader]กับการกระทำของคุณ (หรือตัวควบคุม) และควรเรียกใช้อย่างถูกต้อง

ในหน้าเค้าโครงของฉันด้านบน</body>ฉันมี@AntiForgery.GetHtml();

สุดท้ายในหน้า Razor ของฉันฉันจะเรียก ajax ดังนี้:

var formForgeryToken = $('input[name="__RequestVerificationToken"]').val();

$.ajax({
  type: "POST",
  url: serviceURL,
  contentType: "application/json; charset=utf-8",
  dataType: "json",
  data: requestData,
  headers: {
     "__RequestVerificationToken": formForgeryToken
  },
     success: crimeDataSuccessFunc,
     error: crimeDataErrorFunc
});

1
คุณกำลังดึงค่าฟอร์มทั้งหมดของคุณด้วยตนเองหรือไม่? ทำไมไม่data: $("#the-form").serialize()?
สินจัย

1
@ สินจัยฉันจะต้องดูรหัสของฉันอีกครั้ง แต่ฉันเชื่อว่าฉันกำลังประมวลผลอย่างอื่นอยู่ในนั้นเช่นกัน ".serialize ()" จะใช้งานได้เช่นกันหากคุณต้องการค่าอินพุต
blubberbo

ไม่ต้องกังวลฉันแค่อยากรู้
สินจัย
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.