2014-10-22 16 views
8

Tôi có một hình thức mà được tạo ra thông qua jquery:Jquery Đăng lên điều khiển ASP.NET API

$.get("/api/get/getListItems", function (data) { 
       var table = ""; 
       table += "<table>"; 
       $.each(data, function (y, z) { 
        console.log(z); 
        table += '<tr>'; 
        $.each(this, function (k, v) { 
         table += '<td><input type="text" name="' + k + '" id="' + k + '" value="' + v + '" /></td>'; 
        }); 
        table += '<td><input type="checkbox" name="selected" id="selected" /></td>'; 

        table += '</tr>'; 
       }); 
       table += '<tr><td><input type="submit" id="submit" name="submit" value="Save To Database" /></td></tr>'; 
       table += '</table>'; 
       $('#form').html(table); 
      }); 

và nó tạo ra HTML này (10 dòng của lĩnh vực đầu vào, 7 cột và 1 hộp): http://jsfiddle.net/8zpr2fkL/1/

và tôi nộp mẫu đơn khi nút gửi được nhấp:

$("#form").submit(function (event) { 
     $.post("/api/update/", $("#form").serialize(), alert('success')); 
    }); 

Bây giờ tôi đi qua các dữ liệu để điều khiển API ASP.NET của tôi:

[HttpPost] 
     public dynamic Post([FromBody]CellModel cells) 
     { 
       UpdateClass jobs = new UpdateClass(); 
       return jobs; 
     } 

và đây là lớp CellModel tôi:

public class CellModel 
    { 
     public uint scheduleTaskID { get; set; } 
     public string task { get; set; } 
     public string baselineDate { get; set; } 
     public string scheduledDate { get; set; } 
     public string actualDate { get; set; } 
     public string finishedDate { get; set; } 
     public bool selected { get; set; } 

     public override string ToString() 
     { 
      return scheduleTaskID.ToString(); 
     } 
    } 

Vấn đề của tôi là khi tôi nhấn trình gửi dữ liệu và đặt một breakpoint vào phương pháp điều khiển, các tế bào đếm là 0, là có một cái gì đó tôi mất tích ở đây? Tôi đang cố gắng để vượt qua tất cả các dữ liệu trong văn bản đầu vào để điều khiển. Không có gì được truyền cho bộ điều khiển của tôi. Tôi đang làm gì sai?

Đây là dữ liệu im cố gắng để vượt qua qua jquery $ ('# form') serialize():.

scheduleTaskID=194&task=Permit&baselineDate=6%2F23%2F2005+8%3A00%3A00+AM&scheduledDate=6%2F23%2F2005+8%3A00%3A00+AM&actualDate=6%2F23%2F2005+8%3A00%3A00+AM&finishedDate=&scheduleTaskID=195&task=Office+Files&baselineDate=7%2F13%2F2005+8%3A00%3A00+AM&scheduledDate=7%2F13%2F2005+8%3A00%3A00+AM&actualDate=7%2F13%2F2005+8%3A00%3A00+AM&finishedDate=&scheduleTaskID=196&task=Foundation&baselineDate=7%2F27%2F2005+8%3A00%3A00+AM&scheduledDate=7%2F27%2F2005+8%3A00%3A00+AM&actualDate=8%2F13%2F2005+8%3A00%3A00+AM&finishedDate=&scheduleTaskID=197&task=Framing&baselineDate=8%2F5%2F2005+8%3A00%3A00+AM&scheduledDate=8%2F5%2F2005+8%3A00%3A00+AM&actualDate=8%2F23%2F2005+8%3A00%3A00+AM&finishedDate=&scheduleTaskID=198&task=Finishes+Exterior&baselineDate=8%2F26%2F2005+8%3A00%3A00+AM&scheduledDate=8%2F26%2F2005+8%3A00%3A00+AM&actualDate=9%2F14%2F2005+8%3A00%3A00+AM&finishedDate=&scheduleTaskID=199&task=Drywall&baselineDate=9%2F2%2F2005+8%3A00%3A00+AM&scheduledDate=9%2F2%2F2005+8%3A00%3A00+AM&actualDate=9%2F16%2F2005+8%3A00%3A00+AM&finishedDate=&scheduleTaskID=200&task=Flooring&baselineDate=9%2F1%2F2005+8%3A00%3A00+AM&scheduledDate=9%2F1%2F2005+8%3A00%3A00+AM&actualDate=9%2F20%2F2005+8%3A00%3A00+AM&finishedDate=&scheduleTaskID=201&task=General+Finish&baselineDate=9%2F12%2F2005+8%3A00%3A00+AM&scheduledDate=9%2F12%2F2005+8%3A00%3A00+AM&actualDate=&finishedDate=&scheduleTaskID=202&task=Final+PDI&baselineDate=10%2F11%2F2005+8%3A00%3A00+AM&scheduledDate=10%2F11%2F2005+8%3A00%3A00+AM&actualDate=&finishedDate=&scheduleTaskID=203&task=Permit&baselineDate=4%2F6%2F2005+8%3A00%3A00+AM&scheduledDate=4%2F6%2F2005+8%3A00%3A00+AM&actualDate=4%2F6%2F2005+8%3A00%3A00+AM&finishedDate= 

