Thông số bài viết luôn là null


197

Kể từ khi nâng cấp lên RC cho WebAPI, tôi gặp một số vấn đề kỳ lạ khi gọi POST trên WebAPI của mình. Tôi thậm chí đã quay lại phiên bản cơ bản được tạo trong dự án mới. Vì thế:

public void Post(string value)
{
}

và gọi từ Fiddler:

Header:
User-Agent: Fiddler
Host: localhost:60725
Content-Type: application/json
Content-Length: 29

Body:
{
    "value": "test"
}

Khi tôi gỡ lỗi, chuỗi "giá trị" không bao giờ được gán cho. Nó luôn luôn là NULL. Bất cứ ai có vấn đề này?

(Lần đầu tiên tôi thấy vấn đề với một loại phức tạp hơn)

Vấn đề không chỉ liên quan đến ASP.NET MVC 4, vấn đề tương tự xảy ra đối với một dự án ASP.NET MVC 3 mới sau khi cài đặt RC


Chỉ cần thêm vào vấn đề - nó không độc quyền với JSON, nó cũng xảy ra với XML.
ianrathbone

3
Tôi đã làm phiền với điều này trong hai ngày và sau khi đọc mọi bài viết tôi có thể tìm thấy về nó, hóa ra nó đơn giản như định dạng chuỗi JSON chính xác trong WebRequest: Dữ liệu phải bắt đầu và kết thúc bằng dấu ngoặc kép và nếu bạn thì sử dụng dấu ngoặc đơn trong suốt dữ liệu json của bạn, tất cả đều chơi tốt.
Gineer

Câu trả lời:


101

Vì bạn chỉ có một tham số, bạn có thể thử trang trí nó bằng [FromBody]thuộc tính hoặc thay đổi phương thức để chấp nhận DTO có giá trị như một thuộc tính, như tôi đã đề xuất ở đây: ràng buộc tham số MVC4 RC WebApi

CẬP NHẬT: Trang web ASP.NET chính thức được cập nhật ngày hôm nay với một lời giải thích tuyệt vời: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advified/seinating-html-form-data-part- 1

Tóm lại, khi gửi một loại đơn giản trong thân, chỉ gửi giá trị có tiền tố bằng dấu (=), ví dụ: thân:

=test


9
Tôi đã tạo cho [FromBody] một vòng xoáy nhưng nó không có thay đổi
ianrathbone

11
Chỉ truyền giá trị (tức là không phải là một đối tượng JSON) và nó sẽ hoạt động, theo blog.msdn.com/b/jmstall/archive/2012/04/16/ mẹo
Jim Harte

8
Phần bổ sung =ở phía trước chưa bao giờ có tác dụng với tôi, cho đến khi tôi làm theo lời khuyên của Jim trong bình luận của anh ấy (không phải là một đối tượng JSON) và nó đã hoạt động. Đây là chìa khóa! Tôi thực sự không thích cách WebAPI cầu kỳ.
gitsitgo

