2011-03-01 3 views
0

게시 된 파일 컬렉션과 같은 ASP.NET MVC 앱에서 DB에 삽입 할 항목이 많으면 대부분의 예외 처리 논리를 수행합니다 컨트롤러 또는 inisde 저장소에? ASP.NET MVC 컨트롤러에서 객체 컬렉션을 데이터 저장소에 삽입

는 (저장소에 어쩌면 처리를 제외하고이 방법이 성공적으로 실행 된 여부에 기반 허위/저장소 액션 반환 TRUE)이

[AcceptVerbs(HttpVerbs.Post)] 
    public virtual ActionResult Import(HttpPostedFileBase fileToUpload) 
    { 
     string path = Server.MapPath("~/App_Data/Upload/") + Path.GetFileName(fileToUpload.FileName); 
     fileToUpload.SaveAs(path); 
     string selectCmd = "SELECT * FROM [Pricelist$]"; 

     try { 
      foreach (DataRow dr in ExcelUtility.ReadFile(path, selectCmd).Tables[0].Rows) { 
       Product p = new Product 
       { 
        Title = dr["product_name1"].ToString().Trim(), 
        Measure = dr["product_measure"].ToString().Trim(), 
       }; 

       if (dr["product_price"] != DBNull.Value) 
        p.Price = (double)dr["product_price"]; 
       if (dr["product_taxrate"] != DBNull.Value) 
        p.TaxRate = (double)dr["product_taxrate"]; 
       _repository.Add(p); 
      } 
     } 
     catch (Exception e) { 
      // handle exception or run the action in transaction?? 
     } 

     return RedirectToAction("ImportSuccessful"); 
    } 

또는 뭔가 다른 작업을 수행합니까?

답변

0

정확히 내 답변을 원한다는 것을 실제로 알지 못했기 때문에 내 질문이 내 능력의 최고로 책정되지 않았으므로 필자가 생각해 낸 해결책을 게시 할 것입니다. 이 마지막 날에.

먼저 저장소가 모든 데이터 기능을 처리합니다. 두 번째로, 내 저장소 메서드는 데이터 삽입이 성공했는지 여부를 true/false로 반환합니다 (예외가 아닌 데이터베이스에 삽입하는 데 문제가있을 수 있으며 일부 비즈니스 규칙은 실패 함). 셋째, 내 저장소 메서드는 출력 매개 변수를 통해 반환되는 보고서를 작성합니다.

이제 컨트롤러 액션 코드 :

// 
    // POST: /admin/post/import 
    [HttpPost] 
    public virtual ActionResult Import(HttpPostedFileBase fileToUpload) 
    { 
     string path = Server.MapPath("~/App_Data/Upload/") + Path.GetFileNameWithoutExtension(fileToUpload.FileName) + "-" + Guid.NewGuid() + Path.GetExtension(fileToUpload.FileName); 
     fileToUpload.SaveAs(path); 
     string report = string.Empty; 
     bool success = _repository.ImportPostcodes(path, out report); 
     TempData["ImportReport"] = report; 
     if (success) 
      return RedirectToAction(MVC.admin.Post.ActionNames.ImportSuccess); 
     else 
      return RedirectToAction(MVC.admin.Post.ActionNames.ImportFailed); 
    } 

그리고 이것은 저장소 인터페이스 :

public interface IPostCodeRepository 
{ 
    IApplicationState AppState { get; set; } 
    void Add(PostCode instance); 
    void Delete(PostCode instance); 
    void Delete(Guid rowGuid); 
    void Delete(string postalCode); 
    IQueryable<PostCode> GetAll(); 
    IQueryable<PostCode> GetAll(string query); 
    PostCode Load(Guid rowGuid); 
    PostCode Load(string postalCode); 
    void SaveChanges(); 
    void Update(PostCode instance); 
    bool ImportPostcodes(string path, out string report); 
} 

나는이 사람이 의견이있는 경우가 gets..but만큼 최적의 생각 내 손님이 되라.

0

try 블록 내부에있는 모든 로직을 모델 (또는 저장소)로 옮기는 것으로 시작합니다. 그것은 컨트롤러에 거의 남지 않을 것입니다 - 그리고 그것은 좋은 것입니다.

컨트롤러에 남겨 둘 수있는 유일한 논리는 사용자가 "성공"또는 "오류"페이지로 리디렉션되어야하는지 여부를 결정하는 if 블록입니다.

1

컨트롤러 작업 내의 SQL 쿼리와 DataRow? 오, no. 이 코드는 나에게 WebForms의 좋은 요일을 생각 나게합니다 .-) 정말로 putting your controllers on a diet이되어야합니다.

+0

이것은 의도적입니다.장소에 DI가있는 저장소가 있지만 한 POST 요청에 여러 항목을 삽입한다는 것을보다 분명하게 알리기 위해 게시했습니다. – mare

1

@Hector와 @Darin Dimitrov가 말했듯이 컨트롤러를 얇게 만들어야합니다.

은 귀하의 질문에 대답 " 핸들 예외 또는 거래에 작업을 실행?"하려면,
  • 예, 당신은 당신의 응용 프로그램이 부분적으로를 가져올 수없는 경우 트랜잭션에서 실행해야합니다. Unit Of WorkActionFilter을 사용할 수 있습니다.
  • 예외 처리? 나는 SomeSpecificExceptionExcelUtility.ReadFile 방법으로 올릴 수 있지만 이 아니라Exception 클래스로 올릴 수 있습니다. 그리고 응용 프로그램 요구 사항에 따라 예외적 인 사례 인을 정의해야합니다. HereScott Hanselman에 의한 예외 처리에 관한 the great blog post입니다.
관련 문제