CẬP NHẬT

Tôi đã thay đổi:

$("#form").submit(function (event) { 
      $.post("/api/update/", $("#form").serialize(), alert('success')); 
     }); 

đến

$("#form").submit(function (event) { 
     var array = []; 
     $('#form > table > tbody > tr').each(function (elem) { 
      var item = {}; 
      item.scheduleTaskID = $(this).find("td > #scheduleTaskID").val(); 
      item.task = $(this).find("td > #task").val(); 
      item.baselineDate = $(this).find("td > #baselineDate").val(); 
      item.scheduledDate = $(this).find("td > #scheduledDate").val(); 
      item.actualDate = $(this).find("td > #actualDate").val(); 
      item.finishedDate = $(this).find("td > #finishedDate").val(); 
      item.selected = $(this).find("td > #selected").val(); 
      array.push(item); 
     }); 
     console.log(JSON.stringify(array)); 
     $.post("/api/update/", JSON.stringify(array), alert('success'), 'json'); 
    }); 

trong giao diện điều khiển của tôi đăng nhập dữ liệu của tôi trông như thế này:

[{"scheduleTaskID":"203","task":"Permit","baselineDate":"4/6/2005 8:00:00 AM","scheduledDate":"4/6/2005 8:00:00 AM","actualDate":"4/6/2005 8:00:00 AM","finishedDate":"","selected":"on"},{"scheduleTaskID":"195","task":"Office Files","baselineDate":"7/13/2005 8:00:00 AM","scheduledDate":"7/13/2005 8:00:00 AM","actualDate":"7/13/2005 8:00:00 AM","finishedDate":"","selected":"on"},{"scheduleTaskID":"196","task":"Foundation","baselineDate":"7/27/2005 8:00:00 AM","scheduledDate":"7/27/2005 8:00:00 AM","actualDate":"8/13/2005 8:00:00 AM","finishedDate":"","selected":"on"},{"scheduleTaskID":"197","task":"Framing","baselineDate":"8/5/2005 8:00:00 AM","scheduledDate":"8/5/2005 8:00:00 AM","actualDate":"8/23/2005 8:00:00 AM","finishedDate":"","selected":"on"},{"scheduleTaskID":"198","task":"Finishes Exterior","baselineDate":"8/26/2005 8:00:00 AM","scheduledDate":"8/26/2005 8:00:00 AM","actualDate":"9/14/2005 8:00:00 AM","finishedDate":"","selected":"on"},{"scheduleTaskID":"199","task":"Drywall","baselineDate":"9/2/2005 8:00:00 AM","scheduledDate":"9/2/2005 8:00:00 AM","actualDate":"9/16/2005 8:00:00 AM","finishedDate":"","selected":"on"},{"scheduleTaskID":"200","task":"Flooring","baselineDate":"9/1/2005 8:00:00 AM","scheduledDate":"9/1/2005 8:00:00 AM","actualDate":"9/20/2005 8:00:00 AM","finishedDate":"","selected":"on"},{"scheduleTaskID":"201","task":"General Finish","baselineDate":"9/12/2005 8:00:00 AM","scheduledDate":"9/12/2005 8:00:00 AM","actualDate":"","finishedDate":"","selected":"on"},{"scheduleTaskID":"202","task":"Final PDI","baselineDate":"10/11/2005 8:00:00 AM","scheduledDate":"10/11/2005 8:00:00 AM","actualDate":"","finishedDate":"","selected":"on"},{"scheduleTaskID":"203","task":"Permit","baselineDate":"4/6/2005 8:00:00 AM","scheduledDate":"4/6/2005 8:00:00 AM","actualDate":"4/6/2005 8:00:00 AM","finishedDate":"","selected":"on"},{}] 

