programing

웹 API 복합 매개 변수 속성이 모두 null입니다.

sourcejob 2023. 2. 28. 23:26
반응형

웹 API 복합 매개 변수 속성이 모두 null입니다.

사용자의 기본 설정을 업데이트하는 웹 API 서비스 호출이 있습니다.유감스럽게도 이 POST 메서드를 jQuery ajax 호출에서 호출하면 요청 파라미터 객체의 속성은 전달된 것이 아니라 늘(또는 기본값)입니다.REST 클라이언트(Postman을 사용하고 있습니다)를 사용해 같은 방법으로 호출하면, 훌륭하게 동작합니다.내가 뭘 잘못하고 있는지 모르겠지만 누군가 이걸 전에 봤으면 좋겠어.꽤 간단해...

요청 오브젝트는 다음과 같습니다.

public class PreferenceRequest
{
    [Required]
    public int UserId;

    public bool usePopups;
    public bool useTheme;
    public int recentCount;
    public string[] detailsSections;
}

UserController 클래스의 컨트롤러 메서드는 다음과 같습니다.

    public HttpResponseMessage Post([FromBody]PreferenceRequest request)
    {
        if (request.systemsUserId > 0)
        {
            TheRepository.UpdateUserPreferences(request.UserId, request.usePopups, request.useTheme,
                                         request.recentCount, request.detailsSections);

            return Request.CreateResponse(HttpStatusCode.OK, "Preferences Updated");                
        }
        else
        {
            return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, "You must provide User ID");
        }
    }

Ajax 전화입니다.

var request = {
    UserId: userId,
    usePopups: usePopups,
    useTheme: useTheme,
    recentCount: recentCount,
    detailsSections: details
};

$.ajax({
    type: "POST",
    data: request,
    url: "http://localhost:1111/service/User",
    success: function (data) {
        return callback(data);
    },
    error: function (error, statusText) {
        return callback(error);
    }
});

데이터 타입과 콘텐츠를 설정해 보았습니다.여러 가지 다른 항목('json', 'application/json' 등)에 입력하지만 요청 개체의 속성은 항상 기본값 또는 null입니다.예를 들어, 이 오브젝트를 전달했을 경우:

var request = {
  UserId: 58576,
  usePopups: false,
  useTheme: true,
  recentCount: 10,
  detailsSections: ['addresses', 'aliases', 'arrests', 'events', 'classifications', 'custody', 'identifiers', 'phone', 'remarks', 'watches']
}

위와 같이 유효한 값을 가진 완전히 채워진 요청 개체를 볼 수 있습니다.그러나 Web API 컨트롤러에서는 요청이 존재하지만 속성은 다음과 같습니다.

  UserId: 0,
  usePopups: false,
  useTheme: false,
  recentCount: 0,
  detailsSections: null

참고로 ASP는 하지 않습니다.넷 MVC 또는 ASPNET은 웹 API를 서비스로 사용하고 jQuery $.ajax를 사용하여 모든 콜을 발신합니다.

내가 여기서 뭘 잘못하고 있는지 알기나?감사합니다!

업데이트: 이 웹 API 프로젝트에서 동일한 작업을 수행하는 다른 컨트롤러에 여러 가지 메서드가 있으며 동일한 방법으로 호출하면 완벽하게 작동합니다.아침에 여러 콜을 비교했는데 메서드나 헤더에는 차이가 없는 것 같습니다만, 이 특정의 메서드에서는 동작하지 않습니다.

또한 Put 메서드로 전환하려고 시도했지만 동일한 결과가 나타납니다. 요청 개체가 들어왔지만 올바른 값으로 채워지지 않았습니다.정말 짜증나는 것은 이 프로젝트에는 약 20개의 컨트롤러 클래스가 있고, Posts는 그 모든 것에 대응하고 있다는 것입니다.

ASP를 사용하다§ WebAPI
일반적으로 늘 객체의 원인은 Json 객체가 C# 객체로 역직렬화되기 때문입니다.유감스럽게도 디버깅은 매우 어려우며, 따라서 문제의 원인을 찾을 수 없습니다.
풀 json을 오브젝트로 보낸 후 수동으로 역직렬화하는 것이 좋습니다.적어도 이렇게 하면 null 대신 실제 오류가 발생합니다.
오브젝트를 받아들이도록 메서드시그니처를 변경할 경우 JsonConvert를 사용합니다.