16
Điều này thật ngu ngốc và khó chịu đến nỗi tôi không biết nên nâng cấp hay hạ thấp câu trả lời đã giúp tôi giải quyết vấn đề của mình ... Tại sao nó lại phải ở định dạng này? (Xin lỗi vì thái độ, chỉ lãng phí quá nhiều thời gian cho việc này, và nó không có ý nghĩa gì cả ... :(). Bạn thực sự nên thêm hỗ trợ cho định dạng mà mọi người mong đợi nó chấp nhận.
gdoron đang hỗ trợ Monica

6
Cảm ơn! Làm thế nào trên trái đất chúng ta nên biết rằng chúng ta phải xóa tên tham số khi chỉ gửi một tham số? Mà Birdbrain đã đưa ra ý tưởng này?
Jenny O'Reilly

104

Tôi đã gãi đầu trong ngày hôm nay.

Giải pháp của tôi là thay đổi [FromBody]thành a HttpRequestMessage, về cơ bản di chuyển lên ngăn xếp HTTP.

Trong trường hợp của tôi, tôi đang gửi dữ liệu qua dây được nén json, sau đó là base64'd. Tất cả điều này từ một ứng dụng Android.

Chữ ký gốc của điểm cuối web của tôi trông như thế này (sử dụng [FromBody]):

Điểm cuối của tôi

Khắc phục của tôi cho vấn đề này là hoàn nguyên về việc sử dụng HttpRequestMessagechữ ký của điểm cuối của tôi.

nhập mô tả hình ảnh ở đây

Sau đó, bạn có thể có quyền truy cập vào dữ liệu bài đăng bằng dòng mã này:

nhập mô tả hình ảnh ở đây

Điều này hoạt động và cho phép bạn truy cập vào dữ liệu bài chưa được xử lý. Bạn không phải loay hoay với fiddler đặt dấu = ở đầu chuỗi của bạn hoặc thay đổi loại nội dung.

Bên cạnh đó, trước tiên tôi đã cố gắng làm theo một trong những câu trả lời ở trên đó là thay đổi loại nội dung thành: "Loại nội dung: application / x-www-form-urlencoding". Đối với dữ liệu thô, đây là lời khuyên tồi vì nó loại bỏ + ký tự.

Vì vậy, một chuỗi base64 bắt đầu như thế này: "MQ0AAB + LCAAAAAA" kết thúc như thế này "MQ0AAB LCAAAAAA"! Không phải những gì bạn muốn.

Một lợi ích khác của việc sử dụng HttpRequestMessagelà bạn có quyền truy cập vào tất cả các tiêu đề http từ trong điểm cuối của bạn.


6
Giải pháp tuyệt vời ... tôi đã mất 9 giờ để tìm ra vấn đề này, đã giải quyết vấn đề của mình sau khi tôi xóa giá trị chuỗi [FromBody] và thay thế nó bằng HttpRequestMessage
Kev

1
Hoạt động như một lá bùa! nhưng không có cách nào để sử dụng một loại tham số thực tế của một đối tượng nhất định? ví dụ: tham số loại Đặt hàng cho phương pháp api web?
Ron Nuni

7
Chỉ cần một lưu ý phụ, bạn KHÔNG CẦN HttpRequestMessage requestchữ ký phương thức, vì bạn luôn có sẵn điều này. Trong thân phương thức, nó có thể được truy cập trên Requestđối tượng. ví dụRequest.Content.ReadAsStringAsync().Result;
Morvael

Thông thường vấn đề này là do đối tượng JSON của bạn không chính xác. Tôi đã tìm thấy điều này luôn bởi vì trong hàm tạo có loại không hợp lệ và Json không biết cách chuyển đổi nó 'Giống như một Hướng dẫn thành một chuỗi. Vì vậy, hãy thêm trình chuyển đổi qua cài đặt hoặc thêm hàm tạo trống và bạn không cần quay lại mã cũ như thế này.
Nick Turner

Cách dễ nhất là chuyển đối tượng thành một chuỗi và sau đó thử và chuyển đổi nó và bạn sẽ thấy lỗi JSON. Kiểm tra tiêu đề của bạn cũng.
Nick Turner

71

Tôi vừa mới xảy ra điều này khi sử dụng Fiddler. Vấn đề là tôi đã không chỉ định Content-Type.

Hãy thử bao gồm một tiêu đề cho Content-Typetrong yêu cầu POST của bạn.

Content-Type: application/x-www-form-urlencoded

Ngoài ra, theo nhận xét bên dưới, bạn có thể cần bao gồm tiêu đề JSON

Content-Type: application/json

11
Tôi gặp vấn đề tương tự, ngoại trừ việc tôi cần đặt Loại nội dung: application / json
dvallejo

2
Như được chỉ định trong bài đăng - Tôi đã thêm Loại nội dung: application / json
ianrathbone

2
application / x-www-form-urlencoding không hoạt động với tôi, Loại nội dung: application / json đã làm.
liang

1
Bất kể loại nội dung, nếu bạn chỉ có một tham số, bạn phải chỉ gửi giá trị mà không có tên tham số trong phần thân của yêu cầu. Vì vậy, id = 13 sẽ không hoạt động. Bạn cần gửi 13 một mình. Xem câu trả lời của Jim.
Jenny O'Reilly

Tôi đã phải sử dụng contentType: "application/x-www-form-urlencoded; charset=UTF-8", ví dụ hoàn chỉnh, xem Toàn bộ bệnh nhân và máy chủ
RyBolt

57

Tôi cũng gặp phải vấn đề này và đây là cách tôi giải quyết vấn đề của mình

mã webapi:

public void Post([FromBody] dynamic data)
{
    string value = data.value;
    /* do stuff */
}

mã khách hàng:

$.post( "webapi/address", { value: "some value" } );

1
Điều này hoạt động nếu máy khách đang gửi JSON. Nếu tôi đang gửi một giá trị đơn giản như chuỗi some value, thì datanull.
brianestey

dễ dàng, thay đổi mã máy khách của bạn để gửi lại một đối tượng js.
George

Cách tuyệt vời và sạch sẽ để lấy dữ liệu từ JSON
Wouter Vanherck

Nếu bạn đang gửi json, thì var json = JsonConvert.SerializeObject (data);
dvallejo

41

Tôi đã sử dụng Postmanvà tôi đã làm một lỗi tương tự .. chuyển valueđối tượng dưới dạng json thay vì chuỗi

{
    "value": "test"
}

Rõ ràng cái trên là sai khi tham số api có kiểu chuỗi.

Vì vậy, chỉ cần vượt qua chuỗi trong dấu ngoặc kép trong cơ thể api:

"test"

2
Đây là vấn đề của tôi, và có khả năng là giải pháp thực sự cho câu hỏi. Một chuỗi được mã hóa JSON có dấu ngoặc kép
Kyle W

1
Tôi cũng gặp phải vấn đề này trên Postman. Hóa ra tôi đã chọn sai "dữ liệu biểu mẫu" thay vì "thô" cho phần thân khi Kiểu nội dung được đặt thành ứng dụng / json. Bạn có thể tham khảo ảnh chụp màn hình của zzyykk123456 tại Các vấn đề của aspnet Github: github.com/aspnet/Home/issues/2202
Chun Lin

Điều này làm việc cho tôi. Sử dụng Swagger (swashbuckle) Tôi phải đặt Loại nội dung: application / json và sử dụng dấu ngoặc kép.
John Henckel

1
Chính xác là vấn đề của tôi Nhưng tôi phải lưu ý rằng trong các yêu cầu của Ajax, bạn nên thực hiện 'dữ liệu: JSON.opesify ("YourString")'
Amir Hossein Ahmadi

1
@AmirHosseinAhmadi Tôi mới bắt gặp điều này trên ajax và thấy rằng việc sử dụng thực sự JSON.stringifyđã khiến tôi [frombody]bị như vậy null. Sau khi đặt trường dữ liệu thành giá trị chuỗi (đó là chuỗi json), nó đã hoạt động.
Nexaspx

19

Hãy thử tạo một lớp để làm mô hình dữ liệu, sau đó gửi một đối tượng JSON có các thuộc tính khớp với các thuộc tính của lớp mô hình dữ liệu của bạn. (Lưu ý: Tôi đã thử nghiệm điều này và nó hoạt động với MVC 4 RC 2012 mới nhất mà tôi vừa tải xuống hôm nay).

public HttpResponseMessage Post(ValueModel model)
{
    return Request.CreateResponse<string>(HttpStatusCode.OK, "Value Recieved: " + model.Value);
}

public class ValueModel
{
    public string Value { get; set; }
}

Đối tượng JSON bên dưới được gửi trong phần thân HTTP-POST, kiểu nội dung là application / json

{ "value": "In MVC4 Beta you could map to simple types like string, but testing with RC 2012 I have only been able to map to DataModels and only JSON (application/json) and url-encoded (application/x-www-form-urlencoded body formats have worked. XML is not working for some reason" }

Tôi tin rằng lý do tại sao bạn phải tạo một lớp mô hình dữ liệu là bởi vì các giá trị đơn giản được giả sử là từ các tham số url và một giá trị phức tạp duy nhất được giả sử là từ phần thân. Họ có các thuộc tính [FromBody][FromUrl], nhưng sử dụng[FromBody] string value vẫn không làm việc cho tôi. Có vẻ như họ vẫn đang tìm ra rất nhiều lỗi nên tôi chắc chắn điều này sẽ thay đổi trong tương lai.

Chỉnh sửa: Có XML để hoạt động trong cơ thể. Trình tuần tự hóa XML mặc định đã được thay đổi thành DataContractSerializer thay vì XmlSerializer. Đặt dòng sau vào tệp Global.asax của tôi đã khắc phục sự cố này ( tham khảo )

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;

điều này làm việc với tôi với request.ContentType = "application / json; charset = UTF-8";
Arvind Krmar

15

Sau một số lần thử, tôi nghĩ rằng hành vi mặc định là chính xác và không có gì để hack.

Bí quyết duy nhất là: nếu đối số phương thức bài đăng của bạn stringgiống như bên dưới, bạn nên gửi một chuỗi đơn giản với dấu ngoặc kép trong phần thân (khi sử dụng ajax hoặc người đưa thư), ví dụ:

//send "{\"a\":1}" in body to me, note the outer double quotes
[HttpPost("api1")]
public String PostMethod1([FromBody]string value)
{
    return "received " + value; //  "received {\"a\":1}"
}

Mặt khác, nếu bạn gửi một chuỗi json trong phần thân bài mà không có dấu ngoặc kép bên ngoài và thoát dấu ngoặc kép bên trong, thì nó sẽ có thể được phân tích cú pháp đến lớp mô hình (kiểu đối số), ví dụ:{"a":1, "b":2}

public class MyPoco{
    public int a;
    public int b;
}

//send {"a":1, "b":2} in body to me
[HttpPost("api2")]
public String PostMethod2([FromBody]MyPoco value)
{
    return "received " + value.ToString();  //"received your_namespace+MyPoco"
}

11

Tôi đã tìm kiếm một giải pháp cho vấn đề này trong vài phút, vì vậy tôi sẽ chia sẻ giải pháp của mình.

Nếu bạn đăng một mô hình, mô hình của bạn cần phải có một hàm tạo trống / mặc định, nếu không thì rõ ràng mô hình đó không thể được tạo. Hãy cẩn thận trong khi tái cấu trúc. ;)


