2013-01-02 40 views
0

我是客戶端服務器,SQL程序員(RAD人員),公司決定我們必須轉向.NET環境。我們現在正在研究這個平臺。KendoUI MVC Json - 他們一起工作嗎?

本週我研究了MVC4和Entities Framework,並且我已經讀了很多關於KendoUI的內容。我很懷疑,因爲大部分的例子都帶有KendoGrid + WebApi。我對WebApi知之甚少,但我真的很喜歡這個實體的東西,所以我不認爲我應該給它一個機會。

我要問一些問題,這可能看起來幼稚,但答案將有助於我很多

  1. 有一次,我從現有的數據庫中創建的實體,我可以在JSON格式並以此結果喂一個KendoGrid?

    如果是,如何?我的意思是:

  2. 如何將結果轉換爲Json內部的控制器?

  3. 在KendoGrid的傳輸屬性中,我應該放置Controller/Action的URL?

    和最天真的一個

  4. Telerik的是否有提供可視化工具來創建,配置kendoGrid的任何想法?爲了使它更加RAD,因爲現在需要太多的編碼。也許一個嚮導,你可以用網格列,數據源,運輸等選擇連接實體..

回答

3

可用的輔助方法,我希望你選擇的劍道實體路徑,將會有一個學習曲線,但。不,問題4。但讓我給你一個使用Razor視圖引擎的快速入門,並回答1,2和3.

首先,EF正在創建業務對象。你'應該'將這些轉換爲MVC中的模型。在這個例子中,Person來自EF。我認爲這是扁平化的,因爲它從對象中移除了深度,儘管它仍然可用,所以如果您的數據庫像這樣安裝,您可以引用像Person.Titles.Name這樣的東西。您也可以放入DataAnnotations,它只是搖滾。

using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 
using Project.Business; 

namespace Project.Web.Models 
{ 
    public class PersonModel 
    { 
     public int Id { get; set; } 
     [Required(ErrorMessage = "Last Name is required.")] 
     public string LastName { get; set; } 
     [Required(ErrorMessage = "First Name is required.")] 
     public string FirstName { get; set; } 
     [Display(Name = "Created")] 
     public System.DateTime StampCreated { get; set; } 
     [Display(Name = "Updated")] 
     public System.DateTime StampUpdated { get; set; } 
     [Display(Name = "Enabled")] 
     public bool IsActive { get; set; } 

     public PersonModel() 
     {} 
     public PersonModel(Person person) 
     { 
      Id = person.Id; 
      FirstName = person.FirstName; 
      LastName = person.LastName; 
      StampCreated = person.StampCreated; 
      StampUpdated = person.StampUpdated; 
      IsActive = person.IsActive; 
     } 

     public static IList<PersonModel> FlattenToThis(IList<Person> people) 
     { 
      return people.Select(person => new PersonModel(person)).ToList(); 
     } 

    } 
} 

一起運動......

@(Html.Kendo().Grid<PersonModel>() 
    .Name("PersonGrid") 
    .Columns(columns => { 
     columns.Bound(b => b.Id).Hidden(); 
     columns.Bound(b => b.LastName).EditorTemplateName("_TextBox50"); 
     columns.Bound(b => b.FirstName).EditorTemplateName("_TextBox50"); 
     columns.Bound(b => b.StampUpdated); 
     columns.Bound(b => b.StampCreated); 
     columns.Bound(b => b.IsActive).ClientTemplate("<input type='checkbox' ${ IsActive == true ? checked='checked' : ''} disabled />").Width(60); 
      columns.Command(cmd => { cmd.Edit(); cmd.Destroy(); }).Width(180); 
     }) 
    .ToolBar(toolbar => toolbar.Create()) 
    .Pageable() 
    .Filterable() 
    .Sortable() 
    .Selectable() 
    .Editable(editable => editable.Mode(GridEditMode.InLine)) 
    .DataSource(dataSource => dataSource 
     .Ajax() 
     .Events(events => events.Error("error_handler")) 
     .Model(model => 
      { 
       model.Id(a => a.Id); 
       model.Field(a => a.StampCreated).Editable(false); 
       model.Field(a => a.StampUpdated).Editable(false); 
       model.Field(a => a.IsActive).DefaultValue(true); 
      }) 
     .Create(create => create.Action("CreatePerson", "People")) 
     .Read(read => read.Action("ReadPeople", "People")) 
     .Update(update => update.Action("UpdatePerson", "People")) 
     .Destroy(destroy => destroy.Action("DestroyPerson", "People")) 
     .PageSize(10) 
    ) 
) 

那些_TextBox50是名爲_TextBox50.cshtml EditorTemplates一定要去無論是相對於您的觀點或相對於你的共享文件夾的子文件夾 - 文件夾必須調用EditorTemplates。這看起來像這樣...

@Html.TextBox(string.Empty, string.Empty, new { @class = "k-textbox", @maxlength = "50" }) 

是的,就是這樣。這是一個簡單的例子,他們可以變得更加複雜。或者你最初不必使用它們。

最後,我認爲你真的在尋找...

public partial class PeopleController : Controller 
{ 
    private readonly IPersonDataProvider _personDataProvider; 

    public PeopleController() : this(new PersonDataProvider()) 
    {} 
    public PeopleController(IPersonDataProvider personDataProvider) 
    { 
     _personDataProvider = personDataProvider; 
    } 

