4

我試圖找到使用Web API 2控制器並沒有太多運氣的Kendo Grid MVC服務器包裝的示例。有沒有使用這些服務器包裝使用由VS生成的控制器的方式「添加」 - >「控制」 - >「網絡API 2控制器用行動,用實體框架?」使用異步控制器操作會影響這個嗎?使用Web API 2控制器的Kendo Grid MVC包裝器的示例

我已經看過Telerik(http://docs.telerik.com/kendo-ui/tutorials/asp.net/asp-net-hello-services)和示例項目(http://www.telerik.com/support/code-library/binding-to-a-web-apicontroller-6cdc432b8326)的教程,但都沒有使用VS可以自動生成的新Web API 2控制器。

我寧願能夠使用VS生成的控制器,但我的技能顯然沒有達到適應現有的例子給他們(這是我與MVC /網絡API的第一個項目)。有沒有其他人這樣做過,還是應該像那些兩歲的例子那樣編寫控制器?

ETA:就包括起點目前我有:

我使用EF代碼第一次從數據庫中創建的模型。簡單的一個我使用來測試,這是這一個:

namespace TestProject.Models 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel.DataAnnotations; 
    using System.ComponentModel.DataAnnotations.Schema; 

    [Table("TP.Industry")] 
    public partial class Industry 
    { 
     public Industry() 
     { 
      Companies = new HashSet<Company>(); 
     } 

     public int IndustryId { get; set; } 

     public int IndustryCode { get; set; } 

     [Required] 
     [StringLength(150)] 
     public string IndustryName { get; set; } 

     public virtual ICollection<Company> Companies { get; set; } 
    } 
} 

然後我創建的控制器中使用的「Web API 2控制器用行動,用實體框架」選項,並選中「使用異步控制器動作」來得到如下控制器,該型號:

using System; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
using System.Linq; 
using System.Net; 
using System.Threading.Tasks; 
using System.Web.Http; 
using System.Web.Http.Description; 
using TestProject.Models; 

namespace TestProject.Controllers 
{ 
    public class IndustryController : ApiController 
    { 
     private TestProjectContext db = new TestProjectContext(); 

     // GET api/Industry 
     public IQueryable<Industry> GetIndustries() 
     { 
      return db.Industries; 
     } 

     // GET api/Industry/5 
     [ResponseType(typeof(Industry))] 
     public async Task<IHttpActionResult> GetIndustry(int id) 
     { 
      Industry industry = await db.Industries.FindAsync(id); 
      if (industry == null) 
      { 
       return NotFound(); 
      } 

      return Ok(industry); 
     } 

     // PUT api/Industry/5 
     public async Task<IHttpActionResult> PutIndustry(int id, Industry industry) 
     { 
      if (!ModelState.IsValid) 
      { 
       return BadRequest(ModelState); 
      } 

      if (id != industry.IndustryId) 
      { 
       return BadRequest(); 
      } 

      db.Entry(industry).State = EntityState.Modified; 

      try 
      { 
       await db.SaveChangesAsync(); 
      } 
      catch (DbUpdateConcurrencyException) 
      { 
       if (!IndustryExists(id)) 
       { 
        return NotFound(); 
       } 
       else 
       { 
        throw; 
       } 
      } 

      return StatusCode(HttpStatusCode.NoContent); 
     } 

     // POST api/Industry 
     [ResponseType(typeof(Industry))] 
     public async Task<IHttpActionResult> PostIndustry(Industry industry) 
     { 
      if (!ModelState.IsValid) 
      { 
       return BadRequest(ModelState); 
      } 

      db.Industries.Add(industry); 
      await db.SaveChangesAsync(); 

      return CreatedAtRoute("DefaultApi", new { id = industry.IndustryId }, industry); 
     } 

     // DELETE api/Industry/5 
     [ResponseType(typeof(Industry))] 
     public async Task<IHttpActionResult> DeleteIndustry(int id) 
     { 
      Industry industry = await db.Industries.FindAsync(id); 
      if (industry == null) 
      { 
       return NotFound(); 
      } 

      db.Industries.Remove(industry); 
      await db.SaveChangesAsync(); 

      return Ok(industry); 
     } 

     protected override void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       db.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     private bool IndustryExists(int id) 
     { 
      return db.Industries.Count(e => e.IndustryId == id) > 0; 
     } 
    } 
} 

最後,我把下面的劍道UI MVC包裝代碼在我看來網格:

@(Html.Kendo().Grid<TestProject.Models.Industry>() 
    .Name("Grid") 
    .Columns(columns => 
    { 
     columns.Bound(c => c.IndustryId); 
     columns.Bound(c => c.IndustryCode); 
     columns.Bound(c => c.IndustryName); 
     columns.Command(c => 
     { 
      c.Edit(); 
      c.Destroy(); 
     }); 
    }) 
    .ToolBar(tools => 
    { 
     tools.Create(); 
    }) 
    .Sortable() 
    .Pageable(pageable => pageable 
     .Refresh(true) 
     .PageSizes(true) 
     .ButtonCount(5)) 
    .Filterable() 
    .DataSource(dataSource => dataSource 
     .Ajax() 
     .Model(model => 
     { 
      model.Id(c => c.IndustryId); 
     }) 
     .Read(read => read.Url("../api/Industry").Type(HttpVerbs.Get)) 
     .Create(create => create.Url("../api/Industry").Type(HttpVerbs.Post)) 
     .Update(update => update.Url("../api/Industry").Type(HttpVerbs.Put)) 
     .Destroy(destroy => destroy.Url("../api/Industry").Type(HttpVerbs.Delete)) 
    ) 
) 

