简体   繁体   English

web-api POST 主体对象始终为空

[英]web-api POST body object always null

I'm still learning web API, so pardon me if my question sounds stupid.我仍在学习 Web API,如果我的问题听起来很愚蠢,请原谅我。

I have this in my StudentController :我的StudentController有这个:

public HttpResponseMessage PostStudent([FromBody]Models.Student student)
{
    if (DBManager.createStudent(student) != null)
        return Request.CreateResponse(HttpStatusCode.Created, student);
    else
        return Request.CreateResponse(HttpStatusCode.BadRequest, student);
}

In order to test if this is working, I'm using Google Chrome's extension "Postman" to construct the HTTP POST request to test it out.为了测试这是否有效,我使用谷歌浏览器的扩展“邮递员”来构建 HTTP POST 请求来测试它。

This is my raw POST request:这是我的原始 POST 请求:

POST /api/Student HTTP/1.1
Host: localhost:1118
Content-Type: application/json
Cache-Control: no-cache

{"student": [{"name":"John Doe", "age":18, "country":"United States of America"}]}

student is supposed to be an object, but when I debug the application, the API receives the student object but the content is always null . student应该是一个对象,但是当我调试应用程序时,API 接收到student对象但内容始终为null

FromBody is a strange attribute in that the input POST values need to be in a specific format for the parameter to be non-null, when it is not a primitive type. FromBody 是一个奇怪的属性,因为当参数不是原始类型时,输入 POST 值需要采用特定格式才能使参数为非空。 (student here) (学生在这里)

  1. Try your request with {"name":"John Doe", "age":18, "country":"United States of America"} as the json.尝试使用{"name":"John Doe", "age":18, "country":"United States of America"}作为 json 的请求。
  2. Remove the [FromBody] attribute and try the solution.删除[FromBody]属性并尝试解决方案。 It should work for non-primitive types.它应该适用于非原始类型。 (student) (学生)
  3. With the [FromBody] attribute, the other option is to send the values in =Value format, rather than key=value format.使用[FromBody]属性,另一个选项是以=Value格式而不是key=value格式发送值。 This would mean your key value of student should be an empty string...这意味着您的student键值应该是一个空字符串...

There are also other options to write a custom model binder for the student class and attribute the parameter with your custom binder.还有其他选项可以为学生类编写自定义模型绑定器并使用自定义绑定器属性参数。

I was looking for a solution to my problem for some minutes now, so I'll share my solution.几分钟以来,我一直在寻找解决问题的方法,因此我将分享我的解决方案。

When you have a custom constructor within your model, your model also needs to have an empty/default constructor.当您的模型中有自定义构造函数时,您的模型还需要有一个空/默认构造函数。 Otherwise the model can't be created, obviously.否则,显然无法创建模型。 Be careful while refactoring.重构时要小心。