    public ActionResult Manage() 
    { 
>>> Left in as teaser, good to apply a special Model to a View to pass goodies ;) 
     var model = new PeopleViewModel(); 
     model.AllQualifications = QualificationModel.FlattenToThis(_qualificationDataProvider.Read()); 
     return View(model); 
    } 

    [HttpPost] 
    public JsonResult CreatePerson([DataSourceRequest]DataSourceRequest request, Person person) 
    { 
     if (ModelState.IsValid) 
     { 
      try 
      { 
       person = _personDataProvider.Create(person); 
      } 
      catch (Exception e) 
      { 
       ModelState.AddModelError(string.Empty, e.InnerException.Message); 
      } 
     } 
     var persons = new List<Person> {person}; 
     DataSourceResult result = PersonModel.FlattenToThis(persons).ToDataSourceResult(request, ModelState); 
     return Json(result, JsonRequestBehavior.AllowGet); 
    } 

    public JsonResult ReadPeople([DataSourceRequest]DataSourceRequest request) 
    { 
     var persons = _personDataProvider.Read(false); 
     DataSourceResult result = PersonModel.FlattenToThis(persons).ToDataSourceResult(request); 
     return Json(result, JsonRequestBehavior.AllowGet); 
    } 

    [HttpPost] 
    public JsonResult UpdatePerson([DataSourceRequest]DataSourceRequest request, Person person) 
    { 
     if (ModelState.IsValid) 
     { 
      try 
      { 
       person = _personDataProvider.Update(person); 
      } 
      catch (Exception e) 
      { 
       ModelState.AddModelError(string.Empty, e.InnerException.Message); 
      } 
     } 
     var persons = new List<Person>() {person}; 
     DataSourceResult result = PersonModel.FlattenToThis(persons).ToDataSourceResult(request, ModelState); 
     return Json(result, JsonRequestBehavior.AllowGet); 
    } 

    [HttpPost] 
    public JsonResult DestroyPerson([DataSourceRequest]DataSourceRequest request, Person person) 
    { 
     if (ModelState.IsValid) 
     { 
      try 
      { 
       person = _personDataProvider.Destroy(person); 
      } 
      catch (Exception e) 
      { 
       ModelState.AddModelError(string.Empty, "There was an error deleting this record, it may still be in use."); 
      } 
     } 
     var persons = new List<Person>() {person}; 
     DataSourceResult result = PersonModel.FlattenToThis(persons).ToDataSourceResult(request, ModelState); 
     return Json(result, JsonRequestBehavior.AllowGet); 
    } 
} 

注意,在這種情況下,每個方法將人EF作爲參數,這將是更好地使用PersonModel但我必須證明展平相反。由於它們實際上是相同的,所以這可行。如果模型不同或者您使用的是類工廠,則會變得更棘手。

我有意向你展示了所有的CRUD操作。如果您沒有將結果傳遞迴網格,它會很有趣,並且會在CREATE和UPDATE上給您提供重複或無法正確顯示更新。它傳回DELETE傳遞將有任何錯誤的ModelState。

最後的數據提供者,以便沒有離開想象力... (命名空間聲明被遺漏。)

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
using System.Linq; 
using Project.Business; 

public class PersonDataProvider : ProviderBase, IPersonDataProvider 
{ 
    public Person Create(Person person) 
    { 
     try 
     { 
      person.StampCreated = DateTime.Now; 
      person.StampUpdated = DateTime.Now; 

      Context.People.Attach(person); 
      Context.Entry(person).State = EntityState.Added; 
      Context.SaveChanges(); 
      return person; 
     } 
     catch (Exception e) 
     { 
      Debug.WriteLine(e.Message); 
      throw; 
     } 
    } 

    public IList<Person> Read(bool showAll) 
    { 
     try 
     { 
      return (from q in Context.People 
         orderby q.LastName, q.FirstName, q.StampCreated 
         where (q.IsActive == true || showAll) 
         select q).ToList(); 
     } 
     catch (Exception e) 
     { 
      Debug.WriteLine(e.Message); 
      throw; 
     } 
    } 

... 

} 

注接口和繼承的ProviderBase,你必須做出的。應該很簡單,以找到例子。

這可能看起來像很多編碼,但一旦你把它弄下來,就複製粘貼。

快樂編碼。

+0

謝謝Trey!劍道是我想要走的路。我有最後一個阻礙我的問題。當我從使用PK和FK的數據庫創建實體時,當我嘗試在Controller中Json數據並將它們發送到View中的KendoGrid時,我收到「循環引用」錯誤消息。在我的數據庫模式關係中沒有循環引用雖然!我搜索,學習,測試,但我無法克服它。 http://stackoverflow.com/questions/14153325/ef-entities-that-c​​ontain-relations-pks-fks-cannot-be-json-ed/14153584#comment19607285_14153584 – PanosPlat

+0

@Trey Gramann,是「FlattenToThis」用於防止循環參考? –

+0

等等。它從EF生成的類中移除深層結構。通常,模型和EF類之間存在1對1映射。但在某些情況下,我的FlattenToThis需要幾個對象參數並執行操作來設置可能與數據庫沒有直接關係的模型,只是演示文稿。所以想知道業務邏輯?我的團隊將生成的EF類移入業務項目,接口和部分,這樣我們就可以擴展而不會覆蓋風險。怎麼樣?定製的T4模板。我知道,TMI。 –

0

是的,你可以發送JSON使用JsonResult或使用JSON與允許獲得規定後劍道UI。你可以在傳輸中設置url並指定json作爲類型。

關於你的最後一個問題是沒有可視化工具,但現在也有對劍道的UI

相關問題