Currently, we are using a route like this:
[HttpPost]
[Route("upload")]
public async Task<dynamic> Upload(dynamic uploadedData)
{
JArray files = uploadedData.pdfs;
// ...
}
Rather than using dynamic
, I'd like to have a schematic understanding of the data coming in. So I could use a setup like this, with a class that defines the schema:
public class UploadRequest : JObject
{
public JArray pdfs { get; set; }
}
[HttpPost]
[Route("upload")]
public async Task<dynamic> Upload(UploadRequest uploadedData)
{
// Now can access the JArray via uploadedData.pdfs directly
// ...
}
Is this the right approach to this situation? Or is there another standard best practice for receiving JSON data via ASP .NET WebAPI?
Specifically, this approach doesn't currently work. Though my small schema class extends JObject, I get an error of
The parameters dictionary contains an invalid entry for parameter 'uploadedData' for method 'System.Threading.Tasks.Task`1[System.Object] Upload(UploadRequest)' in 'EditPdfServer.Controllers.PdfFileController'. The dictionary contains a value of type 'Newtonsoft.Json.Linq.JObject', but the parameter requires a value of type 'EditPdfServer.Controllers.PdfFileController+UploadRequest'.
So firstly, does this seem like a proper approach? Secondly, is there a better one? Thirdly, why doesn't this approach work? Thanks in advance.
In this article Routing is how Web API matches a URI to an action. Web API 2 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web API.
This route is defined in the WebApiConfig. cs file, which is placed in the App_Start directory: For more information about the WebApiConfig class, see Configuring ASP.NET Web API.
Using [FromUri] To force Web API to read a complex type from the URI, add the [FromUri] attribute to the parameter. The following example defines a GeoPoint type, along with a controller method that gets the GeoPoint from the URI.
The [FromUri] attribute is prefixed to the parameter to specify that the value should be read from the URI of the request, and the [FromBody] attribute is used to specify that the value should be read from the body of the request.
You're on track.
You don't need to be overly concerned with the internal implementation of Newtonsoft.Json. In particular, you should try to avoid using JObject/JToken/other J-types, and you definitely don't need to subclass JObject.
Your request object class can simply be:
public class UploadRequest
{
[JSONProperty("pdfs")]
public SomePDFClass PDFs[] { get; set; }
}
This would map to a request of:
{
"pdfs": [
{ <some PDF object here> },
{ <some PDF object here> },
{ <some PDF object here> }
]
}
The string parameter of JSONPropertyAttribute
defines the name of the property as it appears in the JSON document, so you don't need to have the same name in code as you do in JSON. You can change the name in code, so long as the attribute still uses the same name as the document.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With