2013-10-18 46 views
0

我在編輯相關對象的屬性時遇到了一些問題。下面是代碼:如何在MVC4中編輯相關對象的屬性?

型號:

DocumentLine.cs

/// <summary> 
/// States the base implementation for all document lines in a purchasing module. 
/// </summary> 
public class DocumentLine : Keyed 
{ 
    // ... some other properties 

    /// <summary> 
    /// Gets or sets the current line's document header. 
    /// </summary> 
    [Navigation] 
    [Display(ResourceType = typeof(Resources.ApplicationResources), Name = "Header")] 
    public virtual DocumentHeader Header { get; set; } 
} 

DocumentHeader.cs

/// <summary> 
/// States the base implementation for all document headers in a purchasing module. 
/// </summary> 
public class DocumentHeader : Keyed 
{ 
    /// <summary> 
    /// Gets or sets the current header's document number. 
    /// </summary> 
    [Required] 
    [Display(ResourceType = typeof(Resources.ApplicationResources), Name = "DocumentNumber")] 
    public string DocumentNumber { get; set; } 

    /// <summary> 
    /// Gets or sets the extra cost of the document. 
    /// </summary> 
    [Display(ResourceType = typeof(Resources.ApplicationResources), Name = "ExtraCost")] 
    [RegularExpression(@"^\d*$", ErrorMessageResourceType=typeof(Resources.ApplicationResources), ErrorMessageResourceName= "Exception_ExtraCost_Error")] 
    public decimal ExtraCost { get; set; } 

    /// <summary> 
    /// Gets or sets the vat's extra cost of the document. 
    /// </summary> 
    [Display(ResourceType = typeof(Resources.ApplicationResources), Name = "ExtraVat")] 
    [RegularExpression(@"^\d*$", ErrorMessageResourceType = typeof(Resources.ApplicationResources), ErrorMessageResourceName = "Exception_ExtraVat_Error")] 
    public decimal ExtraVat { get; set; } 

    /// <summary> 
    /// Gets or sets the navigation property to all dependant Document lines. 
    /// </summary> 
    [Required] 
    [Navigation] 
    [Display(ResourceType = typeof(Resources.ApplicationResources), Name = "DocumentLines")] 
    public virtual ICollection<DocumentLine> DocumentLines { get; set; } 
} 

查看:

@Html.HiddenFor(model => model.Header.Id, Model.Header != null ? Model.Header.Id : null) 
<div class="display-label"> 
    @Html.DisplayNameFor(model => model.Header.ExtraCost) 
</div> 
<div class="display-field"> 
    <input type="text" name="Header.ExtraCost" id="Header.ExtraCost" data-varname="header.extraCost" value="@(Model.Header.ExtraCost)" /> 
    @Html.ValidationMessageFor(model => model.Header.ExtraCost) 
</div> 
<div class="display-label"> 
    @Html.DisplayNameFor(model => model.Header.ExtraVat) 
</div> 
<div class="display-field"> 
    <input type="text" name="Header.ExtraVat" id="Header.ExtraVat" data-varname="header.extraVat" value="@(Model.Header.ExtraVat)" /> 
    @Html.ValidationMessageFor(model => model.Header.ExtraVat) 
</div> 

我知道MVC跟蹤IDS和輸入名稱的值傳遞給控制器​​,這就是爲什麼我把隱藏的輸入爲Header.Id值。此視圖正確顯示值,所以我不認爲問題在這裏。

控制器:

我有一個通用的控制器方法要編輯的工作得很好,雖然我可能必須替換它這種特殊情況下。

/// <summary> 
/// Handles the POST event for the Edit action, updating an existing TEntity object. 
/// </summary> 
/// <param name="id">Id of the TEntity object to update.</param> 
/// <param name="model">TEntity object with properties updated.</param> 
/// <returns>Redirection to the Index action if succeeded, the Edit View otherwise.</returns> 
[HttpPost] 
public virtual ActionResult Edit(string id, TEntity model) 
{ 
    var request = new RestSharp.RestRequest(Resource + "?id={id}", RestSharp.Method.PUT) { RequestFormat = RestSharp.DataFormat.Json } 
     .AddParameter("id", id, RestSharp.ParameterType.UrlSegment) 
     .AddBody(model); 
    var response = Client.Execute(request); 

    // Handle response errors 
    HandleResponseErrors(response); 

    if (Errors.Length == 0) 
     return RedirectToAction("Index"); 
    else 
    { 
     ViewBag.Errors = Errors; 
     return View(model); 
    } 
} 

