You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Retrofit2调用ASP.NET REST服务报错:Expected BEGIN_ARRAY but was BEGIN_OBJECT求助

Troubleshooting "Expected BEGIN_ARRAY but was BEGIN_OBJECT" with Retrofit2 & ASP.NET REST Service

Hey there! Let's break down this super common Retrofit parsing error you're facing. The error message Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ is telling you exactly what's wrong: your Android app is expecting a JSON array (like [{}, {}, ...]) from your ASP.NET service, but it's actually receiving a single JSON object (like {}) instead. Let's walk through step-by-step how to diagnose and fix this.

1. First: Verify Your ASP.NET Service's Response Format

This is the most critical first step—let's confirm what your service is actually sending back.

  • Open your browser or a tool like Postman, and hit the exact endpoint your Retrofit client is calling (e.g., http://your-local-iis-ip/api/catalogo). Look at the response:
    • If you see something like {"Id": 1, "Nombre": "Ejemplo"}, that's a single JSON object.
    • If you see [{"Id":1, ...}, {"Id":2, ...}], that's a JSON array.
  • Check your ASP.NET controller action. If you meant to return a list of Catalogo objects but are returning a single one, that's the issue! For example:
    ❌ Wrong (returns single object):
    [HttpGet]
    public IActionResult GetCatalogos()
    {
        var catalogo = new Catalogo { Id = 1, Nombre = "Test" };
        return Ok(catalogo); // Sends a single object
    }
    
    ✅ Correct (returns array/list):
    [HttpGet]
    public IActionResult GetCatalogos()
    {
        var catalogos = new List<Catalogo>
        {
            new Catalogo { Id = 1, Nombre = "Test 1" },
            new Catalogo { Id = 2, Nombre = "Test 2" }
        };
        return Ok(catalogos); // Sends an array
    }
    

2. Match Your Retrofit Interface to the Service Response

Now make sure your Android Retrofit interface is expecting the right type:

  • If your service returns a single Catalogo object, your interface should look like this:
    public interface CatalogoService {
        @GET("api/catalogo")
        Call<Catalogo> getSingleCatalogo(); // Expects a single object
    }
    
  • If your service returns an array/list of Catalogo objects, use this instead:
    public interface CatalogoService {
        @GET("api/catalogo")
        Call<List<Catalogo>> getCatalogoList(); // Expects an array
    }
    

Mismatching these (e.g., expecting a list but getting a single object) is the #1 cause of this error.

3. Validate Your Model Class Mappings

Even if the array/object mismatch is fixed, you might run into issues if your Catalogo classes don't align between ASP.NET and Android.

  • Case sensitivity: ASP.NET uses PascalCase by default (e.g., Id, Nombre), while Java uses camelCase (e.g., id, nombre). Gson (Retrofit's default converter) doesn't auto-map these unless you tell it to.
    • Fix on Android: Use @SerializedName annotations to match the JSON keys:
      public class Catalogo {
          @SerializedName("Id")
          private int id;
          
          @SerializedName("Nombre")
          private String nombre;
      
          // Getters and setters
      }
      
    • Fix on ASP.NET: Configure JSON to return camelCase instead (in Startup.cs):
      services.AddControllers()
          .AddJsonOptions(options =>
          {
              options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
          });
      
  • Double-check that all fields in your Android Catalogo class exist in the JSON response (and vice versa)—missing or extra fields can cause parsing issues too.

4. Debug with Retrofit Logging

To confirm exactly what JSON your Android app is receiving, add OkHttp's logging interceptor to your Retrofit setup. This will print the full response body to Logcat:

// Add this dependency to your build.gradle if you don't have it:
// implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'

OkHttpClient okHttpClient = new OkHttpClient.Builder()
    .addInterceptor(new HttpLoggingInterceptor()
        .setLevel(HttpLoggingInterceptor.Level.BODY)) // Logs full request/response
    .build();

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("http://your-local-iis-ip/") // Use 10.0.2.2 for Android emulator instead of localhost
    .client(okHttpClient)
    .addConverterFactory(GsonConverterFactory.create())
    .build();

Now check Logcat—you'll see the exact JSON response, which makes it easy to confirm if it's an array or object.

5. Local IIS Gotchas

Don't forget these quick checks for your local IIS setup:

  • Emulator access: If you're using an Android emulator, you can't use localhost to reach your IIS service. Use 10.0.2.2 instead (this maps to your host machine's localhost).
  • CORS configuration: Make sure your ASP.NET service allows requests from your Android app. Add CORS policy in Startup.cs:
    services.AddCors(options =>
    {
        options.AddPolicy("AllowAndroid",
            policy => policy.AllowAnyOrigin() // Restrict to your app's origin in production
                            .AllowAnyHeader()
                            .AllowAnyMethod());
    });
    
    // Then in Configure() method:
    app.UseCors("AllowAndroid");
    

Once you align the service's response format with what Retrofit is expecting, and fix any model mapping issues, this error should disappear.

内容的提问来源于stack exchange,提问作者Andrea Benalcazar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:06:45