và trong API điều khiển ASP.NET của tôi, tôi đã thay đổi phương pháp của tôi như thế này:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Web.Http; 
using MvcApplication1.Models; 

namespace MvcApplication1.Controllers 
{ 
    public class UpdateController : ApiController 
    { 
     [HttpPost] 
     public dynamic Post(List<CellModel> cells) 
     { 
       UpdateClass jobs = new UpdateClass(); 
       //jobs.PostScheduledTasks(cells); 
       return cells; 
     } 

    } 
} 

tôi đặt một breakpoint vào lúc bắt đầu phương thức Post và khi nó chạm vào breakpoint, nó nói rằng các ô Count = 0. .Tôi thấy cuộc gọi mạng, chỉ khi tôi đặt trả về false sau khi cuộc gọi post của tôi và phản hồi trống rỗng [] Tại sao dữ liệu không chuyển đến bộ điều khiển của tôi, có phải vì biểu mẫu đang được tạo ra bởi jquery không?

CẬP NHẬT

Vẫn không có giải pháp, tôi nhìn cuộc gọi mạng của tôi PM này và Mã trạng thái là 301:

enter image description here

+1

nên không có được một danh sách các CellModels? Dường như bạn đang gửi lại hơn 1 ... Điều này có thể không giải quyết được vấn đề, nhưng cái gì của nó để nhìn vào ... –

+0

Có Tôi gửi nhiều hơn một .... – user979331

+0

Một điều khác để thử. Bạn đã đưa ra [FromBody] từ bài đăng của mình chưa? Ngoài ra, đó là dữ liệu được tạo ra từ một cái gì đó như Fiddlr? Đó có phải là những gì đang được truyền qua mạng không? –

Trả lời

19

Không sử dụng $ .post ajax sử dụng bài và đặt loại nội dung thành "application/json; charset = utf-8"

var data = JSON.stringify(array); 
$.ajax({ 
    url:"/api/update/", 
    type:"POST", 
    data:data, 
    contentType:"application/json; charset=utf-8", 
    dataType:"json", 
    success: function(data){ 
    console.log(data); 
    } 
}); 

vấn đề là bạn cần phải nói với máy chủ web bạn đang gửi json và không thể với $.gửi

Đây thực sự là bình thường, và tôi đã phải vật lộn với quá này (và đôi khi tôi vẫn quên), ở đây bạn có thể thấy rằng bạn phải sử dụng $ .ajax

Jquery - How to make $.post() use contentType=application/json?

+0

Có !!!! Điều này làm việc :) Cảm ơn bạn rất nhiều – user979331

+2

@ user979331 Nó hoạt động, nhưng nó có hiệu suất không gian thời gian tồi tệ hơn so với một giải pháp sử dụng $ .post (kiểm tra câu trả lời của tôi). Bạn đang chuyển đổi các phần tử biểu mẫu thành JSON trong vòng lặp foreach và thực hiện tìm kiếm DOM lặp lại bằng cách sử dụng jQuery hoàn toàn không cần thiết. Nó đơn giản hơn nhiều để chỉ cần serialize hình thức và đăng bài nếu bạn làm theo các quy tắc được nêu dưới đây. –

+0

@ TheZenCoder, không biết cách tiếp cận của bạn, là tốt, nhưng tôi sau khi đọc tất cả các liên kết tôi thấy rằng việc mất hiệu suất ở phía khách hàng là đáng khinh. (Thành thật mà nói) Tôi có thể đã không làm việc với các hình thức lớn, tôi không biết bất kỳ hình thức nào khác, nhưng hình thức trung bình bạn có thể tạo ra không có mất mát. Dù sao tôi đã bình chọn cách tiếp cận của bạn là tích cực. Chúc một ngày cuối tuần vui vẻ: D – dariogriffo

0

tôi biết, điều này đã được giải quyết bằng cách sử dụng .ajax thay vì .post. Tôi đã nghĩ đến việc chia sẻ điều này, vì tôi đã giải quyết vấn đề này bằng cách sử dụng .post. Như đã đề cập ở trên, vì bài đăng có loại nội dung Content-Type:application/x-www-form-urlencoded; charset=UTF-8, tham số cells trong phương thức bài đăng sẽ chứa count = 0.

