2014-04-13 4 views
0

MVC 4, ASP.NET을 사용하고 있습니다. 체크 박스 값을 컨트롤러의 포스트 메서드에 전달하는 문제가 있습니다. 널 값으로 리턴합니다.HTTP 배열이 문자열 배열을 반환하지 않습니다.

여기 내 시야의 일부 (작품을 얻기 제대로 데이터를 채우고) :

@using (Html.BeginForm()) 
{ 
<fieldset> 
     <table> 
      <tr> 
       @{ 
        int cnt = 0; 
        List<LearningEnterprises.ViewModel.AssignedVendor> techs = ViewBag.Tech; 

        foreach (var tech in techs) 
        { 
         if (cnt++ % 3 == 0) 
         { 
          @:</tr><tr> 
         } 
         @:<td> 
          <input type="checkbox" 
           name="selectedTechs" 
           value="@tech.TechID" 
           @(Html.Raw(tech.Assigned ? "checked=\"checked\"" : "")) /> 
           @tech.TechID @: @tech.Title 
         @:</td> 
        } 
        @:</tr> 
       } 
     </table> 
     <p> 
       <input type="submit" value="Save" id="save" /> 
     </p> 
     </fieldset> 

} 

여기 내 게시물의 :

[Authorize(Roles = "Admin")] 
    [HttpPost, ValidateInput(false)] 
    public ActionResult EditVendor(int? id, string[] selectedTech) 
    { 
     if (id == null) 
     { 
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
     } 
     var vendor = db.Vendors 
      .Include(i => i.VendorType) 
      .Include(i=>i.Stocks) 
      .Where(i => i.ID == id) 
      .Single(); 

     if (TryUpdateModel(vendor, "", 
     new string[] { "CompanyName", "PhoneNumber", "Address", "ProvinceState", "City", "Country", "PostalCode", "Email", "numberofBooths", "comments", "electric", "internet", "tonicEquipment", "VendorTypeID" })) 
     { 
      try 
      { 
       UpdateVendorTech(selectedTech, vendor); 
       db.Entry(vendor).State = EntityState.Modified; 

       db.SaveChanges(); 
       return RedirectToAction("Index"); 
      } 

      catch (Exception /* dex */) 
      { 
       //Log the error (uncomment dex variable name and add a line here to write a log. 
       ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); 
      } 
     } 
     PopulateAssignedTechData(vendor); 
     PopulateDropDownLists(vendor.VendorTypeID); 
     return View(vendor); 
    } 

문자열 [] selectedTech 디버그에서 null 값을 표시한다. 보기에서 선택된 체크 상자의 id 값과 같아야합니다.

답변

0

내가 볼 수있는 첫번째 일은 당신의 이름이 불일치한다는 것입니다 : 당신이보기에 컨트롤러에 string[] selectedTech하지만 name = "selectedTechs"이 다음 모든 값을 찾을 수 없습니다되는 ASP.NET 바인더, 그것은 null로 배열을 설정합니다. 나는 또한 당신이 당신의 Html.BeginForm()의 모든 게시물의 URL이없는하지만 당신이 말한 경우에 당신은 당신이 그것을에게 다른 방법을 수행한다고 가정 디버그 값을 확인 할 수 있습니다

...

0

나는 user3426870 것으로 기대 그리고 그 문제는 EditVendor 메서드 서명 (selectedTech)의 이름이 뷰의 확인란 이름 (selectedTechs)과 일치하지 않는 것입니다. DefaultModelBinder은 값을 바인딩 할 매개 변수와 일치하지 않을 것으로 생각됩니다.

또한 TryUpdateModel에는 게시 요청에 전달 될 뷰에 정의 된 속성이 포함되어 있지 않으므로이 기능이 작동하지 않을 것으로 판단됩니다.

  • 컨트롤러 방법은 매우 큰 :

    은 당신이 할 수있는 몇 가지 다른 개선 (당신이 연구 할 수있는) 제안 할 수 있습니다. 서비스/리포지토리를 사용하여 비즈니스 논리를 수행하고 데이터베이스 데이터베이스를 호출하여 컨트롤러가 수행중인 작업 수를 줄여야합니다. 이렇게하면 더 작은 부분을 더 테스트 할 수 있습니다.

  • 서명에있는 ID가 null이 아니어야하는 경우 (잘못된 요청을 반환 할 때), nullable int가 아니어야합니다. 매개 변수. 그런 다음 더 이상 점검을 수행 할 필요가 없습니다.

또한, ID가 selectedTech 목록 데이터 통계 또는 유창한 검증을 이용하여 0보다 큰 그러한 검증을 수행 할 수있는 수를 갖는 큰 0보다 크거나 있다는 것을 보장하기 위해 검증을 추가 할 수있다 다음과 같은 코드에서 수행 된 간단한 검사 :

if (ModelState.IsValid) { ... } 

매개 변수가 정의 된 유효성 검사를 통과했는지 확인하십시오.

  • 필요한 정보가 정확히 포함 된보기의보기 모델을 사용해야합니다. 그런 다음 매핑 클래스 (또는 자동 매퍼)를 사용하여이 하위 클래스 비즈니스 클래스와 하위 클래스 비즈니스 클래스간에 매핑 할 수 있습니다. 보기 모델을 사용하는 것이 더 좋으며 ViewBag 속성을 사용하지 않아도됩니다.HTML 도우미 메서드 중 일부를 사용하여 일부보기 모델 속성을 쓸 수도 있습니다.

이러한 아이디어가 도움이되기를 바랍니다.

관련 문제