2011-05-01 1 views
1

텍스트 상자와 DropDownListFor가있는 편집보기를 설정하려고합니다. DDLF를 채우는 방법을 알아 냈습니다. 렌더링 된 값과 게시 된 값은 정확하지만 제대로 업데이트 할 수없는 모델 인 것 같습니다.UpdateModel이 ViewModel을 통해 모델을 업데이트하지 않고 DropDownListFor의 속성을 업데이트하지 않습니다.

업데이트하려는 개체가 LINQtoSQL에서 생성되고 데이터베이스에 외래 키 열이 있습니다. LINQtoSQL 클래스에서 "포함"관계가 발생했습니다. DB의 컬럼과 그것이 나타내는 오브젝트를 나타내는 ID 속성을 얻을 수 있습니다. 또한

 [HttpPost] 
     public ActionResult Edit(int id, FormCollection collection) 
     { 
     var zupanija = repo.ZupanijaById(id); 
     var drzava = new repoDrzava().DrzavaById(Convert.ToInt32(collection["Zupanija.DrzavaID"])); 
     zupanija.Drzava = drzava; 
     } 

을 내가하려고하면 내가 업데이트를 할 알아 낸

 zupanija = new Zupanija();  //object that needs to be updated 
     zupanija.Drzava;     //object that i want to change to make the update 
     zupanija.DrzavaID;    //Property linked to object that should change 

유일한 방법은 내가 다음과 같이 변경하고자하는 개체를 가져 DDLF에서 값을 얻을 그것을 사용하는 것입니다 이 같은 ID 필드를 업데이트 한 후 내가 folowing 오류 얻을 :

  zupanija.DrzavaID = Convert.ToInt32(collection["Zupanija.DrzavaID"]); 

오류 : 던져 새로운 System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException을();

이것은 매우 비열한 방법이며, UpdateModel을 작동 시키려고합니다.

답변

5

내가 조 스티븐스에 의해 블로그에서 해결책을 발견 :

Using Controller UpdateModel when using ViewModel

잡기는 다음에있다 : 뷰 모델이 제대로 속성을 바인딩 한 후 사용하는 경우 필요가있다 UpdateModel 도우미에게 업데이트 할 실제 클래스를 찾는 방법을 "지시"합니다.

내가 업데이트하고 싶었 주요 데이터 클래스와 함께 몇 가지 특성이 포함 된 뷰 모델 클래스를 사용했기 때문에

UpdateModel(zupanija); to UpdateModel(zupanija,"Zupanija"); 

을 수정하는 데 필요한 내 솔루션입니다. 다음은 코드입니다. 이해하는 데 도움이되기를 바랍니다.

public class ZupanijaFVM 
    { 
    public IEnumerable<SelectListItem> Drzave { get; private set; } 
    public Zupanija Zupanija { get; private set; } 
    ... 
    } 

    // From Controller 
    // 
    // GET: /Admin/Zupanije/Edit/5 
    public ActionResult Edit(int id) 
    { 
     var zupanija = repo.ZupanijaById(id); 
     return zupanija == null ? View("Error") : View(new ZupanijaFVM(repo.ZupanijaById(id))); 
    } 

    // 
    // POST: /Admin/Zupanije/Edit/5 

    [HttpPost] 
    public ActionResult Edit(int id, FormCollection collection) 
    { 
     var zupanija = repo.ZupanijaById(id); 
     if (TryUpdateModel(zupanija, "Zupanija")) 
     { 
      repo.Save(); 
      return RedirectToAction("Details", new { id = zupanija.ZupanijaID }); 
     } 
     return View(new ZupanijaFVM(zupanija)); 
    } 

    //From View: 
    @model VozniRed.Areas.Admin.Models.ZupanijeFVM 

    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 
     @using (Html.BeginForm()) 
     { 
     @Html.ValidationSummary(true) 
     <fieldset> 
     <legend>Zupanija</legend> 
      @Html.HiddenFor(model => model.Zupanija.ZupanijaID) 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Zupanija.Naziv) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Zupanija.Naziv) 
      @Html.ValidationMessageFor(model => model.Zupanija.Naziv) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Zupanija.Drzava) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownListFor(model => model.Zupanija.DrzavaID, Model.Drzave) 
      @Html.ValidationMessageFor(model => model.Zupanija.DrzavaID) 
     </div> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
     </fieldset> 
     } 
    <div> 
    @Html.ActionLink("Back to List", "Index") 
    </div> 
1

드롭 다운 목록은 HTML 양식의 <select> 태그로 표시됩니다. <select>에는 ID와 텍스트가 각각 포함 된 <option> 태그 목록이 포함되어 있습니다. 사용자가 옵션을 선택하고 양식을 제출하면이 옵션의 해당 ID가 서버에 POST됩니다. 그리고 신분증 만. 그래서 당신이 당신의 Edit에 들어가기를 기대할 수 있습니다. POST 액션은 선택된 옵션의 ID입니다. 그리고 모두 UpdateModel은 보내진 요청 매개 변수를 사용하여 강력한 형식의 개체로 변환합니다. 하지만 POSTed는 모두 여러분이 얻을 수있는 간단한 ID입니다. 거기에서 해당 모델을 얻으려면이 ID를 사용하여 데이터 저장소를 쿼리해야합니다. 그래서 당신은 존재하지 않는 무언가를 얻을 수 없습니다. 다른 뭔가를 찾고있는 동안