I spend several hours with this issue... :( Getters and setters are REQUIRED in POST parameters object declaration. I do not recommend using simple data objects (string,int, ...) as they require special request format.我在这个问题上花了几个小时... :( 在 POST 参数对象声明中需要 Getter 和 setter。我不建议使用简单的数据对象(字符串、整数、...),因为它们需要特殊的请求格式。

[HttpPost]
public HttpResponseMessage PostProcedure(EdiconLogFilter filter){
...
}

Does not work when:在以下情况下不起作用:

public class EdiconLogFilter
{
    public string fClientName;
    public string fUserName;
    public string fMinutes;
    public string fLogDate;
}

Works fine when:在以下情况下工作正常:

public class EdiconLogFilter
{
    public string fClientName { get; set; }
    public string fUserName { get; set; }
    public string fMinutes { get; set; }
    public string fLogDate { get; set; }
}

If the any of values of the request's JSON object are not the same type as expected by the service then the [FromBody] argument will be null .如果请求的 JSON 对象的任何值与服务预期的类型不同,则[FromBody]参数将为null

For example, if the age property in the json had a float value:例如,如果 json 中的age属性有一个float值:

"age":18.0 “年龄”:18.0

but the API service expects it to be an int但 API 服务期望它是一个int

"age":18 “年龄”:18

then student will be null .那么student将为null (No error messages will be sent in the response unless no null reference check). (除非没有空引用检查,否则不会在响应中发送错误消息)。

This is a little old one and my answer will go down to the last place but even so I would like to share my experience.这是一个有点旧的问题,我的答案将归结到最后一个位置,但即便如此,我还是想分享我的经验。

Tried every suggestion but still having the same "null" value in a PUT [FromBody].尝试了每个建议,但在 PUT [FromBody] 中仍然具有相同的“空”值。

Finally found it was all about Date format while JSON serializing the EndDate property of my Angular Object.最终发现这完全是关于日期格式,而 JSON 序列化了我的 Angular 对象的 EndDate 属性。

No error was thrown, just received an empty FromBody object....没有抛出错误,只是收到一个空的 FromBody 对象....

If using Postman, make sure that:如果使用 Postman,请确保:

  • You have set a "Content-Type" header to "application/json"您已将“Content-Type”标头设置为“application/json”
  • You are sending the body as "raw"您将身体作为“原始”发送
  • You don't need to specify the parameter name anywhere if you are using [FromBody]如果使用 [FromBody],则无需在任何地方指定参数名称

I was stupidly trying to send my JSON as form data, duh...我愚蠢地试图将我的 JSON 作为表单数据发送,呃...

TL;DR: Don't use [FromBody], but roll your own version of it with better error handling. TL;DR:不要使用 [FromBody],而是使用更好的错误处理推出你自己的版本。 Reasons given below.原因如下。

Other answers describe many possible causes of this problem.其他答案描述了此问题的许多可能原因。 However, the root cause is that [FromBody] simply has terrible error handling, which makes it almost useless in production code.然而,根本原因是[FromBody]错误处理很糟糕,这使得它在生产代码中几乎没有用处。

For example, one of the most typical reasons for the parameter to be null is that the request body has invalid syntax (eg, invalid JSON).例如,参数为null的最典型原因之一是请求正文的语法无效(例如,无效的 JSON)。 In this case, a reasonable API would return 400 BAD REQUEST , and a reasonable web framework would do this automatically.在这种情况下,合理的 API 会返回400 BAD REQUEST ,而合理的 Web 框架会自动执行此操作。 However, ASP.NET Web API is not reasonable in this regard.但是,ASP.NET Web API 在这方面并不合理。 It simply sets the parameter to null , and the request handler then needs "manual" code to check if the parameter is null .它只是将参数设置为null ,然后请求处理程序需要“手动”代码来检查参数是否为null

Many of the answers given here are therefore incomplete with regards to error handling, and a buggy or malicious client may cause unexpected behavior on the server side by sending an invalid request, which will (in the best case) throw a NullReferenceException somewhere and return an incorrect status of 500 INTERNAL SERVER ERROR or, worse, do something unexpected or crash or expose a security vulnerability.因此,这里给出的许多答案在错误处理方面是不完整的,并且有缺陷或恶意的客户端可能会通过发送无效请求在服务器端导致意外行为,这将(在最好的情况下)在某处抛出NullReferenceException并返回一个500 INTERNAL SERVER ERROR错误状态,或者更糟糕的是,做一些意外或崩溃或暴露安全漏洞。

A proper solution would be to write a custom " [FromBody] " attribute which does proper error handling and returns proper status codes, ideally with some diagnostic information to aid client developers.一个合适的解决方案是编写一个自定义的“ [FromBody] ”属性,该属性进行正确的错误处理并返回正确的状态代码,最好带有一些诊断信息来帮助客户端开发人员。

A solution that might help (not tested yet) is to make parameters required, as follows: https://stackoverflow.com/a/19322688/2279059一个可能有帮助(尚未测试)的解决方案是使参数成为必需的,如下所示: https : //stackoverflow.com/a/19322688/2279059

The following clumsy solution also works:以下笨拙的解决方案也有效:

// BAD EXAMPLE, but may work reasonably well for "internal" APIs...

public HttpResponseMessage MyAction([FromBody] JObject json)
{
  // Check if JSON from request body has been parsed correctly
  if (json == null) {
    var response = new HttpResponseMessage(HttpStatusCode.BadRequest) {
      ReasonPhrase = "Invalid JSON"
    };
    throw new HttpResponseException(response);
  }

  MyParameterModel param;
  try {
    param = json.ToObject<MyParameterModel>();
  }
  catch (JsonException e) {
    var response = new HttpResponseMessage(HttpStatusCode.BadRequest) {
      ReasonPhrase = String.Format("Invalid parameter: {0}", e.Message)
    };
    throw new HttpResponseException(response);
  }

  // ... Request handling goes here ...

}

This does (hopefully) proper error handling, but is less declarative.这会(希望)正确处理错误,但声明性较低。 If, for example, you use Swagger to document your API, it will not know the parameter type, which means you need to find some manual workaround to document your parameters.例如,如果您使用 Swagger 来记录您的 API,它不会知道参数类型,这意味着您需要找到一些手动解决方法来记录您的参数。 This is just to illustrate what [FromBody] should be doing.这只是为了说明[FromBody][FromBody]

EDIT: A less clumsy solution is to check ModelState : https://stackoverflow.com/a/38515689/2279059编辑:一个不那么笨拙的解决方案是检查ModelStatehttps : //stackoverflow.com/a/38515689/2279059

EDIT: It appears that ModelState.IsValid is not, as one would expect, set to false if using JsonProperty with Required = Required.Always and a parameter is missing.编辑:如果使用JsonPropertyRequired = Required.Always并且缺少参数,则ModelState.IsValid似乎没有像人们预期的那样设置为false So this is also useless.所以这也是没用的。

However, in my opinion, any solution that requires writing additional code in every request handler is unacceptable.但是,在我看来,任何需要在每个请求处理程序中编写额外代码的解决方案都是不可接受的。 In a language like .NET, with powerful serialization capabilities, and in a framework like ASP.NET Web API, request validation should be automatic and built-in, and it is totally doable, even though Microsoft does not provide the necessary built-in tools.在.NET这样的语言中,具有强大的序列化能力,在ASP.NET Web API这样的框架中,请求验证应该是自动的和内置的,这是完全可行的,即使微软没有提供必要的内置工具。

I was also trying to use the [FromBody], however, I was trying to populate a string variable because the input will be changing and I just need to pass it along to a backend service but this was always null我也试图使用 [FromBody],但是,我试图填充一个字符串变量,因为输入会发生变化,我只需要将它传递给后端服务,但这始终为空

Post([FromBody]string Input]) 

So I changed the method signature to use a dynamic class and then convert that to string所以我将方法签名更改为使用动态类,然后将其转换为字符串

Post(dynamic DynamicClass)
{
   string Input = JsonConvert.SerializeObject(DynamicClass);

This works well.这很好用。

It can be helpful to add TRACING to the json serializer so you can see what's up when things go wrong.将 TRACING 添加到 json 序列化程序会很有帮助,这样您就可以在出现问题时查看发生了什么。

Define an ITraceWriter implementation to show their debug output like:定义一个 ITraceWriter 实现以显示其调试输出,例如:

class TraceWriter : Newtonsoft.Json.Serialization.ITraceWriter
{
    public TraceLevel LevelFilter {
        get {
            return TraceLevel.Error;
        }
    }

    public void Trace(TraceLevel level, string message, Exception ex)
    {
        Console.WriteLine("JSON {0} {1}: {2}", level, message, ex);
    }
}

Then in your WebApiConfig do:然后在您的 WebApiConfig 中执行以下操作:

    config.Formatters.JsonFormatter.SerializerSettings.TraceWriter = new TraceWriter();

(maybe wrap it in an #if DEBUG) (也许将它包装在#if DEBUG 中)

After Three days of searching and none of above solutions worked for me , I found another approach to this problem in this Link: HttpRequestMessage经过三天的搜索,上述解决方案均不适用于我,我在此链接中找到了解决此问题的另一种方法: HttpRequestMessage

I used one of the solutions in this site我使用了本网站中的一种解决方案

[HttpPost]
public async System.Threading.Tasks.Task<string> Post(HttpRequestMessage request)
{
    string body = await request.Content.ReadAsStringAsync();
    return body;
}

Just to add my history to this thread.只是为了将我的历史添加到这个线程中。 My model:我的型号:

public class UserProfileResource
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Phone { get; set; }

    public UserProfileResource()
    {
    }
}

The above object couldn't be serialized in my API Controller and would always return null.上面的对象无法在我的 API 控制器中序列化,并且总是返回 null。 The issue was with Id of type Guid : everytime I passed empty string as an Id (being naive that it will automatically be converted to Guid.Empty ) from my frontend I received null object as [FromBody] paramether.问题在于 Guid 类型的 Id :每次我从前端传递空字符串作为 Id(天真,它将自动转换为Guid.Empty )时,我收到空对象作为[FromBody]

Solution was either to解决方案是要么

  • pass valid Guid value传递有效的Guid
  • or change Guid to String或将Guid更改为String

In my case the problem was the DateTime object I was sending.就我而言,问题是我发送的DateTime对象。 I created a DateTime with "yyyy-MM-dd", and the DateTime that was required by the object I was mapping to needed "HH-mm-ss" aswell.我用“yyyy-MM-dd”创建了一个DateTime ,我映射到的对象所需的DateTime也需要“HH-mm-ss”。 So appending "00-00" solved the problem (the full item was null because of this).所以附加“00-00”解决了这个问题(因此整个项目为空)。

This is another issue related to invalid property values in an Angular Typescript request.这是与 Angular Typescript 请求中的无效属性值相关的另一个问题。

This is was related to the conversion between a Typescript number to an int(Int32) in C#.这与 C# 中 Typescript 数字到 int(Int32) 之间的转换有关。 I was using Ticks (UTC milliseconds) which is larger than the signed, Int32 range (int in C#).我使用的是大于有符号的 Int32 范围(C# 中的 int)的 Ticks(UTC 毫秒)。 Changed the C# model from int to long and everything worked fine.将 C# 模型从 int 更改为 long,一切正常。

I had the same problem.我有同样的问题。

In my case, the problem was in public int? CreditLimitBasedOn { get; set; }就我而言,问题出在public int? CreditLimitBasedOn { get; set; } public int? CreditLimitBasedOn { get; set; } public int? CreditLimitBasedOn { get; set; } property I had. public int? CreditLimitBasedOn { get; set; }属性我了。

my JSON had the value "CreditLimitBasedOn":true when It should contain an integer.我的 JSON 的值为"CreditLimitBasedOn":true当它应该包含一个整数时。 This property prevented the whole object being deserialized on my api method.这个属性阻止了整个对象在我的 api 方法上被反序列化。

Maybe for someone it will be helpful: check the access modifiers for your DTO/Model class' properties, they should be public .也许对某人会有所帮助:检查 DTO/Model 类属性的访问修饰符,它们应该是public In my case during refactoring domain object internals were moved to DTO like this:在我的情况下,在重构域对象内部的过程中被移动到 DTO,如下所示:

// Domain object
public class MyDomainObject {
    public string Name { get; internal set; }
    public string Info { get; internal set; }
}
// DTO
public class MyDomainObjectDto {
    public Name { get; internal set; } // <-- The problem is in setter access modifier (and carelessly performed refactoring).
    public string Info { get; internal set; }
}

DTO is being finely passed to client, but when the time comes to pass the object back to the server it had only empty fields (null/default value). DTO 被精细地传递给客户端,但是当需要将对象传递回服务器时,它只有空字段(空/默认值)。 Removing "internal" puts things in order, allowing deserialization mechanizm to write object's properties.删除“内部”使事情井然有序,允许反序列化机制编写对象的属性。

public class MyDomainObjectDto {
    public Name { get; set; }
    public string Info { get; set; }
}

检查是否在作为 null 的字段上设置了JsonProperty属性 - 可能是它们映射到不同的 json 属性名称。

I've hit this problem so many times, but actually, it's quite straightforward to track down the cause.我已经多次遇到这个问题,但实际上,查找原因非常简单。

Here's today's example.这是今天的例子。 I was calling my POST service with an AccountRequest object, but when I put a breakpoint at the start of this function, the parameter value was always null .我正在使用AccountRequest对象调用我的 POST 服务,但是当我在此函数的开头放置断点时,参数值始终为null But why ?!为什么?!

[ProducesResponseType(typeof(DocumentInfo[]), 201)]
[HttpPost]
public async Task<IActionResult> Post([FromBody] AccountRequest accountRequest)
{
    //  At this point...  accountRequest is null... but why ?!

    //  ... other code ... 
}

To identify the problem, change the parameter type to string , add a line to get JSON.Net to deserialize the object into the type you were expecting, and put a breakpoint on this line:要识别问题,请将参数类型更改为string ,添加一行让JSON.Net将对象反序列化为您期望的类型,并在此行上放置一个断点:

[ProducesResponseType(typeof(DocumentInfo[]), 201)]
[HttpPost]
public async Task<IActionResult> Post([FromBody] string ar)
{
    //  Put a breakpoint on the following line... what is the value of "ar" ?
    AccountRequest accountRequest = JsonConvert.DeserializeObject<AccountRequest>(ar);

    //  ... other code ...
}

Now, when you try this, if the parameter is still blank or null , then you simply aren't calling the service properly.现在,当您尝试此操作时,如果参数仍然为空或null ,那么您只是没有正确调用该服务。

However, if the string does contain a value, then the DeserializeObject should point you towards the cause of the problem, and should also fail to convert your string into your desired format.但是,如果字符串确实包含一个值,那么DeserializeObject应该指出问题的原因,并且也应该无法将您的字符串转换为您想要的格式。 But with the raw ( string ) data which it's trying to deserialize, you should now be able to see what's wrong with your parameter value.但是对于它试图反序列化的原始( string )数据,您现在应该能够看到您的参数值有什么问题。

(In my case, we were calling the service with an AccountRequest object which had been accidentally serialized twice !) (在我的例子中,我们使用AccountRequest对象调用服务,该对象被意外序列化了两次!)

I used HttpRequestMessage and my problem got solved after doing so much research我使用了 HttpRequestMessage,经过大量研究,我的问题得到了解决

[HttpPost]
public HttpResponseMessage PostProcedure(HttpRequestMessage req){
...
}

In my case, using postman I was sending a DateTime with invalid separators (%) so the parse failed silently.在我的情况下,使用邮递员我发送了一个带有无效分隔符 (%) 的 DateTime,因此解析失败了。 Be sure you are passing valid params to your class constructor.确保您将有效的参数传递给类构造函数。

None of the above was my solution: in my case the issue is that [ApiController] was not added to the controller so it is giving Null value以上都不是我的解决方案:就我而言,问题是 [ApiController] 未添加到控制器中,因此它给出了 Null 值

[Produces("application/json")]
[Route("api/[controller]")]
[ApiController] // This was my problem, make sure that it is there!
public class OrderController : Controller

... ...

I just ran into this and was frustrating.我刚刚遇到了这个并且很沮丧。 My setup: The header was set to Content-Type: application/JSON and was passing the info from the body with JSON format, and was reading [FromBody] on the controller.我的设置:标头设置为 Content-Type: application/JSON 并以 JSON 格式传递来自正文的信息,并在控制器上读取 [FromBody]。

Everything was set up fine and I expect it to work, but the problem was with the JSON sent over.一切都设置得很好,我希望它能正常工作,但问题在于发送的 JSON。 Since it was a complex structure, one of my classes which was defined 'Abstract' was not getting initialized and hence the values weren't assigned to the model properly.由于它是一个复杂的结构,我的一个定义为“抽象”的类没有被初始化,因此这些值没有正确分配给模型。 I removed the abstract keyword and it just worked..!!!我删除了抽象关键字,它就起作用了..!!!

One tip, the way I could figure this out was to send data in parts to my controller and check when it becomes null... since it was a complex model I was appending one model at a time to my request params.一个提示,我可以解决这个问题的方法是将数据分部分发送到我的控制器并检查它何时变为空......因为它是一个复杂的模型,我一次将一个模型附加到我的请求参数中。 Hope it helps someone who runs into this stupid issue.希望它可以帮助遇到这个愚蠢问题的人。

Seems like there can be many different causes of this problem...似乎这个问题可能有很多不同的原因......

I found that adding an OnDeserialized callback to the model class caused the parameter to always be null .我发现向模型类添加OnDeserialized回调会导致参数始终为null Exact reason unknown.具体原因不明。

using System.Runtime.Serialization;

// Validate request
[OnDeserialized]  // TODO: Causes parameter to be null
public void DoAdditionalValidatation() {...}

If this is because Web API 2 ran into a deserialization problem due to mismatched data types, it's possible to find out where it failed by inspecting the content stream.如果这是因为 Web API 2 由于数据类型不匹配而遇到反序列化问题,则可以通过检查内容流找出它失败的地方。 It will read up until it hits an error, so if you read the content as a string, you should have the back half of the data you posted:它会一直读取直到遇到错误,因此如果您将内容作为字符串读取,您应该拥有您发布的数据的后半部分:

string json = await Request.Content.ReadAsStringAsync();

Fix that parameter, and it should make it further next time (or succeed if you're lucky!)...修复该参数,下次它应该会更进一步(如果幸运的话,它会成功!)...

I had this problem in my .NET Framework Web API, because my model existed in a .NET Standard project that referenced a different version of data annotations.我在我的 .NET Framework Web API 中遇到了这个问题,因为我的模型存在于一个引用不同版本数据注释的 .NET Standard 项目中。

Adding the ReadAsAsync line below highlighted the cause for me:添加下面的 ReadAsAsync 行突出显示了我的原因:

public async Task<HttpResponseMessage> Register(RegistrationDetails registrationDetails)
{
    var regDetails = await Request.Content.ReadAsAsync<RegistrationDetails>();

In my case ( .NET Core 3.0 ) I had to configure JSON serialization to resolve camelCase properties using AddNewtonsoftJson() :就我而言( .NET Core 3.0 ),我必须配置 JSON 序列化以使用AddNewtonsoftJson()解析camelCase 属性:

services.AddMvc(options =>
{
    // (Irrelevant for the answer)
})
.AddNewtonsoftJson(options =>
{
    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});

Do this in your Startup / Dependency Injection setup.在您的启动/依赖注入设置中执行此操作。

I was struggling with this for hours today.我今天为此苦苦挣扎了几个小时。 I could see that there was data in the response body because of the length, but any time I tried to read the data, I got an empty string, or the arguments in the parameter list for the method returned null.由于长度的原因,我可以看到响应正文中有数据,但是每当我尝试读取数据时,我都会得到一个空字符串,或者方法的参数列表中的参数返回空值。 I compared this controller to another that was already working and found that I was missing the ApiController attribute for the class declaration.我将这个控制器与另一个已经在工作的控制器进行了比较,发现我缺少类声明的ApiController属性。 I also removed the FromBody attribute from my parameter declaration.我还从参数声明中删除了FromBody属性。 I am not sure when that was added, but I am using .Net 5.0.我不确定何时添加,但我使用的是 .Net 5.0。

As detailed in my other answer , the problem is with error handling in the [FromBody] attribute, and you cannot do much about that without writing your own version of it.正如其他答案中所详述的,问题在于[FromBody]属性中的错误处理,如果不编写自己的版本,您就无法做太多事情。

However, a general solution that will improve error handling in your entire API without making changes in any controller or action is to write a custom JSON formatter (derived from FotoWareApiJsonFormatter ) which handles serialization errors properly.但是,在不更改任何控制器或操作的情况下改进整个 API 中的错误处理的通用解决方案是编写一个自定义 JSON 格式化程序(派生自FotoWareApiJsonFormatter )来正确处理序列化错误。

I will not present the entire solution here, but the important part is to catch JsonSerializationException and JsonReaderException in the formatter and make sure the endpoint will return 400 Bad Request as a result.我不会在这里展示整个解决方案,但重要的部分是在格式化程序中捕获JsonSerializationExceptionJsonReaderException ,并确保端点将因此返回400 Bad Request

This ensures that if the request contains invalid JSON, or the JSON does not fulfill model constraints (such as missing required properties, type errors, etc.), the API will automatically return 400 Bad Request before your controller action is called, so you do not need to write extra error handling in the controller, and your parameter using [FromBody] will never be null .这确保如果请求包含无效的 JSON,或者 JSON 不满足模型约束(例如缺少必需的属性、类型错误等),API 将在调用控制器操作之前自动返回400 Bad Request ,因此您可以不需要在控制器中编写额外的错误处理,并且使用[FromBody]参数永远不会为null

// in JSON formatter class
private object Deserialize(Stream readStream, Type type)
{
    try
    {
        var streamReader = new StreamReader(readStream);
        return GetSerializer().Deserialize(streamReader, type);
    }
    catch (JsonSerializationException e)
    {
        // throw another exception which results in returning 400 Bad Request
    }
    catch (JsonReaderException e)
    {
        // throw another exception which results in returning 400 Bad Request
    }
}

You also have to ensure that your custom JSON formatter is the only formatter, eg, by adding this code to Application_Start() :您还必须确保您的自定义 JSON 格式化程序是唯一的格式化程序,例如,将此代码添加到Application_Start()

var jsonFormatter = new MyJsonFormatter();

// Always return JSON, and accept JSON only
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(jsonFormatter);

This assumes that your API accepts and returns JSON only, as most modern APIs do.这假设您的 API 仅接受并返回 JSON,就像大多数现代 API 一样。 Offering XML or other formats as an alternative if you are not going to test or advertise it is unnecessary at best and a potential security risk at worst.提供 XML 或其他格式作为替代,如果您不打算测试或做广告,最好的情况是没有必要,最坏的情况是潜在的安全风险。

Be careful when introducing this to an existing API, as it can introduce some unexpected breaking changes, so good testing is advised.在将其引入现有 API 时要小心,因为它可能会引入一些意外的破坏性更改,因此建议进行良好的测试。 Consider it as a cleanup of the error handling in your API.将其视为对 API 中错误处理的清理。

还有一件事要注意……我的模型被标记为 [Serializable],这导致了失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM