Fix body parsing
diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py
index a1cc0b9808d4c..33130a90ef339 100644
--- a/fastapi/dependencies/utils.py
+++ b/fastapi/dependencies/utils.py
@@ -634,7 +634,11 @@ async def request_body_to_args(
                 ) and isinstance(received_body, FormData):
                     value = received_body.getlist(field.alias)
                 else:
-                    value = received_body.get(field.alias)
+                    try:
+                        value = received_body.get(field.alias)
+                    except AttributeError:
+                        errors.append(get_missing_field_error(field.alias))
+                        continue
             if (
                 value is None
                 or (isinstance(field_info, params.Form) and value == "")
@@ -645,18 +649,7 @@ async def request_body_to_args(
                 )
             ):
                 if field.required:
-                    if PYDANTIC_1:
-                        errors.append(
-                            ErrorWrapper(MissingError(), loc=("body", field.alias))
-                        )
-                    else:  # pragma: nocover
-                        errors.append(
-                            ErrorWrapper(  # type: ignore
-                                MissingError(),
-                                loc=("body", field.alias),
-                                config=BaseConfig,
-                            )
-                        )
+                    errors.append(get_missing_field_error(field.alias))
                 else:
                     values[field.name] = deepcopy(field.default)
                 continue
@@ -685,6 +678,16 @@ async def request_body_to_args(
     return values, errors
 
 
+def get_missing_field_error(field_alias: str) -> ErrorWrapper:
+    if PYDANTIC_1:
+        missing_field_error = ErrorWrapper(MissingError(), loc=("body", field_alias))
+    else:  # pragma: no cover
+        missing_field_error = ErrorWrapper(  # type: ignore
+            MissingError(), loc=("body", field_alias), config=BaseConfig,
+        )
+    return missing_field_error
+
+
 def get_schema_compatible_field(*, field: ModelField) -> ModelField:
     out_field = field
     if lenient_issubclass(field.type_, UploadFile):
diff --git a/tests/test_tutorial/test_body_multiple_params/test_tutorial003.py b/tests/test_tutorial/test_body_multiple_params/test_tutorial003.py
index 54bf193e9a613..7dcf9edd846a5 100644
--- a/tests/test_tutorial/test_body_multiple_params/test_tutorial003.py
+++ b/tests/test_tutorial/test_body_multiple_params/test_tutorial003.py
@@ -166,6 +166,30 @@ def test_openapi_schema():
                 ]
             },
         ),
+        (
+            "/items/5",
+            [],
+            422,
+            {
+                "detail": [
+                    {
+                        "loc": ["body", "item"],
+                        "msg": "field required",
+                        "type": "value_error.missing",
+                    },
+                    {
+                        "loc": ["body", "user"],
+                        "msg": "field required",
+                        "type": "value_error.missing",
+                    },
+                    {
+                        "loc": ["body", "importance"],
+                        "msg": "field required",
+                        "type": "value_error.missing",
+                    },
+                ]
+            },
+        ),
     ],
 )
 def test_post_body(path, body, expected_status, expected_response):

Closes #914 

I believe this is the "correct" way to fix this issue, as the provided body could be invalid in a number of ways, and this should handle anything that json could get parsed into. (The error message also seems appropriate to me even for malformed bodies.)

There was actually already a test for this, but it only checked for a (malformed) body of `None`, not `[]`, so it was easy to add a test case as another parametric case.

