How to make http get request from flutter app to the localhost?

Viewed 1725

Basically I am making a request GET from a flutter app to my localhost, I have my own Web API in visual studio, and whenever I make the request it gives me Bas Request[400]. So when I make this request it gives my bad request and that's also the case if I make the request using my IP address because I am using an actual android phone to run flutter and I can't request using 'localhost' So I wrote the IP Address of my machine. and even in postman the same.

my fluuter app:

import 'dart:io';
import 'package:dio/adapter.dart';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';


class Project {
  final String Id;
  final String Name;
  final double Amount;


  Project({this.Id, this.Name, this.Amount});

  factory Project.fromJson(Map<String, dynamic> json) {
    return Project(
      Id: json['Id'],
      Name: json['Name'],
      Amount: json['Amount'],
    );
  }
}


void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  List<Project> projects = new List<Project>();
  String url = "https://192.168.100.5:44391";

  void fetsh() async
  {
    Dio dio = new Dio();
    (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
        (HttpClient client) {
      client.badCertificateCallback =
          (X509Certificate cert, String host, int port) => true;
      return client;
    };
    try
    {
      var respond = await dio.get("$url/api/Project");
      print(respond.statusCode);
      print(respond.data);
      var respondData = respond.data as List;
      setState(() {
        projects = respondData.map((e) => Project.fromJson(e)).toList();
      });

    }
    catch(e) {
      print("error");
      print(e);
    }

  }



  @override
  void initState() {
    super.initState();
    fetsh();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Fetch Data Example'),
        ),
        body: ListView.builder(
            itemCount: this.projects.length,
            itemBuilder: (BuildContext context, int index) {
              return new Text(this.projects[index].Name);
            }
        )
      ),
    );
  }
}

and the server-side:

using demo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace demo.Controllers
{
    public class ProjectController : ApiController
    {
        List<Project> mylist = new List<Project>();
        public ProjectController()
        {
            mylist.Add(new Project { Id = 1, Name = "Project 1", Amount = 150 });
            mylist.Add(new Project { Id = 2, Name = "Project 2", Amount = 150 });
            mylist.Add(new Project { Id = 3, Name = "Project 3", Amount = 150 });

        }
        // GET: api/Project
        public List<Project> Get()
        {
            return mylist;
        }

        [Route("api/Project/GetProjectNames")]
        [HttpGet]
        public List<string> GetProjectNames() 
        {
            List<string> output = new List<string>();
            foreach (var item in mylist)
            {
                output.Add(item.Name);
            }
            return output;
        }

        // GET: api/Project/5
        public Project Get(int id)
        {
            return mylist.Where(x=>x.Id == id).FirstOrDefault();
        }

        // POST: api/Project
        public void Post([FromBody]string value)
        {
        }

        // PUT: api/Project/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE: api/Project/5
        public void Delete(int id)
        {
        }
    }
}
2 Answers

You could use a tunnel such as ngrok in order to expose your localhost API over the internet which would allow it to be accessible from the app running on your phone or emulator. One of the advantages of using a tunnel is that it is relatively easy to get up and running however one of the disadvantages is that your localhost API would be exposed over the internet.

Not exactly clear if you're trying to access your backend in local network for testing or over the internet. For local network just use IP of your machine running your backend. For internet you need to use your internet IP or use something like duckdns.org to give you a domain that you can use with dynamic IP. For internet access don't forget to forward your backend port on your router to the IP where backend code is running.

Related