改造流末端意外连接

时间:2019-12-04 21:38:25

标签: android .net connection retrofit

我当前正在尝试将android应用程序连接到本地ASP.NET后端。
这样做时,我不断收到错误消息
Retrofit Unexpected end of stream Connection

我真的不知道我错了。我查看了其他解决方案,但似乎没有一个对我有帮助。
我读过一些有关内容长度的问题。在Startup.cs的configure方法中,我注意到以下代码。

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, DataInitializer dataInitializer)
        {
            app.Use(async (ctx, next) =>
            {
                await next();
                if (ctx.Response.StatusCode == 204)
                {
                    ctx.Response.ContentLength = 0;
                }
            });

但是我不知道这是否是造成我问题的原因。

下面,我添加了可能是问题一部分的其余代码。

.Net的Startup.cs

 public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            //AddScopeds for each repository//
            //...//
            services.AddCors(o => o.AddPolicy("AllowAllOrigins", builder =>
            {
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader()
                       .AllowCredentials();
        }));

            services.AddIdentity<IdentityUser, IdentityRole>(cfg => cfg.User.RequireUniqueEmail = true).AddEntityFrameworkStores<ApplicationDbContext>();


            services.AddOpenApiDocument(
   c =>
   {
       c.DocumentName = "apidocs";
       c.Title = "Test API";
       c.Version = "v1";
       c.Description = "The Test API documentation description.";
       c.DocumentProcessors.Add(new SecurityDefinitionAppender("JWT Token", new SwaggerSecurityScheme
       {
           Type = SwaggerSecuritySchemeType.ApiKey,
           Name = "Authorization",
           In = SwaggerSecurityApiKeyLocation.Header,
           Description = "Copy 'Bearer' + valid JWT token into field"
       }));
       c.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT Token"));
   }
);

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme =
                JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    RequireExpirationTime = true //Ensure token hasn't expired
                };
            });

            services.Configure<IdentityOptions>(options =>
            {
                // Password settings.
                options.Password.RequireDigit = true;
                options.Password.RequireLowercase = true;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                options.Password.RequiredLength = 8;
                options.Password.RequiredUniqueChars = 1;

                // Lockout settings.
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                options.Lockout.MaxFailedAccessAttempts = 5;
                options.Lockout.AllowedForNewUsers = true;

                // User settings.
                options.User.AllowedUserNameCharacters =
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
                options.User.RequireUniqueEmail = true;
            });

        }


        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, KlimaatMobielDataInitializer dataInitializer)
        {
            app.Use(async (ctx, next) =>
            {
                await next();
                if (ctx.Response.StatusCode == 204)
                {
                    ctx.Response.ContentLength = 0;
                }
            });
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseCors("AllowAllOrigins"); //
            app.UseStaticFiles();
            app.UseStaticFiles(new StaticFileOptions()
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", @"Resources")),
                RequestPath = new PathString("/Resources")
            });
            app.UseHttpsRedirection();
            app.UseMvc();
            app.UseSwaggerUi3();
            app.UseSwagger();
            app.UseAuthentication();
        }
    }

改造界面

private const val BASE_URL = "http://10.0.2.2:5001/api/"
    private val retrofit = Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .baseUrl(BASE_URL)
        .build()

    interface TestApiService {
        @GET("material")
        fun getMaterials():
                Call<List<Material>>
    }

    object TestApi {
        val retrofitService: KlimaatApiService by lazy {
            retrofit.create(KlimaatApiService::class.java)
        }
    }

使用界面

    public fun getMaterialen() {
        Timber.plant(Timber.DebugTree())
        KlimaatApi.retrofitService.getMaterialen().enqueue(object : Callback<List<Material>> {
            override fun onFailure(call: Call<List<Material>>, t: Throwable) {
                _response.value = "Failure: " + t.message
                Timber.e(t.message)
            }
            override fun onResponse(
                call: Call<List<Material>>,
                response: Response<List<Material>>
            ) {

                if(!response.isSuccessful){

                    Timber.e("Code: ${response.code()}")
                }
                var materials = response.body()
                for(mat in materials!!){
                    Timber.e(mat.name)
                }
            }
        })
    }

0 个答案:

没有答案