序列化保存在elmah日志中的表单数据到模型对象中

时间:2013-05-16 21:36:51

标签: asp.net-mvc model-binding elmah

我有Elmah记录错误。错误保存完整的表单发布信息。我可以通过URL访问这些错误及其XML或JSON表示。我想要调试的一些错误会发布很多值,并且重现这些错误非常困难且耗时。

我想要的是一种使用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对象。

鉴于以下模型:

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",
}

...解析器无法序列化Offers属性,因为Elmah保存的Json格式不正确。它的格式是默认的ModelBinder,但是如何针对这个Json运行呢?

我是如何将Elamh保存的Json序列化为模型对象的?

2 个答案:

答案 0 :(得分:1)

默认MVC4 HomeController中的完整工作示例:

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);
        }
    }
}

最后,您将获得正确填充的模型。

答案 1 :(得分:0)

简化示例:

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

所以,基本上,首先只将JSON反序列化为System.Web.Mvc.FormCollection。或者在NameValueCollection中,您可以从那里创建FormCollection。然后,触发MVC绑定,您将获得您的模型。

此代码段应位于控制器操作内,以便您可以访问Controller.UpdateModel方法(或TryUpdateModel)。