的主要問題是,這種代碼不僅沒有編輯相關對象的值,但也設置爲null DocumentLine的Header.Id值。

有什麼建議嗎?

回答

0

我不得不修改默認的RestSharp PUT方法,強制它首先更新文檔標題,然後是發票行。

/// PUT api/<controller>/5 
/// <summary> 
/// Upserts a InvoiceLine object and its DocumentHeader to the underlying DataContext 
/// </summary> 
/// <param name="id">Id of the InvoiceLine object.</param> 
/// <param name="value">The InvoiceLine object to upsert.</param> 
/// <returns>An HttpResponseMessage with HttpStatusCode.Ok if everything worked correctly. An exception otherwise.</returns> 
public override HttpResponseMessage Put(string id, [FromBody]InvoiceLine value) 
{ 
    //If creation date is in UTC format we must change it to local time 
    value.DateCreated = value.DateCreated.ToLocalTime(); 

    //update the document header if there is any change 
    var header = Database.Set<DocumentHeader>() 
     .FirstOrDefault(x => x.Id == value.Header.Id); 

    if (header != null) 
    { 
     value.Header.DocumentLines = header.DocumentLines; 
     value.Header.DocumentNumber = header.DocumentNumber; 
     Database.Entry<DocumentHeader>(header) 
      .CurrentValues.SetValues(value.Header); 
    } 
    else 
    { 
     Database.Set<DocumentHeader>().Add(value.Header); 
    } 

    // If entity exists, set current values to atomic properties 
    // Otherwise, insert as new 
    var entity = Database.Set<InvoiceLine>() 
     .FirstOrDefault(x => x.Id == id); 

    if (entity != null) 
    { 
     Database.Entry<InvoiceLine>(entity) 
      .CurrentValues.SetValues(value); 
     FixNavigationProperties(ref entity, value); 
    } 
    else 
    { 
     FixNavigationProperties(ref value); 
     Database.Set<InvoiceLine>().Add(value); 
    } 

    if (value is ISynchronizable) 
     (value as ISynchronizable).LastUpdated = DateTime.UtcNow; 

    // Save changes and handle errors 
    SaveChanges(); 

    return new HttpResponseMessage(HttpStatusCode.OK); 
} 

這對我有效。希望有所幫助。

0

的問題是在我的回答的最後一段在這裏更可能的,但這裏有一些其他技巧來幫助你調試問題,這樣的..

看看谷歌瀏覽器的網絡選項卡,或下載螢火對於Firefox,並查看實際發佈到該方法的內容,在該方法上放置一個斷點並確保該方法的參數實際上正在獲取值。

刪除「標題」。從您的輸入的名稱和ID實際使用 @ Html.EditorFor(model => model.ExtraCost) 。你還沒有發佈你的編輯視圖的GET方法,斷點,並確保一個實體被傳遞給視圖。

如果你得到這個工作,你只需要使用@ Html.HiddenFor(型號=> model.Id)

您認爲該ID將被張貼標識,把你的控制器,它被稱爲ID, thsi將不會綁定,所以我會懷疑Id實際上從未過去到ActionResult。

+0

我用Firebug檢查了POST調用,它正確地將參數傳遞給ActionResult。如果沒有「標題」,我無法使用EditorFor。因爲這是一個從DocumentLine繼承的InvoiceLine,它不包含ExtraCost和ExtraVat的定義。 > _ < – Kutyel

+0

您是否已將參數ID更改爲ActionResult中的Id? – Dan

+0

感謝您的回答,但是,我改變了它,它不工作。 Post參數都是正確的,但仍然是刪除'Header.Id'屬性。如果它不與'id'綁定,那麼我的代碼的其餘部分將不起作用,所以這似乎不成問題。 – Kutyel

相關問題