public HttpResponseMessage Post(Object model)
        {
            var jsonString = model.ToString();
            PreferenceRequest result = JsonConvert.DeserializeObject<PreferenceRequest>(jsonString);
        }

따라서 값이 바인딩되지 않는 3가지 문제가 있을 수 있습니다.

  1. 공용 매개 변수 없는 생성자 없음
  2. 속성을 공개적으로 설정할 수 없습니다.
  3. 바인딩 오류가 발생하여 ModelState가 생성됩니다.유효한 == false - 일반적인 문제: 호환되지 않는 값 유형(json 개체에서 문자열로, 비호환 등)

그래서 API 호출에 오류가 발생할 경우 오류를 반환하는 필터를 적용해야 하는지 고민하고 있습니다!

아마 도움이 될 거예요, 저도 같은 문제를 겪고 있었어요.

모든 것이 정상적으로 동작하고 있었고, 순식간에 모든 속성이 디폴트로 설정되었습니다.

몇 가지 간단한 테스트 결과, 문제의 원인은 [Serializable](시리얼화 가능)임을 알 수 있었습니다.

public IHttpActionResult Post(MyComplexClass myTaskObject)
{
    //MyTaskObject is not null, but every member are (the constructor get called).
}

그리고 여기 내 수업의 일부분이 있다:

[Serializable]  <-- have to remove that [if it was added for any reason..]
public class MyComplexClass()
{
     public MyComplexClass ()
     {
        ..initiate my variables..
     }

