0

如果 AJAX 调用成功,我想返回一个简单的对象Success = true

public ActionResult Foo(int id)
{
    // ...
    return Json(new {Success=true});
}

这工作正常,我的 javascript 接收的对象看起来像

{ Success : true }  

但是因为返回的对象是匿名类型,所以我不能在我的测试中做(类似的事情)以下内容:

var result = (JsonResult)controller.AddNote(id, message);
dynamic data = result.Data;

// Assert
Assert.That(data.Success, Is.EqualTo(true));

所以我尝试返回一个 ExpandoObject ,它允许测试以我想要的方式工作,但是在 AJAX 响应中发送回的 JSON 是一团糟,如本问题所述。

[{"Key":"Success","Value":true}]

是否有一种简单、干净的方法来实现看起来应该很容易的事情,或者是在链接问题中实现一些自定义序列化的唯一方法?

4

2 回答 2

1
  1. 如果您dynamic使用[assembly: InternalsVisibleTo("TestsProject")]. 因为为匿名类型生成的类是内部的,并且运行时绑定不适用于内部类型。在本文中,您可以找到有关此的更多信息。
  2. 如果您不喜欢这种方法,您可以回退到普通的旧反射(隐藏在一些辅助方法后面):

    [TestMethod]
    public void AddNote1()
    {
        ...
        var result = ((JsonResult)controller.AddNote(id, message));
        var data = result.Data;
    
        // Assert
        Assert.AreEqual(Get<bool>(data, "Success"), true);
     }
    
     private T Get<T>(object instance, string propertyName)
     {
         return (T) instance.GetType().GetProperty(propertyName).GetValue(instance, null);
     }
    
  3. 使用命名类而不是匿名类。

  4. 正如您所提到的,您必须使用某种序列化解决方法。

于 2011-11-10T19:04:16.837 回答
0

你可以做的是:

var js = new JavaScriptSerializer();
var response = new { id = 0, Status = false };
dynamic object = js.Deserialize(new StringReader(JSONText), response.GetType());

Assert.IsTrue(object.Success)

这是做什么的:

  1. 创建一个 JavaScriptSerializer。
  2. 创建一个与您的 json 具有相同布局的新匿名对象,因此序列化程序知道您的对象是什么样的
  3. 将 json 反序列化为一个新的动态对象。

这样做的缺点是您的 json 对象上没有 IntelliSense,因此编译器不会捕获任何拼写错误。

注意:我这里的代码是用stackoverflow写的,所以可能会有一些小错误。我没有测试它,但它应该可以工作:P

于 2011-11-10T18:30:37.683 回答