Sim*_*ver 22 asp.net-mvc json design-patterns
JsonResult类是一种非常有用的方法,可以通过AJAX将Json作为动作返回给客户端.
public JsonResult JoinMailingList(string txtEmail)
{
// ...
return new JsonResult()
{
Data = new { foo = "123", success = true }
};
}
Run Code Online (Sandbox Code Playgroud)
然而(至少根据我的第一印象)这真的不是一个很好的分离关注点.
我想知道为什么对象和Json之间的转换没有通过属性以声明方式实现.在下面的代码中,您基本上告诉MVC this method is convertible to Json,然后如果从AJAX客户端调用它,则检查new JsonResult()内部执行转换的属性.
单元测试可以只采取动作结果(ObjectActionResult)并拉出强类型Foo.
[JsonConvertible]
public ActionResult JoinMailingList(string txtEmail)
{
// ...
return new ObjectActionResult()
{
Data = new Foo(123, true)
};
}
Run Code Online (Sandbox Code Playgroud)
我只是好奇人们的想法和任何可供选择的模式.
这些也只是我最初的观察 - 可能还有更多理由说明为什么这不是一个理想的设计(可能还有很多理由为什么它是一个完全可以接受和实用的设计!)我今晚只是感觉理论和魔鬼 - 拥护者.
*免责声明:我甚至没有开始考虑如何实施属性或者它可能具有哪些副作用或重复性等.
Fra*_*ger 10
我觉得你无所事事.那么如果控制器在其公共接口中知道JSON呢?
曾经有人告诉我:"让你的代码变得通用,不要让你的应用程序通用."
你在这里写一个应用程序控制器.应用程序控制器是可以的 - 它的职责是在模型和视图之间进行缓解并调用模型中的更改 - 以了解某个视图(JSON,HTML,PList,XML,YAML).
在我自己的项目中,我通常有类似的东西:
interface IFormatter {
ActionResult Format(object o);
}
class HtmlFormatter : IFormatter {
// ...
}
class JsonFormatter : IFormatter {
// ...
}
class PlistFormatter : IFormatter {
// ...
}
class XmlFormatter : IFormatter {
// ...
}
Run Code Online (Sandbox Code Playgroud)
基本上是"格式化程序",它接受对象并为它们提供不同的表示.HtmlFormatter如果对象实现,s甚至足够智能输出表IEnumerable.
现在,返回数据的控制器(或者可以使用HtmlFormatters 生成网站部分的控制器)采用"格式"参数:
public ActionResult JoinMailingList(string txtEmail, string format) {
// ...
return Formatter.For(format).Format(
new { foo = "123", success = true }
);
}
Run Code Online (Sandbox Code Playgroud)
您可以为单元测试添加"对象"格式化程序:
class ObjectFormatter : IFormatter {
ActionResult Format(object o) {
return new ObjectActionResult() {
Data = o
};
}
}
Run Code Online (Sandbox Code Playgroud)
使用此方法,您的任何查询/操作/过程/ ajax调用,无论您想要调用它们,都可以以各种格式输出.
我一般不要担心它.Asp.Net MVC足以解决问题,将泄漏降至最低.你是对的; 测试时有一点障碍.
这是我使用的测试助手,它运行良好:
protected static Dictionary<string, string> GetJsonProps(JsonResult result)
{
var properties = new Dictionary<string, string>();
if (result != null && result.Data != null)
{
object o = result.Data;
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(o))
properties.Add(prop.Name, prop.GetValue(o) as string);
}
return properties;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用Request.IsAjaxRequest()扩展方法返回不同的ActionResult类型:
if (this.Request != null && this.Request.IsAjaxRequest())
return Json(new { Message = "Success" });
else
return RedirectToAction("Some Action");
Run Code Online (Sandbox Code Playgroud)
注意:您需要Request!= null才能破坏您的测试.