     public string blabla {get;set;}
     public int intTest {get;set;
}

가 [ 것이 를 [FromBody]로 .From Body [From Body] 。

public HttpResponseMessage Post(PreferenceRequest request)

to 및 to and and and

$.ajax({
    type: "POST",
    data: JSON.stringify(request);,
    dataType: 'json',
    contentType: "application/json",
    url: "http://localhost:1111/service/User",

참고로 javascript에서 모델을 작성하는 것은 베스트 프랙티스가 아닐 수 있습니다.

@blorkfish가 게시한 이 기술을 사용하면 효과가 있었습니다.

public HttpResponseMessage Post(Object model)
    {
        var jsonString = model.ToString();
        PreferenceRequest result = JsonConvert.DeserializeObject<PreferenceRequest>(jsonString);
    }

파라미터 오브젝트에는 네이티브타입이 몇 개 있고 속성으로 오브젝트가 몇 개 더 있습니다.오브젝트에는 internal 및 JsonConvert 마크가 붙은 컨스트럭터가 있습니다.jsonString의 DiserializedObject 호출에서 다음 오류가 발생하였습니다.

ChildObjectB 형식에 사용할 생성자를 찾을 수 없습니다.클래스에는 기본 생성자, 인수가 있는 생성자 또는 JsonConstructor 속성이 표시된 생성자가 있어야 합니다.

생성자를 public으로 변경했는데 Object 모델 매개 변수를 실제 개체로 바꾸면 매개 변수 개체가 채워집니다.감사합니다!

알아요, 좀 늦은 감이 있지만, 같은 문제에 부딪혔어요.@blorkfish의 답변은 저에게도 효과가 있었지만, 다른 해결책으로 이끌었습니다.복잡한 오브젝트 중 하나에 파라미터가 없는 생성자가 없었습니다.이 생성자를 추가한 후 Put 요청과 Post 요청이 모두 예상대로 작동하기 시작했습니다.

저도 이 문제에 직면해 있습니다.디버깅과 조사로부터 몇 시간 후, 이 문제는 Content-Type 또는 Type $Ajax 속성으로 인해 발생한 것이 아닙니다.이 문제는 JSON 오브젝트의 NULL 값으로 인해 발생한 것입니다.POST가 NULL 값을 수정한 후에는 POST가 정상이고 기본적으로 respucomParacion으로 전송되기 때문입니다.class 여기 코드:

JSON

 respuestaComparacion: {
                            anioRegistro: NULL, --> cannot cast to BOOL
                            claveElector: NULL, --> cannot cast to BOOL
                            apellidoPaterno: true,
                            numeroEmisionCredencial: false,
                            nombre: true,
                            curp: NULL, --> cannot cast to BOOL
                            apellidoMaterno: true,
                            ocr: true
                        }

컨트롤러

[Route("Similitud")]
[HttpPost]
[AllowAnonymous]

public IHttpActionResult SimilitudResult([FromBody] RespuestaComparacion req)
{
   var nombre = req.nombre;
}

학급

public class RespuestaComparacion
    {
        public bool anioRegistro { get; set; }
        public bool claveElector { get; set; }
        public bool apellidoPaterno { get; set; }
        public bool numeroEmisionCredencial { get; set; }
        public bool nombre { get; set; }
        public bool curp { get; set; }
        public bool apellidoMaterno { get; set; }
        public bool ocr { get; set; }
    }

이게 도움이 됐으면 좋겠다.

저도 같은 문제에 부딪혔어요.필요한 수정은 파라미터 클래스에 대한 JSON의 모든 serialize 가능한 속성이 get;set; 메서드가 명시적으로 정의되어 있는지 확인하는 것입니다.C# 자동 속성 구문에 의존하지 마십시오!asp.net의 새로운 버전에서 이 문제가 해결되었으면 합니다.

파티에는 조금 늦었지만, 같은 문제가 있어서 수정이 내용을 공표하는 것이었습니다.Ajax 호출을 입력합니다.

    var settings = {
        HelpText: $('#help-text').val(),
        BranchId: $("#branch-select").val(),
        Department: $('input[name=departmentRadios]:checked').val()

    };

$.ajax({
        url: 'http://localhost:25131/api/test/updatesettings',
        type: 'POST',
        data: JSON.stringify(settings),
        contentType: "application/json;charset=utf-8",
        success: function (data) {
            alert('Success');
        },
        error: function (x, y, z) {
            alert(x + '\n' + y + '\n' + z);
        }
    });

API 컨트롤러는 다음과 같이 설정할 수 있습니다.

    [System.Web.Http.HttpPost]
    public IHttpActionResult UpdateSettings([FromBody()] UserSettings settings)
    {
//do stuff with your UserSettings object now
        return Ok("Successfully updated settings");
    }

내 경우, 내가 추가했을 때 문제가 해결되었다.

get {} set {}

파라미터 클래스 정의:

public class PreferenceRequest
{
    public int UserId;
    public bool usePopups {get; set;}
    public bool useTheme {get; set;}
    public int recentCount {get; set;}
    public string[] detailsSections {get;set;}
}

대신:

   public class PreferenceRequest
    {
        [Required]
        public int UserId;
        public bool usePopups;
        public bool useTheme;
        public int recentCount;
        public string[] detailsSections;
    }

어제 하루 종일 이 문제로 고민했기 때문에, 같은 상황에서 다른 사람에게 도움이 될 만한 것을 추가하고 싶습니다.

저는 Xamarin Studio를 사용하여 각도 및 웹 API 프로젝트를 만들었습니다.디버깅 중에 오브젝트가 null이 될 수도 있고 채워진 오브젝트가 될 수도 있습니다.Visual Studio에서 프로젝트를 디버깅하기 시작했을 때에만 모든 게시 요청에서 개체가 채워졌습니다.이것은 Xamarin Studio에서 디버깅할 때 문제가 있는 것 같습니다.

다른 IDE에서 이 null 매개 변수 문제가 발생하는 경우 Visual Studio에서 디버깅을 시도하십시오.

오늘도 당신과 같은 문제가 있어요.보낼 때POST로부터의 요구.ajax컨트롤러가 빈 개체를 수신합니다.Null및 기본 속성 값.방법은 다음과 같습니다.

[HttpPost]
public async Task<IActionResult> SaveDrawing([FromBody]DrawingModel drawing)
{


    try
    {

        await Task.Factory.StartNew(() =>
        {
            //Logic
        });
        return Ok();
    }
    catch(Exception e)
    {
        return BadRequest();
    }
}

나의Content-Type다 맞았고 다른 것도 다 맞았습니다.여러 가지를 시도해 본 결과, 다음과 같이 오브젝트를 송신할 수 있었습니다.

$.ajax({
    url: '/DrawingBoard/SaveDrawing',
    type: 'POST',
    contentType: 'application/json',
    data: dataToPost
}).done((response) => { }); 

동작하지 않지만, 다음과 같이 송신하면 동작합니다.

$.ajax({
    url: '/DrawingBoard/SaveDrawing',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify(dataToPost)
}).done((response) => { }); 

네, 실종자요JSON.stringify()모든 문제를 일으켰고, 더 이상 언급할 필요가 없습니다.=또는 접두사 또는 접미사로 다른 어떤 것도JSON.stringify. 조금 파헤치고 나서.요청 페이로드의 형식이 두 요청 간에 완전히 다르다는 것을 발견했습니다.
paylayload가 paylayload인 입니다.JSON.stringify

JSON.stringify를 사용하여 페이로드 요청

은 요청 이며, 요청 payload는 .JSON.stringify

JSON.stringify를 사용하지 않고 payload를 요청합니다.

될★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★Google Chrome웹 응용 프로그램을 테스트합니다.빈 캐시와 하드 새로고침을 때때로 수행합니다.

같은 문제에 부딪혔는데, 해결책은 클래스 속성의 유형이 json 속성과 일치하는지 확인하는 것이었습니다.

Json: "attribute": "true"

부울이 아닌 문자열로 취급해야 합니다.이러한 문제가 있는 경우, 장애가 있는 Atribute 아래에 있는 모든 Atribute는 디폴트로 null이 됩니다.

오늘도 같은 문제에 부딪혔습니다.Azure에서 API를 디버깅하고 Xamarin Android 앱을 디버깅한 결과, 레퍼런스 업데이트의 문제임이 판명되었습니다.API에 Newtonsoft가 포함되어 있는지 확인하십시오.JSON NUGET 패키지가 갱신되었습니다(그것을 사용하고 있는 경우).

이 문제는 다른 답변으로는 해결되지 않았기 때문에 이 해결방법은 검토할 가치가 있습니다.

다음과 같은 DTO 및 컨트롤러 방식을 사용했습니다.

public class ProjectDetailedOverviewDto
{
    public int PropertyPlanId { get; set; }

    public int ProjectId { get; set; }

    public string DetailedOverview { get; set; }
}

public JsonNetResult SaveDetailedOverview(ProjectDetailedOverviewDto detailedOverview) { ... }

DTO에 파라미터와 이름이 같은 속성(detailedOverview)이 있었기 때문에 deserialiser는 혼란스러워서 복합 객체 전체가 아닌 문자열로 파라미터를 채우려고 했습니다. 메서드 을 "Controller "로 이었습니다.'overview'탈영병은 내가 사유지에 접근하려는 게 아니라는 걸 알았을 거야

나는 이 문제에 직면했다. 이 문제를 해결하라.

  1. nuget 패키지 newton에서 모델에서 속성 [JsonProperty("json request에 있는 속성 이름")]을 사용합니다.
  2. 오브젝트를 시리얼화한 경우 PostAsync만 호출합니다.

이런 거죠.

var json = JsonConvert.SerializeObject(yourobject);
var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
var response = await client.PostAsync ("apiURL", stringContent);
  1. 동작하지 않으면 API에서 [본문]을(를) 삭제합니다.

HttpGet

public object Get([FromBody]object requestModel)
{
    var jsonstring = JsonConvert.SerializeObject(requestModel);
    RequestModel model = JsonConvert.DeserializeObject<RequestModel>(jsonstring);
}
  public class CompanyRequestFilterData
    {
             public string companyName { get; set; }
             public string addressPostTown { get; set; }
             public string businessType { get; set; }
             public string addressPostCode{ get; set; }
             public bool companyNameEndWith{ get; set; }
             public bool companyNameStartWith{ get; set; }
             public string companyNumber{ get; set; }
             public string companyStatus{ get; set; }
             public string companyType{ get; set; }
             public string countryOfOrigin{ get; set; }
             public DateTime? endDate{ get; set; }
             public DateTime? startDate { get; set; }
}

webapi 컨트롤러

    [HttpGet("[action]"),HttpPost("[action]")]
    public async Task<IEnumerable<CompanyStatusVm>> GetCompanyRequestedData(CompanyRequestFilterData filter)
    {}

jsvascript/타이프스크립트

export async function GetCompanyRequesteddata(config, payload, callback, errorcallback) {
await axios({
    method: 'post',
    url: hostV1 + 'companydata/GetCompanyRequestedData',
    data: JSON.stringify(payload),
    headers: {
        'secret-key': 'mysecretkey',
        'Content-Type': 'application/json'
    }
})
    .then(res => {
        if (callback !== null) {
            callback(res)
        }
    }).catch(err => {
        if (errorcallback !== null) {
            errorcallback(err);
        }
    })

}

이것이 동작하고 있는 c# core 3.1 입니다.

제 경우는 bool 데이터 타입이었는데, 문자열을 bool [companyNameEndWith]와 [companyNameStartWith]로 변경했습니다만, 데이터 타입을 확인해 주세요.

언급URL : https://stackoverflow.com/questions/24129919/web-api-complex-parameter-properties-are-all-null

반응형