Deserialize from HttpRequest not working correctly in web api

Multi tool use


Deserialize from HttpRequest not working correctly in web api
I have a custom model binder to get some values from FormData
that come from a react application. Everything works fine except for one specific property: TenantDomainUrl
. When deseerialization occurs, this value is set to null
, even if its sent in the request:
FormData
TenantDomainUrl
null
Image1: (just before sending the request, check the console:
The custom model binder code is this:
public class TenantModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(Tenant))
{
return false;
}
var task = Task.Run(async () =>
{
var model = new Tenant();
if (!actionContext.Request.Content.IsMimeMultipartContent())
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "WebRequeest content 'multipart/form-data' is valid");
}
else
{
var provider = await actionContext.Request.Content.ReadAsMultipartAsync();
//var fileContent = provider.Contents.FirstOrDefault(n => n.Headers.ContentDisposition.Name.Equals("file"));
var fileContent = provider.Contents.FirstOrDefault(n => n.Headers.ContentDisposition.Name.Equals(@"""file"""));
if (fileContent == null)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Section 'file' is missed");
}
//var modelContent = provider.Contents.FirstOrDefault(n => n.Headers.ContentDisposition.Name.Equals("model"));
var modelContent = provider.Contents.FirstOrDefault(n => n.Headers.ContentDisposition.Name.Equals(@"""model"""));
if (modelContent == null)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Section 'model' is missed");
}
if (fileContent != null && modelContent != null)
{
model = JsonConvert.DeserializeObject<Tenant>(
await modelContent.ReadAsStringAsync());
model.CertificateFile = fileContent.ReadAsByteArrayAsync().Result;
}
}
return model;
});
task.Wait();
bindingContext.Model = task.Result;
return true;
}
}
And the 2nd image after deserialization
I dont think I actually need to post the REACT JS Code
Update:
readasstring returns the json correctly with the value, but after deserialization the property is null:
Update 2, tenant class
public class Tenant
{
[JsonProperty("id")]
public string TenantDomainUrl { get; set; }
public string ApplicationId { get; set; }
public string SiteCollectionTestUrl { get; set; }
public string CertificatePassword { get; set; }
public byte CertificateFile { get; set; }
public Uri CertificatePath { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
Tenant
please see update
– Luis Valencia
yesterday
2 Answers
2
Because of the JsonProperty
it will not be read from the TenantDomainUrl
JSON
value, but from id
.
JsonProperty
TenantDomainUrl
JSON
id
[JsonProperty("id")]
Remove the attribute, or alter the posted JSON
.
JSON
UPDATE
In your first picture above I notice
"id":null
Refering to a previous post on this topic, make sure to pass this id
via your FormData
with the key id
and the value set, something like here below.
id
FormData
id
data.append("model", JSON.stringify({ "id": "your-id-goes-here" }}
please see this: stackoverflow.com/questions/51468975/…
– Luis Valencia
yesterday
Edit:
If the [JsonProperty("id")]
must stay on TenantDomainUrl, you need to change the JSON you post to this endpoint to have a key of id instead of TenantDomainUrl. Something like this
[JsonProperty("id")]
{"id":"cm.microsoft.com","ApplicationId":"a21-fan-...", /* other properties in your JSON */}
instead of
{"TenantDomainUrl":"cm.microsoft.com","ApplicationId":"a21-fan-...", /* other properties in your JSON */}
I am using Cosmonaut nuget package to insert the Tenant information into CosmosDB, according to the developer I have to put JsonProperty in the field that should be the id. Please see my previous question here: stackoverflow.com/questions/51468975/…
– Luis Valencia
yesterday
In that case, you need to change the JSON you send to the server to have a key of "id" instead of "TenantDomainUrl" then.
– Zac
yesterday
Updated my answer based on your previous question. In the future, it is best to include all details in a single question (instead of having details in another question)
– Zac
yesterday
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
What does your
Tenant
class look like? Does your TenantDomainUrl have a public set accessor?– Zac
yesterday