在MVC ASP.net中使用X-editable时避免重复的最好方法
本文关键字:方法 net ASP MVC X-editable | 更新日期: 2023-09-27 18:10:34
我刚刚开始使用一个很好的js库来编辑表单元素。这是库的链接。
它工作得很好,你可以在适当的地方更新你的表单元素。但是,您需要为每个单独的表单元素创建一个操作。
示例:
<a href="#" class="EditableSection" data-type="text" data-pk="@Model.id" data-name="Name" data-url="@Url.Action("_EditName", "User", new { Model.id})" data-title="Edit Name">@Model.Name</a>
<a href="#" class="EditableSection" data-type="text" data-pk="@Model.id" data-name="MiddleName" data-url="@Url.Action("_EditMiddleName", "User", new { Model.id})" data-title="Edit Middle Name">@Model.MiddleName</a>
<a href="#" class="EditableSection" data-type="text" data-pk="@Model.id" data-name="SurName" data-url="@Url.Action("_EditSurName", "User", new { Model.id})" data-title="Edit SurName">@Model.SurName</a>
在UserController中,我认为我需要有3个不同的动作,除了元素更新之外,动作的大部分内部类似。
这是一个动作:
[HttpPost]
public ActionResult _EditUserName(int id, int pk, string value, string name)
{
var user= this._userRep.First(o => o.id== pk);
if (user!= null && user.id== id)
{
if (!string.IsNullOrEmpty(value))
{
user.UserName= value; //this is the only line changes from one to another action respectively user.MiddleName = value or user.SurName = value
this._userRep.Update(user);
this._userRep.SaveChanges();
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
return Json(new { status = "error", msg = "You cannot leave blank" });
}
return Json(new {status="error",msg="You cannot leave blank"});
}
我可以看到2个选项来改进使代码DRY
第一个是为每个表单元素创建一个操作,并将所有公共任务放在一个单独的方法中以调用每个操作。(我仍然认为太多的打字和混乱)
第二个选项是我关注的,但我不知道是哪个,我想在这里得到你的帮助:
创建一个公共操作作为_EditUserDetails,并使用下面的条件:
[HttpPost]
public ActionResult _EditUserDetails(int id, int pk, string value, string name)
{
var user= this._userRep.First(o => o.id== pk);
if (user!= null && user.id== id)
{
if (!string.IsNullOrEmpty(value))
{
if(name=user.UserName.toString())
user.UserName= value;
else if(name=user.MiddleName.toString())
user.MiddleName= value;
else if(name=user.MiddleName.toString())
user.SurName= value;
this._userRep.Update(user);
this._userRep.SaveChanges();
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
return Json(new { status = "error", msg = "You cannot leave blank" });
}
return Json(new {status="error",msg="You cannot leave blank"});
}
我无法获得用户对象变量名的名称进行比较,我也不确定这是检查它的正确方法
if(name=user.UserName.toString())
//name等于表单元素名称。并且我知道user.UserName.toString()
返回值而不是'UserName'
这里是代替user。UserName值,我只想使用名称本身UserName进行比较?我可以创建一个静态强类型类在这种情况下使用,但你认为这是必要的吗?为什么我不能使用对象变量的名称进行比较?
你对此的最佳实践是什么?
您可以使用反射来根据名称设置属性值。如果你使用这种方法,我建议你添加一个白名单,以防止过度发布。
<a href="#" class="EditableSection" data-type="text" data-pk="@Model.id" id="Name" data-url="@Url.Action("InlineEdit", "User", new { Model.id})" data-title="Edit Name">@Model.Name</a>
<a href="#" class="EditableSection" data-type="text" data-pk="@Model.id" id="MiddleName" data-url="@Url.Action("InlineEdit", "User", new { Model.id})" data-title="Edit Middle Name">@Model.MiddleName</a>
xeditables通过name参数传递ID,因此不需要添加"data-name"属性
[HttpPost,
ValidateAntiForgeryToken]
public ActionResult InlineEdit(int pk, string value, string name)
{
//
// White list to prevent overposting
string whitelist = "Name,MiddleName,SurName";
if (!whitelist.Contains(name))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, string.Format("Invalid Field {0}", name));
};
var user= this._userRep.First(o => o.id== pk);;
if (user == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, string.Format("Resource not found"));
}
try
{
this.SetPropertyValue(user, name, value);
this._userRep.Update(user);
this._userRep.SaveChanges();
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
catch (DbEntityValidationException ex)
{
var error = ex.EntityValidationErrors.First().ValidationErrors.First();
this.ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, string.Format("{0}: {1}", error.PropertyName, error.ErrorMessage));
}
}
下面是一个函数,用于在将属性转换为适当的数据类型之前设置属性
private Object SetPropertyValue(Object entity, string property, string value)
{
PropertyInfo propertyInfo = entity.GetType().GetProperty(property);
if (propertyInfo != null)
{
Type t = propertyInfo.PropertyType;
object d;
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
{
if (String.IsNullOrEmpty(value))
d = null;
else
d = Convert.ChangeType(value, t.GetGenericArguments()[0]);
}
else if (t == typeof(Guid))
{
d = new Guid(value);
}
else
{
d = Convert.ChangeType(value, t);
}
propertyInfo.SetValue(entity, d, null);
}
return entity;
}
三个字段的大量代码(在这种情况下,我宁愿用户3个操作)。