使用Retrofit2调用ASP.NET REST服务报错:Expected BEGIN_ARRAY but was BEGIN_OBJECT求助
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.
- If you see something like
- Check your ASP.NET controller action. If you meant to return a list of
Catalogoobjects but are returning a single one, that's the issue! For example:
❌ Wrong (returns single object):
✅ Correct (returns array/list):[HttpGet] public IActionResult GetCatalogos() { var catalogo = new Catalogo { Id = 1, Nombre = "Test" }; return Ok(catalogo); // Sends a single object }[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
Catalogoobject, 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
Catalogoobjects, 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
@SerializedNameannotations 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; });
- Fix on Android: Use
- Double-check that all fields in your Android
Catalogoclass 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
localhostto reach your IIS service. Use10.0.2.2instead (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

