Saltar al contenido

“El valor JSON no se pudo convertir a System.String” al intentar llamar al punto final del controlador

Te damos la bienvenida a nuestra web, en este lugar vas a encontrar la respuesta a lo que buscabas.

Solución:

El enlazador de modelos no puede asignar/vincular los datos enviados a los parámetros del controlador

Tu acción espera un simple string del cuerpo de la solicitud

public async Task AddQuestion([FromBody] string question)

Pero enviaste un objeto complejo

 "test" : "test" 

Es posible que haya obtenido una coincidencia si los nombres de las propiedades hubieran coincidido

Por ejemplo

 "question" : "test" 

Dado que el enlazador de modelos tendrá en cuenta los nombres de las propiedades al hacer coincidir los parámetros.

si quieres recibir un raw string entonces necesitas enviar un JSON crudo válido string

" "test": "test ""

Eso está bien escapado.

Otra opción es usar un objeto complejo para el parámetro.

class Question  
    public string test  get; set; 
    //...other properties

que coincide con los datos esperados

public async Task AddQuestion([FromBody] Question question) 
    string value = question.test;

    //...

El enlazador de modelos vinculará los datos y los pasará a los parámetros de acción.

Enlace de modelo de referencia en ASP.NET Core

Gracias @Nkosi por identificar el problema y proporcionar el artículo Enlace de modelos en ASP.NET Core.

Como pasé mucho tiempo revisando ejemplos obsoletos sobre cómo llamar a una API, aquí está mi código de referencia (a partir de septiembre de 2020):

En el proyecto API, utilicé el [BindProperty] attribute en las propiedades de la clase modelo.

    // ASP.NET CORE API - C# model

    using Microsoft.AspNetCore.Mvc;
    using System;
    
    namespace MyTestAPI.Models
    
        public partial class MyTest
        
            [BindProperty]
            public int TestId  get; set; 
            [BindProperty]
            public string Message  get; set; 
            [BindProperty]
            public Guid? CreatedBy  get; set; 
            [BindProperty]
            public DateTime Timestamp  get; set; 
        
    

En el controlador API, el mi prueba la clase se deserializa automáticamente debido a la propiedad attributes de El Mi prueba clase de modelo:

// ASP.NET CORE API - C# controller

using Dapper;
using HangVue.API.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MyTestAPI.Models;

namespace HangVue.API.Controllers

    [Route("api/[controller]")]
    [ApiController]
    public class TestController : ControllerBase
         

       [HttpPost]
       public void Post([FromBody] MyTest mytest)
       

           var parameters = new DynamicParameters();
           parameters.Add("@pMessage", mytest.Message, System.Data.DbType.String, System.Data.ParameterDirection.Input);
           parameters.Add("@CreatedBy", mytest.CreatedBy.ToString(), System.Data.DbType.String, System.Data.ParameterDirection.Input);

           string sql = "[dbo].[uspTest]";

           using (var conn = new System.Data.SqlClient.SqlConnection(*** SQL_conn_string_goes_here ***))
           
             var affectedRows = conn.Query(sql, parameters, commandType: System.Data.CommandType.StoredProcedure);
           
       
      

Del lado del cliente, uso Xamarin.Forms con RestSharp para invocar mi API. Él token de acceso es obligatorio porque uso la autenticación de Azure AD B2C.

// Xamarin.Forms - C# Client (iOS + Android)

using Microsoft.Identity.Client;
using RestSharp;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace YourApp.Services

    public static class TestServices
       

       public async static Task NewTest(int iTestId, string sMessage, Guid? gCreatedBy, DateTime dTimestamp)
       
          try
          
             var mytest = new Models.MyTest 
             
                TestId = iTestId,
                Message = sMessage,
                CreatedBy = gCreatedBy,
                Timestamp = dTimestamp
             ;

             // Client --- API end-point example:  https://yourAPIname.azurewebsites.net/
             RestSharp.RestClient client = new RestClient(*** https://Your_API_base_end_point_goes_here ***);
            
             // Request 
             RestSharp.RestRequest request = new RestSharp.RestRequest("api/test", RestSharp.Method.POST, RestSharp.DataFormat.Json);
             request.AddParameter("Authorization", "Bearer " + *** Your_AccessToken_goes_here ***, RestSharp.ParameterType.HttpHeader);
             request.AddHeader("Content-Type","application/json; CHARSET=UTF-8");
             request.AddHeader("Accept", "application/json");
             request.AddJsonBody(mytest);

             // Invoke
             RestSharp.IRestResponse response = await client.ExecuteAsync(request);

             if (response.StatusCode == System.Net.HttpStatusCode.OK)
             
                *** do something ***    
                return *** a string *** ;
             
             else
             
                *** do something ***
                return *** a string *** ;
             
          
          catch (Exception ex)
          
             *** do something ***
          
       
    

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *