2013-05-16 5 views
2

Elmah 로깅 오류가 있습니다. 오류는 전체 양식 게시물 정보를 저장합니다. URL을 통해 이러한 오류 및 XML 또는 JSON 표현에 액세스 할 수 있습니다. 디버깅하고 싶은 오류 중 상당수는 게시되고 이러한 오류를 재생산하는 것은 매우 어렵고 시간이 많이 걸립니다.elmah에 저장된 양식 데이터를 모델 객체로 직렬화합니다.

내가 원하는 것은 elmah 로그 정보를 사용하여 특정 작업을 수행하는 데 필요한 모델을 채우는 방법입니다. 그런 다음 단위 테스트에서이 모델을 사용하여 오류가 발생한 이유를 정확하게 확인할 수 있습니다.

지금까지 XML 및 JSON elamh 오류 정보로 모델을 파싱 해 보았습니다. 아래는 내가 JSON에서 구문 분석 뭘하려 :

MyModel model = ParseTo<MyModel>("Url of elmah json error"); 
public static T ParseTo<T>(string UrlOfJson) 
{ 
    string fullJsonString = string.Empty; 
    using(var webClient = new WebClient()) 
    { 
     fullJsonString = webClient.DownloadString(UrlOfJson); 
    } 

    JObject o = JObject.Parse(fullJsonString); 
    string inputString = o.SelectToken("form").ToString(); 

    return JsonConvert.DeserializeObject<T>(inputString); 
} 

이 거의 작동합니다. 거의 List 객체를 deserialize 할 수 없기 때문입니다.

public class MyModel 
{ 
    public int CustomerId { get; set; } 
    public List<Offer> Offers { get; set; } 
} 

public class Offer 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

...이 JSON : 다음과 같은 모델을 감안할 때

{ 
    "CustomerId": "4564", 
    "Offers[0].Id": "635", 
    "Offers[0].Name": "name1", 
    "Offers[1].Id": "636", 
    "Offers[1].Name": "name2", 
} 

... 파서는 ELMAH에 의해 저장 JSON 올바른 아니므로 Offers 속성을 직렬화 실패 그것을위한 형식. 기본 ModelBinder에서 이해할 수있는 형식이지만,이 Json에 대해 어떻게 실행할 수 있습니까?

어떻게하면 모델 객체에 Elamh가 저장 한 Json을 직렬화 할 수 있습니까?

+0

하지만 실제로는 FormCollection 키 - 값 쌍을 로그에 저장했습니다. 모델 자체가 아닙니다. 권리? – Nenad

+0

직접 데이터를 저장하지 않았습니다. 오류가 발생하면 Elmah는 양식 게시 정보를 로그 아웃합니다. 양식 정보는 본질적으로 모델 정보입니다. – Dmitry

답변

0

간단한 예 :

FormCollection form = ParseTo<FormCollection>("Url of elmah json error"); 
    var instance = new MyModel(); 
    UpdateModel<MyModel>(instance, form.ToValueProvider()); 

그래서, 기본적으로, 오직 첫번째 System.Web.Mvc.FormCollection에 JSON을 역 직렬화. 또는 NameValueCollection에있는 경우 FormCollection을 만들 수 있습니다. 그런 다음 MVC 바인딩을 트리거하면 모델이 생성됩니다.

이 스 니펫은 Controller.UpdateModel 메서드 (또는 TryUpdateModel)에 액세스 할 수 있도록 컨트롤러 동작 내부에 있어야합니다. 기본 MVC4 HomeController에서

+0

컨트롤러에 코드를 추가 할 수 없습니다. 질문에 설명 된 이유로 TestClass에서 필요합니다. 또한 질문에서 볼 수 있듯이, 중단 한 TODO 부분은 내가 가장 애를 먹고있는 부분입니다. – Dmitry

+0

유오 완전히 잘못 됐어. 당신은 단순히 deserialization 대상 클래스를 대체해야합니다. 그리고 그것은 MVC 모델 바인딩 형식이기 때문에 JSON이 아니라 MVC 모델 바인딩을 사용하여 객체를 생성해야합니다. 결국 ... 컨트롤러에서 먼저 시도하고 작동하게 한 다음 테스트 클래스로 재생하십시오. – Nenad

+0

나를 잃어 버렸습니다. 더 많은 코드를 제공 할 수 있다면 좋을 것입니다. 특히 테스트 클래스에 작성 될 수있는 코드. 나는 내가 많이 묻는 것을 이해하지만. – Dmitry

1

전체 작업 예 : 끝에

using System; 
using System.Collections.Generic; 
using System.Web.Mvc; 

namespace DefaultMvc4Application.Controllers 
{ 
    public class HomeController : Controller 
    { 
     public class MyModel 
     { 
      public int CustomerId { get; set; } 
      public List<Offer> Offers { get; set; } 
     } 

     public class Offer 
     { 
      public int Id { get; set; } 
      public string Name { get; set; } 
     } 

     public ActionResult Index() 
     { 
      string json = @"{ 
           ""CustomerId"": ""4564"", 
           ""Offers[0].Id"": ""635"", 
           ""Offers[0].Name"": ""name1"", 
           ""Offers[1].Id"": ""636"", 
           ""Offers[1].Name"": ""name2"", 
          }"; 
      var dict = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(json); 
      var form = new FormCollection(); 

      foreach (KeyValuePair<string, string> kvp in dict) 
       form.Add(kvp.Key, kvp.Value); 


      var model = new MyModel(); 
      UpdateModel<MyModel>(model, form); 

      return View(model); 
     } 
    } 
} 

가 제대로 채워 모델을 얻을.

+0

대단하군요! 도와 주셔서 감사합니다. 유일한 문제는'UpdateModel' 메소드가'Controller'를 상속받지 않는 클래스에서 사용 가능하지 않다는 것입니다. 그러므로 나는 Test에서 그것을 사용할 수 없다. 'FormCollection'을 Poco로 변환하는 방법을 찾아 보았지만 유용한 것은 찾을 수 없었습니다. – Dmitry

+1

UpdateModel은 MVC 인프라 (IModelBinder, ControllerContext, HttpContext 등)에 종속됩니다. "UnitTest"에 대해 많은 것을 조롱해야합니다. 그런 다음 사용자 지정 구성 (사용자 지정 모델 바인더, 등 ...)이 있으면 문제를 정확하게 재현 할 수 없습니다. 기본적으로 분리 된 UnitTest를 사용하여 엔드 투 엔드 실패를 재현하려는 경우가 정의에 따라 다릅니다. ("unit-test"데이터를로드하는 데 webClient를 사용하는 것은 말할 것도 없습니다) – Nenad

+0

내게 다행히도 내 사이트에는 사용자 정의 구성이 없습니다. 모델 바인더를 포함한 앞으로의 기본 설정을 계속 진행합니다. 양식에 너무 많은 입력이 있습니다. 나는 정의에 대해 신경 쓰지 않는다. 나는 단지 문제를 풀고 싶다. – Dmitry