Để giải quyết vấn đề này, bạn phải tự chụp đối tượng yêu cầu và nhận dữ liệu bài đăng và sau đó thực hiện deserialize và nhận đối tượng là List<CellModel>. Tôi đã sử dụng tất cả các mã được đăng bởi OP, và chỉ sửa đổi post phương pháp như thể hiện trong sau, và nó đã làm việc.

[HttpPost] 
public dynamic Post(List<CellModel> cells) 
{ 
    string content = string.Empty; 
    if (HttpContext.Current.Request.InputStream.CanSeek) 
    { 
     HttpContext.Current.Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin); 
    } 
    using (System.IO.StreamReader reader = new System.IO.StreamReader(HttpContext.Current.Request.InputStream)) 
    { 
     content = reader.ReadToEnd(); 
    } 
    if (!string.IsNullOrEmpty(content)) 
    { 
     // Deserialize and operate over cells. 
     try 
     { 
      var obj = Newtonsoft.Json.JsonConvert.DeserializeObject(content, typeof(List<CellModel>)); 
     } 
     catch (Exception ex) 
     { 
      return ex; 
     } 

    } 
    return cells; 
} 

Đây là những gì tôi nhận được khi gỡ lỗi.

enter image description here

enter image description here

+0

Giả sử rằng bạn có 120 điểm cuối POST trong API của bạn, điều này hoàn toàn không thể khôi phục được – dariogriffo

+0

Tôi không biết, điều gì sẽ là OP của chúng tôi cho điều này, nếu bạn biết điều đó, hãy cho tôi biết, tôi đã cố giải quyết bằng ' .post', và đó là doable. Nhưng có, '.axax' là cách tốt nhất để xử lý' HTTPPost' được sử dụng trong webapi. –

4

Trong khi bạn có một cách tiếp cận khác bởi @dariogriffo, tôi muốn cung cấp cho bạn một giải pháp đầy đủ sử dụng cách tiếp cận ban đầu của bạn với $ .post.

cách tiếp cận ban đầu của bạn với hình thức serialization là đúng, vì vậy đoạn mã sau là đúng:

$("#form").submit(function (event) { 
    $.post("/api/update/", $("#form").serialize(), alert('success')); 
}); 

Tuy nhiên, điều này đã không làm việc vì hình thức động của bạn không tuân theo quy ước đặt tên cho các lĩnh vực đầu vào dự kiến bởi chất kết dính mô hình mặc định của ASP.NET MVC, và kết quả là dạng tuần tự hóa của bạn không phải là thứ mà trình mô hình hóa mặc định có khả năng liên kết với mô hình cells của bạn. Đó là lý do tại sao bạn không nhận được bất kỳ tế bào nào trong bộ điều khiển khi thực hiện POST.

Để làm rõ điều đó có nghĩa, ASP.NET dự kiến ​​mỗi lĩnh vực đầu vào tương ứng với một tài sản mô hình có định dạng tên sau đây nếu bạn đang gửi bài đến một thường xuyên MVC 5 Bộ điều khiển:

actionattributename[index].propertyname 

Nếu bạn là gửi bài đến một bộ điều khiển Web API 2 nó nên là:

[index].propertyname 

Kể từ khi thuộc tính hành động của bạn được đặt tên cells và nó có một tài sản scheduledTaskID, và bạn đang gửi bài đến một bộ điều khiển WebAPI một trong những đóng góp của bạn sẽ trông như thế:

<input type="text" name="[0].scheduleTaskID" id="scheduleTaskID" value="194"> 

Có một vài quy tắc khác liên quan đến việc cấu trúc biểu mẫu để làm cho biểu mẫu có thể liên kết. Bạn có thể tìm thấy một bài đăng blog tốt đẹp về nó ở đây:

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

Nếu bạn sau đó ước mẫu bạn sẽ có thể gửi bài dưới hình thức tuần tự của bạn để điều khiển của bạn mong đợi một List<CellModel> cellsmà không cần phải sử dụng phương pháp JSON, đó là đắt hơn nhiều như được đề xuất trong các câu trả lời khác.

Dưới đây là một fiddle với một hình thức ví dụ cấu trúc một cách chính xác bởi Web API quy tắc chất kết dính 2 mặc định:

http://jsfiddle.net/8zpr2fkL/12/

Bạn có thể thử đến $ .post hình thức này sử dụng $ .post để điều khiển web api của bạn và nó sẽ hoạt động như một sự quyến rũ!

+0

Tôi thích giải pháp này – dariogriffo

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