我是Web服务(WebApi)开发新手,但直到现在,这是一段美妙的经历:)。但现在,我对我在Web服务中处理Put()请求的方式感到困惑。WebApi - 使用反射来检查表单值是否为空以便为实体设置值不好吗?
我有一个Put()请求接收multipart/form-data。在更新相应的实体之前,我必须检查表单体的值是否为空。
如果实体的特定属性为空,即不存在于主体中,则不应对属性进行任何更改,在这种情况下,属性将具有先前设置的值。如果某个属性的值存在于主体中,则需要更新该实体的相应值。
我使用if-else,但它导致了很多代码,因为我有大约10个实体属性。所以我删除了所有if-else并使用反射来实现此目的。下面是我现在用目前的代码,
[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;
}
上面的代码做工作,但问题是 - 这是唯一的办法或者有什么更好的办法来实现什么,我试图做的?如果有的话,那些方法上的指针很少会被真正赞赏。
感谢提前:)
?:或??运算符可能有助于避免if语句在很多情况下 – Kira
您可以发布“put”方法的代码吗? –
@Anand Yeah null合并运算符会很好。但是,如果我有太多的属性,我会重复所有属性的操作。 – iamyogish