2014-06-26 63 views
3

我剛開始使用一個漂亮的js庫來編輯表單元素。 Here是圖書館的鏈接。在MVC中使用X-editable時不要重複自己的最佳方式

它很好,你可以恰到好處地更新你的表單元素。但是,您需要爲每個單獨的表單元素創建一個操作。

一個例子:

<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()返回值而不是'用戶名'

這裏是而不是user.UserName值我只是想使用名稱本身,它是UserName的比較? 我可以創建一個靜態的強類型在這種情況下使用,但你認爲這是必要的嗎?爲什麼我不能只使用對象變量的名稱進行比較?

你最好的做法是什麼?

回答

3

您可以通過用戶反射來設置基於名稱的屬性值。 如果您使用這種方法,我會建議您添加一個白名單以防止發佈。

<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通過在名稱參數傳遞ID所以無需將其轉換爲適當的數據之前,添加一個「數據名稱」屬性

[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在這種情況下的行動)。如果你有很多你想要更新的字段非常有用。

+0

要獲得'ValidateAntiForgeryToken',需要使用'@ Html.AntiForgeryToken()'。看[這個問題](https://github.com/vitalets/x-editable/issues/741#issuecomment-91127543) –

相關問題