0

I have created a sample app in Django which deletes a question from App. And provides a correct output when consumed using POSTMAN.

class Questions(APIView):
  def delete(self,request):
        received_id = request.POST["id"]
        print(received_id)
        place = Question.objects.get(pk=received_id)
        place.delete()
        questions = Question.objects.all()
        seriliazer = QuestionSerializer(questions,many = True)
        return Response({'Orgs': seriliazer.data})

However, when I am trying to achieve it from iOS app, it's returning {"detail":"Unsupported media type "text/plain" in request."}

func deleteQuestion( id: Int){
    guard let url  = URL(string: "http://127.0.0.1:8000/V1/API/questions/") else {
        return
    }
    var request = URLRequest(url: url)
    let postString = "id=15"
    request.httpBody = postString.data(using: String.Encoding.utf8);
    request.httpMethod = "DELETE"
    URLSession.shared.dataTask(with: request) { data, response, error in
        let str = String(decoding: data!, as: UTF8.self)
        print(str)
        if error == nil {
            self.fetcOrganizatinData()
        }
    }.resume()
}

Could not really understand where exactly the problem is ?

Dipesh Pokhrel
  • 386
  • 5
  • 20

3 Answers3

0

If the api is expecting Json, the body you are sending is not Json, it’s encoded plain text. If it should be Json you can change the body string into the Json format like:

“{\”id\”:15}”
// you may want to tell it what you’re sending
request.setValue("application/json", forHTTPHeaderField: "Accept-Encoding")

Another thing it could be is the request is missing the Accept-Encoding header which tells the api what you’re sending up where Content-Type is what the api typically sends down.

I’ve experienced header injection when I’ve sent requests through specific gateways that aren’t always right. I’d the header isn’t present, something along the way could try to help you out and add the header. This has caused me problems on the past. I still don’t know exactly where in our stack it was occurring, but adding the header fixed my problem.

You can add the header like:

request.setValue("charset=utf-8", forHTTPHeaderField: "Accept-Encoding")
Jake
  • 2,126
  • 1
  • 10
  • 23
  • i assumed you are taking about request.setValue("charset=utf-8", forHTTPHeaderField: "Accept-Encoding") ,which did not yield result – Dipesh Pokhrel Jul 30 '21 at 10:32
  • i understood the problem is in the code received_id = self.request.GET["id"],, Now I want to know how to parse body on DELETE method @Jake – Dipesh Pokhrel Jul 30 '21 at 11:03
  • Try this answer. https://stackoverflow.com/a/29781023/9333764 I'm not familiar with DJango, I am familiar with swift – Jake Jul 30 '21 at 11:11
  • you would probably ignore the body["content"] part of that answer – Jake Jul 30 '21 at 11:12
0

DELETE request's body will be ignored, I could guess from the Is an entity body allowed for an HTTP DELETE request? post. HENCE Better to send the complete URL or in header itself,

so I made the function as below

def delete(self,request):
        received_id = request.headers['id']
        place = Question.objects.get(pk=received_id)
        place.delete()
        return HttpResponse("DELETE view is working fine ")

and swift

 func deleteQuestion( id: Int){
        guard let url  = URL(string: "http://127.0.0.1:8000/V1/API/questions/") else {
            return
        }
        var request = URLRequest(url: url)
        //let postString = "id=\(id)"
       // request.httpBody =  postString.data(using: String.Encoding.utf8);
        request.httpMethod = "DELETE"
        request.setValue("charset=utf-8", forHTTPHeaderField: "Accept-Encoding")
        request.setValue("charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.setValue("\(id)", forHTTPHeaderField: "id")
        URLSession.shared.dataTask(with: request) { data, response, error in
            let str = String(decoding: data!, as: UTF8.self)
            print(str)
            if error == nil {
                self.fetcOrganizatinData()
            }
        }.resume()
    }
Dipesh Pokhrel
  • 386
  • 5
  • 20
0

Shortly add Content-Type application/json in your headers Reason this happens because the postman has some default headers usually 8. One of them is Content-Type text/plain and by writing "Content-Type": "application/json" we can overwrite that rule. So whenever you want to pass your data like JSON do that. to learn more what is by default in postman I recommend you to read this official documentation of postman. It happens with me I solved this with overwriting default Content-Type