0

関連オブジェクトのプロパティの編集で問題が発生しています。コードは次のとおりです。

モデル:

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 は入力の ID と名前を追跡して値をコントローラーに渡すことを認識しています。そのため、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);
    }
}

主な問題は、このコードが関連するオブジェクトの値を編集していないだけでなく、DocumentLineの値を null に設定していることです。Header.Id

何かアドバイス?

4

2 に答える 2

0

問題は、ここでの私の回答の最後の段落にある可能性が高いですが、このような問題をデバッグするのに役立つ他のヒントをいくつか紹介します..

Google chrome のネットワーク タブを確認するか、Firefox 用の Firebug をダウンロードして、実際にメソッドに投稿しているものを確認し、メソッドにブレーク ポイントを配置して、メソッドのパラメーターが実際に値を取得していることを確認します。

「ヘッダー」を削除します。入力の名前と ID から、代わりに @Html.EditorFor(model => model.ExtraCost) を実際に使用します。編集ビューの GET メソッドを投稿していません。これにブレークポイントを設定し、エンティティがビューに渡されていることを確認してください。

これが機能する場合は、 @Html.HiddenFor(model => model.Id) を使用するだけで済みます

あなたのビューでは、IdはIDとして投稿され、コントローラーに入れられます.

于 2013-10-18T11:05:34.537 に答える
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);
}

これは私にとってはうまくいきました。それが役立つことを願っています。

于 2013-10-28T10:28:00.050 に答える