1

I want to send an object with subobjects as Json to my Net Core API using c#. This works if the sub-objects are filled. But as soon as the sub-object is null, it doesn't arrive at the controller. I received an error with status code 400.

    StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:{  Date: Thu, 10 Mar 2022 09:40:25 GMT Server: Kestrel Content Length: 296 Content-Type: application/problem+json; charset=utf-8 }}

I've been googling and trying a lot for the past 2 days. but unfortunately nothing works.

This is my model

   public class Location
   {
        [Key]
        public string Zipcode{ get; set; }
        public string LocationName { get; set; }
        public DateTime CreationDate{ get; set; }

        [ForeignKey("Street")]
        public string StreetID{ get; set; }
        public virtual Street Street{ get; set; }
    }

    public class Street
    {
        [Key]
        public string StreetName { get; set; }
    }

This is my Reqeust

            HttpClient httpClient = new HttpClient();
            string requestUri = "https://localhost:5001/Customers/CreateLocation";
            
            var json = JsonConvert.SerializeObject(location);
            var buffer = System.Text.Encoding.UTF8.GetBytes(json);
            var byteContent = new ByteArrayContent(buffer);
            byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var response = await httpClient.PostAsync(requestUri, byteContent);
            string result = response.Content.ReadAsStringAsync().Result;

This is my Controller

        [HttpPost]
        [Route("CreateLocation")]
        public IActionResult CreateOrt(Location location)
        {
            location = KundenRepositorie.CreateLocation(Bankdaten_DB, location);
            return CreatedAtAction("GetCustomerByID", new { id = location.Zipcode}, location);
        }

I have already added the following to Programm.cs

builder.Services.AddControllers().AddNewtonsoftJson();
builder.Services.AddControllers().AddJsonOptions(options =>
{
   options.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;
});

This Json Works fine and arrives at the controller

{"Zipcode":"89898",
 "LocationName ":"MyCity",
 "CreationDate":"2022-03-10T11:01:25.9840573+01:00",
 "StreedID":"Am Dorf",
 "Street":
          {"StreetName ":"Am Dorf",
            "Kunden":null}
}

But here I get the error message and it doesn't arrive

{"Zipcode":"89898",
    "LocationName":"MyCity",
    "CreationDate":"2022-03-10T11:12:39.8402702+01:00",
    "StreedID":null,
    "Street":null}

I am very grateful for any help tip. Maybe I'm doing something fundamentally wrong. I'm here learning for myself and experimenting with the API and the database model to gain experience.

1 Answer 1

2

since you are using net 6 , you have to make everything nullable, this is why you have the error you can try this

public class Location
   {
        .....
        public string? StreetID{ get; set; }
        public virtual Street? Street{ get; set; }
    }

but I recommend you to fix everything, by removing nullable from your project properties, otherwise it will be repeating and repeating

<PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <!--<Nullable>enable</Nullable>-->
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

then fix the program, you added controllers twice, it should be once

builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
  options.SerializerSettings.ContractResolver =
        new CamelCasePropertyNamesContractResolver());

then fix your http request , you don't need any byte array, since you are sending json

    string requestUri = "https://localhost:5001/Customers/CreateLocation";
using HttpClient client = new HttpClient();

client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

 var json = JsonConvert.SerializeObject(location);
var content = new StringContent(json, UTF8Encoding.UTF8, "application/json");    
  
var response = await client.PostAsync(requestUri, content);     

if (response.IsSuccessStatusCode)
    {
        var stringData = await response.Content.ReadAsStringAsync();
        var result = JsonConvert.DeserializeObject<object>(stringData);
    }   

and fix the post action

         [HttpPost]
        [Route("CreateLocation")]
        public IActionResult CreateOrt([FromBody] Location location)
Sign up to request clarification or add additional context in comments.

8 Comments

Hello, Thanks for the quick reply and for pointing out the duplicate add. I've tried different types of http requests. Unfortunately it still doesn't work. I get the same error message again :(
@Tinkerer did you fix the class by making properties nullable?
@Tinkerer You need to add [FromBody] attribute as I mentioned in my answer.
@RahulSharma It is working wihout it . Just some properties are not showing. "This Json Works fine and arrives at the controller"
@Serge Then how come the error is StatusCode: 400, ReasonPhrase: 'Bad Request'? If it was being received and then some error would have occurred in the Controller method, the error would be a 500 Internal Server Error
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.