Tái cấu trúc là chính xác những gì tôi bit ở đây, cảm ơn cho tiền boa!
Alan

10

Điều này làm việc cho tôi:

  1. Tạo một lớp D # CTO, với một thuộc tính cho mọi thuộc tính bạn muốn truyền từ jQuery / Ajax

    public class EntityData
    {
        public string Attr1 { get; set; }
        public string Attr2 { get; set; }
    }
  2. Xác định phương thức api web:

    [HttpPost()]
    public JObject AddNewEntity([FromBody] EntityData entityData)
    {
  3. Gọi api web như vậy:

    var entityData = {
        "attr1": "value1",
        "attr2": "value2"
    };
    
    $.ajax({
        type: "POST",
        url: "/api/YOURCONTROLLER/addnewentity",
        async: true,
        cache: false,
        data: JSON.stringify(entityData),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            ...
        }
    });

Cảm ơn bạn đã đăng bài này, tôi đã thử rất nhiều mẫu nhưng điều này hiệu quả với tôi!
Satbir

10

Đối với những người có cùng vấn đề với Swagger hoặc Postman như tôi đã làm, nếu bạn chuyển một thuộc tính đơn giản dưới dạng chuỗi trong bài đăng, ngay cả với "ContentType" được chỉ định, bạn vẫn sẽ nhận được giá trị null.

Đi qua chỉ:

MyValue

Sẽ nhận được trong bộ điều khiển là null.

Nhưng nếu bạn vượt qua:

"MyValue"

Giá trị sẽ nhận được ngay.

Các trích dẫn đã làm cho sự khác biệt ở đây. Tất nhiên, điều này chỉ dành cho Swagger và Postman. Chẳng hạn, trong ứng dụng Frontend sử dụng Angular, điều này sẽ được giải quyết bằng khung tự động.


6

Tôi gặp vấn đề tương tự và thấy rằng khi thay đổi Loại nội dung thành "application / json" không khắc phục được sự cố. Tuy nhiên "application / json; charset = utf-8" đã hoạt động.


Yup, API Web sẽ không được khử lưu lượng nếu không có bộ ký tự = utf-8. blog.codenamed.nl/2015/05/12/ cường
Sam

4

Tôi gặp vấn đề tương tự trong đó đối tượng yêu cầu cho phương pháp API Web của tôi luôn là null. Tôi nhận thấy rằng vì tên hành động của bộ điều khiển có tiền tố là "Nhận", API Web đã coi đây là HTTP GET chứ không phải là POST. Sau khi đổi tên hành động của bộ điều khiển, bây giờ nó hoạt động như dự định.


3

Với Angular, tôi có thể truyền dữ liệu ở định dạng này:

 data: '=' + JSON.stringify({ u: $scope.usrname1, p: $scope.pwd1 }),
 headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' }

