2008-11-06 39 views
32

Tôi có Chế độ xem cho phép người dùng nhập/chỉnh sửa dữ liệu cho Tiện ích con mới. Tôi muốn tạo thành dữ liệu đó thành một đối tượng json và gửi nó đến bộ điều khiển của tôi thông qua AJAX vì vậy tôi có thể thực hiện xác nhận trên máy chủ mà không cần đăng lại.Cách chuyển loại phức tạp bằng cách sử dụng json sang bộ điều khiển ASP.NET MVC

Tôi đã làm việc đó, ngoại trừ tôi không thể biết cách truyền dữ liệu sao cho phương thức điều khiển của tôi có thể chấp nhận kiểu Widget phức tạp thay vì tham số riêng cho từng thuộc tính.

Vì vậy, nếu đây là đối tượng của tôi:

public class Widget 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public decimal Price { get; set; } 
} 

Tôi muốn phương pháp điều khiển của tôi để tìm một cái gì đó như thế này:

public JsonResult Save(Widget widget) 
{ 
    ... 
} 

Hiện nay, jQuery của tôi trông như thế này:

var formData = $("#Form1").serializeArray(); 

$.post("/Widget/Save", 
    formData, 
    function(result){}, "json"); 

Biểu mẫu của tôi (Form1) có trường nhập cho mỗi thuộc tính trên Tiện ích con (Id, Tên, Giá). Điều này làm việc tuyệt vời, nhưng cuối cùng nó đi qua từng thuộc tính của Widget như một tham số riêng biệt cho phương thức điều khiển của tôi.

Có cách nào tôi có thể "chặn" dữ liệu, có thể sử dụng một ActionFilterAttribute, và deserialize nó vào một đối tượng Widget trước khi phương pháp điều khiển của tôi được gọi?

Trả lời

24

Cảm ơn Jeff, điều đó đã giúp tôi đi đúng hướng. DefaultModelBinder là đủ thông minh để làm tất cả các phép thuật cho tôi ... vấn đề của tôi là trong loại Widget của tôi. Trong sự vội vàng của tôi, loại của tôi được định nghĩa là:

public class Widget 
{ 
    public int Id; 
    public string Name; 
    public decimal Price; 
} 

Lưu ý rằng loại có trường công cộng thay vì tài sản công cộng. Một khi tôi thay đổi những tài sản, nó đã làm việc. Dưới đây là mã nguồn thức mà làm việc một cách chính xác:

Widget.aspx:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Widget.aspx.cs" Inherits="MvcAjaxApp2.Views.Home.Widget" %> 
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server"> 
    <script src="../../Scripts/jquery-1.2.6.js" type="text/javascript"></script> 
    <script type="text/javascript"> 
    function SaveWidget() 
    { 
     var formData = $("#Form1").serializeArray(); 

     $.post("/Home/SaveWidget", 
     formData, 
     function(data){ 
      alert(data.Result); 
     }, "json"); 
    } 
    </script> 
    <form id="Form1"> 
     <input type="hidden" name="widget.Id" value="1" /> 
     <input type="text" name="widget.Name" value="my widget" /> 
     <input type="text" name="widget.Price" value="5.43" /> 
     <input type="button" value="Save" onclick="SaveWidget()" /> 
    </form> 
</asp:Content> 

HomeController.cs:

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

namespace MvcAjaxApp2.Controllers 
{ 
    [HandleError] 
    public class HomeController : Controller 
    { 
     public ActionResult Index() 
     { 
      ViewData["Title"] = "Home Page"; 
      ViewData["Message"] = "Welcome to ASP.NET MVC!"; 
      return View(); 
     } 

     public ActionResult About() 
     { 
      ViewData["Title"] = "About Page"; 
      return View(); 
     } 

     public ActionResult Widget() 
     { 
      ViewData["Title"] = "Widget"; 
      return View(); 
     } 

     public JsonResult SaveWidget(Widget widget) 
     { 
      // Save the Widget 
      return Json(new { Result = String.Format("Saved widget: '{0}' for ${1}", widget.Name, widget.Price) }); 
     } 
    } 
    public class Widget 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public decimal Price { get; set; } 
    } 
} 
+3

Tuyệt vời, vui vì bạn đã sửa nó. Và cảm ơn vì đã đăng cách bạn sửa nó, điều đó sẽ giúp ích rất nhiều trong tương lai! –

+1

Các lĩnh vực công khai là sinh sản của quỷ trong .NET. Họ phá vỡ mọi thứ. MỌI MỌI TẤT CẢ BẠN! – Will

+0

Cảm ơn. Điều này đã giúp tôi. –

2

Những gì bạn muốn làm là cấu trúc đối tượng dạng javascript của bạn trong cùng một cách đối tượng phụ trợ của bạn được cấu trúc:

{ Id : "id", Name : "name", Price : 1.0 } 

Sau đó sử dụng các plugin toJSON để chuyển đổi nó thành chuỗi trên. Bạn gửi chuỗi này đến backend của bạn và sử dụng một cái gì đó giống như các thư viện JayRock để chuyển đổi nó sang một đối tượng Widget mới.

4

Phil Haacka good blog post về mô hình ràng buộc có thể hữu ích. Không phải 100% những gì bạn đang nói ở đây, nhưng tôi nghĩ nó có thể giúp bạn hiểu rõ hơn về DefaultModelBinder.

6

Lưu ý rằng (trong MrDustpan của giải pháp) tham số têntiện ích trong phương thức Hành động MVC phải khớp với tiền tố được sử dụng trong tên tên attri bute trong tập tin ASPX.

Nếu trường hợp này không xảy ra thì Phương thức hành động sẽ luôn nhận được đối tượng null.

<input type="text" name="widget.Text" value="Hello" /> - OK 
<input type="text" name="mywidget.Text" value="Hello" /> - FAILS 
+0

Điểm tuyệt vời và dễ bị bỏ qua. Có vẻ là trường hợp nhạy cảm quá. –

Các vấn đề liên quan