I am new to Web services (WebApi) development, but it's been wonderful experience till now :). But right now, I am confused with the way I am handling Put() requests in my web service.
I have a Put() request which receives multipart/form-data. I have to check whether the Form body values are null or not before updating the corresponding Entity.
If a particular property of Entity is null i.e. not present in the body, I should not make any changes to property in which case property will have previously set value. If there's a value present in the body for a property, then I need to update the corresponding value for the entity.
I used if-else, but it caused lot of code as I have around 10 properties for the entity. So I removed all the if-else and used reflection to achieve this. Here's the code which I am using currently,
[AuthorizationRequired]
[Route("v1/product/updateproduct/")]
[HttpPut]
public bool Put()
{
var httpRequest = HttpContext.Current.Request;
string pdfFolderPath = HttpContext.Current.Server.MapPath("~/Pdf/");
string imageFolderPath = HttpContext.Current.Server.MapPath("~/Images/");
ProductEntity productToUpdate = new ProductEntity();
int id = int.Parse(httpRequest["ProductId"].ToString());
if (id > 0)
{
//Get the existing product entity for the ID
ProductEntity existingProduct = _productServices.GetProductById(id);
if (existingProduct != null)
{
//Check if any files are sent in the PUT Request
//If there are files with appropriate names, then delete the existing files with the new files sent
if (httpRequest.Files.Count > 0)
{
//Handle Files.
}
//Updating the changed properties of Product by using Reflection.
PropertyInfo[] properties = productToUpdate.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
//Check if the property of the Product class exists in the Form Body of Put.
//If it exists, take the corresponding value of property and update it to the product.
//If it doesn't exist, retain the value present in the existing product as it is.
if (httpRequest.Form.AllKeys.Contains(property.Name, StringComparer.OrdinalIgnoreCase))
{
int formPropertyIndex = Array.FindIndex(httpRequest.Form.AllKeys, str => str.Equals(property.Name, StringComparison.OrdinalIgnoreCase));
string propertyToFind = httpRequest.Form.AllKeys[formPropertyIndex];
if (String.Equals(propertyToFind, "FacilityId", StringComparison.OrdinalIgnoreCase))
{
productToUpdate.GetType().GetProperty(propertyToFind, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance).SetValue(productToUpdate, Convert.ToInt32(httpRequest[property.Name]));
}
else
{
productToUpdate.GetType().GetProperty(propertyToFind, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance).SetValue(productToUpdate, httpRequest[property.Name].ToString());
}
}
else
{
var existingValue = existingProduct.GetType().GetProperty(property.Name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance).GetValue(existingProduct);
productToUpdate.GetType().GetProperty(property.Name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance).SetValue(productToUpdate, existingValue);
}
}
if (productToUpdate.ImagePath == null)
productToUpdate.ImagePath = existingProduct.ImagePath;
if (productToUpdate.AR_PdfPath == null)
productToUpdate.AR_PdfPath = existingProduct.AR_PdfPath;
if (productToUpdate.AR_Alt_PdfPath == null)
productToUpdate.AR_Alt_PdfPath = existingProduct.AR_Alt_PdfPath;
if (productToUpdate.EN_PdfPath == null)
productToUpdate.EN_PdfPath = existingProduct.EN_PdfPath;
if (productToUpdate.EN_Alt_PdfPath == null)
productToUpdate.EN_Alt_PdfPath = existingProduct.EN_Alt_PdfPath;
//Update LastModifiedBy & LastModifiedAt
string token = httpRequest.Headers.GetValues("Token").ToList().FirstOrDefault();
UserEntity user = _tokenServices.GetUserDetailsForToken(token);
productToUpdate.LastModifiedBy = user.UserName;
productToUpdate.LastModifiedAt = DateTime.Now;
return _productServices.UpdateProduct(id, productToUpdate);
}
else
{
return false;
}
}
return false;
}
The above code does the job, but the question is - Is this the only way or is there any better way to achieve what I am trying to do? If there is, few pointers on those approach would be really appreciated.
Thanks In Advance :)