Và trong Trình kiểm soát API Web:

    [HttpPost]
    public Hashtable Post([FromBody]string jsonString)
    {
        IDictionary<string, string> data = JsonConvert.DeserializeObject<IDictionary<string, string>>(jsonString);
        string username = data["u"];
        string pwd = data["p"];
   ......

Ngoài ra, tôi cũng có thể đăng dữ liệu JSON như thế này:

    data: { PaintingId: 1, Title: "Animal show", Price: 10.50 } 

Và, trong bộ điều khiển, chấp nhận một loại lớp như thế này:

    [HttpPost]
    public string POST(Models.PostModel pm)
    {

     ....
    }

Dù bằng cách nào, nếu bạn có một lớp công khai được thiết lập trong API thì hãy đăng JSON, nếu không thì hãy đăng '=' + JSON.opesify ({..: ..., ..: ...})


3

Trong trường hợp của tôi, vấn đề là tham số là một chuỗi chứ không phải đối tượng, tôi đã thay đổi tham số thành JObject của Newsoft.Json và nó hoạt động.


2

Thêm dòng

        ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

đến cuối chức năng protected void Application_Start()trong Global.asax.cs đã khắc phục sự cố tương tự đối với tôi trong ASP.NET MVC3.


Cảm ơn sự giúp đỡ nhưng tiếc là nó đã không giúp đỡ. Tôi sẽ giữ dòng trong thời gian này vì nó có thể giúp đỡ bằng mọi cách!
ianrathbone

Chỉ cần thêm các vấn đề tương tự xảy ra khi tôi đăng XML
ianrathbone

2

Nếu bạn đang sử dụng DataContractSerializer cho Xml Formatter hoặc JSON Formatter, bạn cần loại bỏ nó. Tôi đã có cái này trong tệp WebApiConfig của mình:

public static void Register(HttpConfiguration config)
{
     config.Routes.MapHttpRoute(
           name: "DefaultApi",
           routeTemplate: "api/{controller}/{id}",
           defaults: new { id = RouteParameter.Optional }
     );    

     var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
     jsonFormatter.UseDataContractJsonSerializer = true;
}

Đơn giản là tôi bình luận jsonFormatter.UseDataContractJsonSerializer = true;và tham số đầu vào của tôi không còn nữa. Cảm ơn 'Despertar' đã cho tôi manh mối.


2

Nếu bạn chắc chắn về JSON đã gửi của mình thì bạn phải theo dõi API cẩn thận:

  1. Cài đặt Microsoft.AspNet.WebApi.Tracinggói
  2. Thêm config.EnableSystemDiagnosticsTracing();vào WebApiConfiglớp bên trong Registerphương thức.

Bây giờ hãy nhìn vào đầu ra Debug và bạn có thể sẽ thấy không hợp lệ ModelState mục nhật ký .

Nếu ModelStatekhông hợp lệ, bạn có thể tìm thấy nguyên nhân thực sự trong đó Errors:

Thậm chí không ai có thể đoán được một ngoại lệ như vậy:

Could not load file or assembly 'Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

bạn đã cứu cuộc đời tôi. Lấy null làm mô hình và sau khi cài đặt gói, thấy rằng JSON của tôi không đúng định dạng.
Khizar Iqbal

2

Tôi có cùng một vấn đề nhận null là tham số, nhưng nó có liên quan đến các đối tượng lớn. Hóa ra vấn đề liên quan đến chiều dài tối đa của IIS. Nó có thể được cấu hình trong web.config.

  <system.web>
    <httpRuntime targetFramework="4.7" maxRequestLength="1073741824" />
  </system.web>

Tôi tự hỏi tại sao API Web đã khắc phục lỗi và gửi các đối tượng null đến API của tôi. Tôi đã tìm thấy lỗi khi sử dụng Microsoft.AspNet.WebApi.Tracing.



1

Tôi biết đây không phải là một câu trả lời cho câu hỏi này, nhưng tôi đã gặp nó khi tìm kiếm một giải pháp cho vấn đề của tôi.

Trong trường hợp của tôi, loại phức tạp không bị ràng buộc nhưng tôi không thực hiện POST, tôi đang thực hiện GET với các tham số chuỗi truy vấn. Giải pháp là thêm [FromUri] vào đối số:

public class MyController : ApiController
{
    public IEnumerable<MyModel> Get([FromUri] MyComplexType input)
    {
        // input is not null as long as [FromUri] is present in the method arg
    }
}

Đó là vì phần thân của yêu cầu bị bỏ qua (và đôi khi gây ra lỗi) khi sử dụng GET. Lý do nó hoạt động bây giờ là vì bạn hiện đang truyền tham số vào chuỗi truy vấn và cơ thể của bạn trống rỗng như trên GET
RyBolt

1

Tôi đã có cùng một vấn đề trong Fiddler. Tôi đã có Content-Type: application/json; charset=utf-8hoặc Content-Type: application/jsontrong tiêu đề yêu cầu.

Cơ thể yêu cầu của tôi cũng là một chuỗi đơn giản và trong Fiddler tôi đã viết : {'controller':'ctrl'}. Điều này làm cho tham số chuỗi trong phương thức POST của tôi được null.

Khắc phục : nhớ sử dụng dấu ngoặc kép, từ đó chỉ ra một chuỗi. Đó là, tôi đã sửa nó bằng cách viết "{'controller':'ctrl'}". (Lưu ý: khi viết JSON, hãy chắc chắn sử dụng dấu nháy đơn hoặc thoát các dấu ngoặc kép như thế này "{\"controller\":\"ctrl\"}":).


Tôi đã phải làm điều tương tự trong Postman. Nhưng tôi không cần phải làm điều này khi tôi gọi các dịch vụ Mùa xuân. Có vẻ như một vấn đề về phía .Net.
Malcolm McRoberts

1

Cách đơn giản nhất mà tôi tìm thấy để đối phó với đối tượng JSON đơn giản mà tôi chuyển vào MVC 6 là lấy loại tham số bài đăng như NewtonSoft jObject:

public ActionResult Test2([FromBody] jObject str)
{
        return Json(new { message = "Test1 Returned: "+ str }); ;
}

Test ( [FromBody] object body, [FromHeader(Name="Content-Type")] string bodyMediaType) có thể hoạt động tốt hơn khi kiểm tra bodyMediaType == "application.json"trước khi chuyển cơ thể sang JObject cung cấp cơ hội cho các thay thế.
VladH

1

Giải pháp tốt nhất cho tôi là sử dụng HTTP đầy đủ như dưới đây:

[Route("api/open")]
[HttpPost]
public async Task<string> open(HttpRequestMessage request)
{
    var json = await request.Content.ReadAsStringAsync();
    JavaScriptSerializer jss = new JavaScriptSerializer();            
    WS_OpenSession param = jss.Deserialize<WS_OpenSession>(json);
    return param.sessionid;
}

và sau đó giải tuần tự hóa chuỗi cho đối tượng bạn mong đợi trong phần thân bài. Đối với tôi, WS_OpenSession là một lớp có chứa sessionid, người dùng và khóa.

Bạn có thể từ đó sử dụng đối tượng param và truy cập các thuộc tính của nó.

Rất rất hiệu quả.

Tôi đã nói có nguồn gốc từ url này:

http://bizcoder.com/posting-raw-json-to-web-api


1

Đối với các loại phức tạp, API Web cố gắng đọc giá trị từ nội dung thư, sử dụng trình định dạng loại phương tiện.

Vui lòng kiểm tra nếu bạn có bất kỳ [Serializable] thuộc tính trang trí lớp mô hình của bạn.

Xóa thuộc tính để xem nếu nó hoạt động. Điều này làm việc cho tôi.


1

Tôi đến bữa tiệc muộn một chút, nhưng bất kỳ ai tình cờ phát hiện ra giá trị NULL đều được thông qua khi sử dụng bộ điều khiển chỉ cần thêm "=" vào trước yêu cầu POST của bạn.

Bộ điều khiển cũng chuyển một giá trị NULL khi tôi sử dụng Kiểu nội dung của ứng dụng / json . Lưu ý Loại nội dung "application / x-www-form-urlencoding" bên dưới. Tuy nhiên, kiểu trả về từ API là "application / json".

 public static string HttpPostRequest(string url, Dictionary<string, string> postParameters)
    {
        string postData = "=";

        foreach (string key in postParameters.Keys)
        {
            postData += HttpUtility.UrlEncode(key) + "="
                  + HttpUtility.UrlEncode(postParameters[key]) + ",";
        }

        HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
        myHttpWebRequest.Method = "POST";

        byte[] data = System.Text.Encoding.ASCII.GetBytes(postData);

        myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
        myHttpWebRequest.ContentLength = data.Length;

        Stream requestStream = myHttpWebRequest.GetRequestStream();
        requestStream.Write(data, 0, data.Length);
        requestStream.Close();

        HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

        Stream responseStream = myHttpWebResponse.GetResponseStream();

        StreamReader myStreamReader = new StreamReader(responseStream, System.Text.Encoding.Default);

        string pageContent = myStreamReader.ReadToEnd();

        myStreamReader.Close();
        responseStream.Close();

        myHttpWebResponse.Close();

        return pageContent;
    }

1

không quan trọng bạn muốn đăng loại giá trị nào, chỉ cần đặt nó trong dấu ngoặc kép, để lấy nó dưới dạng chuỗi. Không cho các loại phức tạp.

javascript:

    var myData = null, url = 'api/' + 'Named/' + 'NamedMethod';

    myData = 7;

    $http.post(url, "'" + myData + "'")
         .then(function (response) { console.log(response.data); });

    myData = "some sentence";

    $http.post(url, "'" + myData + "'")
         .then(function (response) { console.log(response.data); });

    myData = { name: 'person name', age: 21 };

    $http.post(url, "'" + JSON.stringify(myData) + "'")
         .then(function (response) { console.log(response.data); });

    $http.post(url, "'" + angular.toJson(myData) + "'")
         .then(function (response) { console.log(response.data); });

c #:

    public class NamedController : ApiController
    {
        [HttpPost]
        public int NamedMethod([FromBody] string value)
        {
            return value == null ? 1 : 0;
        }
    }

1

Nếu bạn đặt chú thích [FromBody] và bạn có một đối tượng Dto làm tham số cho phương thức của mình và vẫn không thể lấy dữ liệu qua, hãy bắt đầu xem xét các thuộc tính và trường của DTO.

Tôi đã có vấn đề tương tự, nơi DTO của tôi sắp trở thành vô giá trị. Tôi tìm thấy lý do là một trong các thuộc tính đã trỏ vào một đối tượng không thể được tuần tự hóa :( khiến cho trình định dạng phương tiện không thể phân tích dữ liệu. Do đó, đối tượng luôn luôn là null.


1

Kiểm tra kỹ các loại dữ liệu của bạn. Chất kết dính mô hình dotnet sẽ không chuyển đổi một số float thành một số nguyên (và tôi giả sử các khái niệm liên quan khác). Điều này sẽ khiến toàn bộ mô hình bị từ chối.

Nếu bạn có json như thế này:

{
    "shoeSize": 10.5
}

nhưng mô hình c # của bạn trông như thế này:

class Shoe{
    public int shoeSize;
}

chất kết dính mô hình sẽ từ chối mô hình và bạn sẽ nhận được null.


1

Tôi khá muộn với vấn đề này nhưng đã gặp phải vấn đề tương tự và sau một ngày trải qua rất nhiều câu trả lời ở đây và nhận được thông tin cơ bản, tôi đã tìm thấy giải pháp đơn giản / nhẹ nhất để gửi lại một hoặc nhiều tham số cho Hành động API Web 2 như sau:

Điều này giả định rằng bạn biết cách thiết lập trình điều khiển / hành động API Web với định tuyến chính xác, nếu không tham khảo: https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with -aspnet-web-api / guide-your-first-web-api .

Đầu tiên là Bộ điều khiển hành động, giải pháp này cũng yêu cầu thư viện Newtonsoft.Json.

[HttpPost]
public string PostProcessData([FromBody]string parameters) {
    if (!String.IsNullOrEmpty(parameters)) {
        JObject json = JObject.Parse(parameters);

        // Code logic below
        // Can access params via json["paramName"].ToString();
    }
    return "";
}

Phía khách hàng sử dụng jQuery

var dataToSend = JSON.stringify({ param1: "value1", param2: "value2"...});
$.post('/Web_API_URI', { '': dataToSend }).done(function (data) {
     console.debug(data); // returned data from Web API
 });

Vấn đề chính tôi tìm thấy là đảm bảo bạn chỉ gửi một tham số tổng thể duy nhất trở lại API Web và đảm bảo rằng nó không có tên chỉ là giá trị { '': dataToSend } nếu không giá trị của bạn sẽ là null ở phía máy chủ.

Với điều này, bạn có thể gửi một hoặc nhiều tham số cho API Web trong cấu trúc JSON và bạn không cần khai báo bất kỳ phía máy chủ đối tượng bổ sung nào để xử lý dữ liệu phức tạp. JObject cũng cho phép bạn lặp lại linh hoạt tất cả các tham số được truyền trong khi cho phép khả năng mở rộng dễ dàng hơn nếu các tham số của bạn thay đổi theo thời gian. Hy vọng rằng sẽ giúp được ai đó đã đấu tranh như tôi.


0

Chính xác việc truyền tham số duy nhất trong cơ thể cho WebAPI hoạt động mã này $.post(url, { '': productId }

Và bắt nó trong hành động [HttpPost] public ShoppingCartAddRemoveViewModel Delete([FromBody]string value)

Điều quan trọng là sử dụng từ ma thuật 'giá trị'. Nó cũng có thể là int, hoặc một số loại nguyên thủy. Không có vấn đề chỉnh sửa kiểu nội dung hoặc tiêu đề Mess là mã này không hoạt động trong hành động bài mvc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.