<script> 

    $(function() { 
     var grid = $("#Grid").data("kendoGrid"); 

     // WebAPI needs the ID of the entity to be part of the URL e.g. PUT /api/Product/80 
     grid.dataSource.transport.options.update.url = function (data) { 
      return "api/Industry/" + data.IndustryId; 
     } 

     // WebAPI needs the ID of the entity to be part of the URL e.g. DELETE /api/Product/80 
     grid.dataSource.transport.options.destroy.url = function (data) { 
      return "api/Industry/" + data.IndustryId; 
     } 
    }); 

</script> 

電網沒有返回DAT和請求,API返回這500內部服務器錯誤:

This XML file does not appear to have any style information associated with it. The document tree is shown below. 
<Error> 
    <Message>An error has occurred.</Message> 
    <ExceptionMessage> 
     The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'. 
    </ExceptionMessage> 
    <ExceptionType>System.InvalidOperationException</ExceptionType> 
    <StackTrace/> 
    <InnerException> 
    <Message>An error has occurred.</Message> 
    <ExceptionMessage> 
     Type 'System.Data.Entity.DynamicProxies.Industry_5BBD811C8CEC2A7DB96D23BD05DB137D072FDCC62C2E0039D219F269651E59AF' with data contract name 'Industry_5BBD811C8CEC2A7DB96D23BD05DB137D072FDCC62C2E0039D219F269651E59AF:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer. 
    </ExceptionMessage> 
    <ExceptionType> 
     System.Runtime.Serialization.SerializationException 
    </ExceptionType> 
    <StackTrace> 
     at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext() 
    </StackTrace> 
    </InnerException> 
</Error> 

事實上,如果我只是腳手架對模型的視圖,就像這樣:

@model IEnumerable<TestProject.Models.Industry> 

@{ 
    ViewBag.Title = "Industries"; 
} 

<h2>Industries</h2> 

<p> 
    @Html.ActionLink("Create New", "Create") 
</p> 
<table class="table"> 
    <tr> 
     <th> 
      @Html.DisplayNameFor(model => model.IndustryCode) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.IndustryName) 
     </th> 
     <th></th> 
    </tr> 

@foreach (var item in Model) { 
    <tr> 
     <td> 
      @Html.DisplayFor(modelItem => item.IndustryCode) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.IndustryName) 
     </td> 
     <td> 
      @Html.ActionLink("Edit", "Edit", new { id=item.IndustryId }) | 
      @Html.ActionLink("Details", "Details", new { id=item.IndustryId }) | 
      @Html.ActionLink("Delete", "Delete", new { id=item.IndustryId }) 
     </td> 
    </tr> 
} 

</table> 

的「@foreach(VAR項目在模型中){「line生成一個」NullReferenceException:未將對象引用設置爲對象的實例「。錯誤。

即使Kendo部分是不正確的,至少所有的VS生成的代碼應該正常工作,似乎並不是。

+0

什麼是你的難度?錯誤?不編譯代碼? – Stargazer

+0

我已經添加了我正在測試的現有代碼以及我得到的原始問題的錯誤。 – DivisionByZero

+0

如果你用一個客戶測試你的api,例如郵差或黑客,你會看到結果嗎?而且,既然你使用異步,我猜你必須考慮到這一點...不知道雖然... – Stargazer

回答

2

因此,根據我迄今爲止的研究,似乎沒有任何使用帶有異步操作的Web API 2控制器的Kendo MVC包裝器的示例。

但是,現在似乎有一個Web API Editing部分在Kendo UI快速入門文檔(我發誓不是之前)有一個更新的示例,不依賴於添加DataSourceRequestModelBinder.cs文件到項目。

控制器設置基本上與前面的例子類似,但是。對電網包裝的DataSource現在看起來是這樣的:

.DataSource(dataSource => dataSource 
    .WebApi() 
    .Model(model => 
    { 
     model.Id(i => i.IndustryId); 
     model.Field(i => i.IndustryId).Editable(false); 
    }) 
    .Create(create => create.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "Industries" }))) 
    .Read(read => read.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "Industries" }))) 
    .Update(update => update.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "Industries", id = "{0}" }))) 
    .Destroy(destroy => destroy.Url(Url.HttpRouteUrl("DefaultApi", new { controller = "Industries", id = "{0}" }))) 
) 

這.WebApi()方法,只是沒有顯示我的任何搜索起來。這似乎工作,所以我會去運行它。謝謝,所有!

+0

它如何知道要運行哪個操作?如果你有一個自定義的命名動作呢? –

0

Here你可以找到一個有關MVC技術的例子。應該有一個你正在尋找的例子。

+0

除非我忽略了一些東西,這些例子都與我看過的現有的非常相似。如果我無法使最新的VS生成的Web API 2控制器正常工作,這些肯定會成爲我使用的選項2。謝謝! – DivisionByZero