如何从Javascript传递json对象到asp.net mvc控制器

5

我刚刚开始学习MVC,有很多困惑。

当我们在ASP.NET WebForm项目中用jQuery调用服务器端函数时,该方法必须是静态的,并且必须使用WebMethod属性进行修饰。那么我想知道,在MVC的情况下是否适用相同的规则。

我找到了相关代码,但还没有测试它。

客户端方法

function getTradeContribs(id,pfid, nodedates) {

    var data = {};
    data.portfolioId = pfid;
    data.nodedates = nodedates;

    $.ajax({
            type: "POST",
            url: "/Portfolios/getTradeContribs/"+id,
            dataType: "json",
            data: JSON.stringify(data),
            contentType: "application/json; charset=utf-8",
            success: parseTradeContribs,
            error: function (error) {
                    alert("failed in opening XML file !!!");
            }
    });
   }

服务器端方法

public string getTradeContribs(int id,string portfolioId, string nodedates)
{
    string jsonTest = @" {""nodedates"": ""date"":""01/01/2012""}";
    return jsonTest;
}

从上面的代码中我有一些问题 1)MVC中有多少种类型的控制器方法? 2)url:"/Portfolios/getTradeContribs",这是什么样的URL。 Portfolios是控制器名称,getTradeContribs是操作名称吗? 如果不是,那么getTradeContribs是什么类型的方法。
3)为什么getTradeContribs没有返回ActionResult? 4)ActionResult的意义是什么? 5)为什么id作为查询字符串传递,而其余数据作为JSON传递。 它如何工作?
请讨论这些问题,因为我是MVC新手。

在开始尝试新技术/框架之前,您应该先了解该技术/框架的基础知识。请不要把这个论坛当作学习基础知识的替代品。因此,我会给您的问题打下降级标记。 - Scorpion-Prince
@Scorpion-Prince的3673次浏览和不断增加的数量表明这可能是一个有用的问题。即使对于OP来说不是复习,复习也不是邪恶的。 - ruffin
2个回答

7
每当我们在ASP.NET WebForm项目中通过jQuery调用任何服务器端函数时,该方法必须是静态的并且必须使用WebMethod属性进行装饰。那么我想知道,在MVC中是否适用相同的规则。
不完全一样。ASP.NET MVC是一种完全不同的模式。在ASP.NET MVC中,您使用控制器操作返回操作结果(从ActionResult派生的类)。因此,如果您想返回JSON,则只需定义一个控制器操作,该操作返回JsonResult并将模型传递给它即可:
public ActionResult GetTradeContribs(int id, string portfolioId, string nodedates)
{
    var model = new 
    {
        nodedates = "foo",
        date = DateTime.Now
    };
    return Json(model, JsonRequestBehavior.AllowGet);
}

或者更好的定义视图模型:

public class TradeContribsRequestViewModel
{
    public int Id { get; set; }
    public string PortfolioId { get; set; }
    public string NodeDates { get; set; }
}

public class TradeContribsViewModel
{
    public string NodeDates { get; set; }
    public DateTime Date { get; set; }
}

接下来:

public ActionResult GetTradeContribs(TradeContribsRequestViewModel request)
{
    var model = new TradeContribsViewModel
    {
        NodeDates = "foo",
        Date = DateTime.Now
    };
    return Json(model, JsonRequestBehavior.AllowGet);
}

ASP.NET MVC会自动将模型序列化为JSON字符串并传递给视图。然后,您可以使用ajax调用它:

$.ajax({
    url: '@Url.Action("GetTradeContribs", "Portfolios")',
    type: 'POST',
    data: { 
        id: 123, 
        portfolioId: 'some id', 
        nodedates: 'some node dates' 
    },
    success: function(result) {
        // You could directly use the properties of the result object here
        // like for example: alert(result.nodedates);
    }
});

您绝不能像在原始的getTradeContribs方法中一样硬编码JSON。这是基础设施管道,已经由框架为您处理了。您需要关心的仅仅是定义:

  • 一个返回ActionResult的控制器动作
  • 一个控制器动作将传递给视图的模型类型
  • 一个视图

我不理解这行代码 url: '@Url.Action("GetTradeContribs", "Portfolios")',Portfolios是什么? - Thomas
Url.Action助手使用您的路由配置来发出URL。第一个参数是操作名称,第二个参数是控制器名称。因此,如果您使用默认路由,则@Url.Action("GetTradeContribs", "Portfolios")将发出/Portfolios/GetTradeContribs。此外,当您在IIS中部署应用程序时,助手将考虑虚拟目录名称并生成/AppName/Portfolios/GetTradeContribs,这是此情况下的正确URL。因此,您应始终在ASP.NET MVC中使用URL助手,而不要像您在示例中所做的那样硬编码它们。 - Darin Dimitrov

2
以下是您的问题的一些答案:
  1. 在MVC中有多少种类型的控制器方法存在 - 不确定您的意思。可以通过路由URL访问的控制器中的方法称为控制器操作方法。这些方法使用ASP.net MVC应用程序的Global.asax文件中的RouteConfig类进行映射。
  2. url:“/ Portfolios / getTradeContribs”,这是什么样的url - 这些是restful URL。MVC框架将这些URL映射到控制器内的特定方法(Controller Actions)。请查看asp.net mvc网站以了解MVC的基础知识。
  3. getTradeContribs未返回ActionResult,为什么 - 不必从控制器操作返回ActionResult。 MVC框架提供了一些ActionResults-例如ViewResult(用于显示视图),JsonResult(返回JSON对象)等。在这种情况下,您可以返回字符串或JsonResult。通过返回字符串,客户端脚本需要将其解析为JSON对象,如果返回JsonResult,则客户端脚本将具有填充的JSON对象可供使用。
  4. ActionResult的意义 - ActionResult是一个抽象基类,它将控制器操作的结果转换为各种格式(HTML、JSON、XML等)。它只是一种轻松的方式来呈现控制器操作的结果,或者在您的情况下将结果传递回客户端。
  5. 为什么ID作为查询字符串传递,而其余数据作为JSON。它将如何工作 - ASP.Net MVC框架有一个称为Model Binder的组件,当调用操作方法时,它将尝试将通过查询字符串和表单提交值传递的值绑定到方法中的参数。如果您想要更改用于将值绑定到参数的逻辑,则可以插入自己的Modelbinder。
希望这些回答了您的问题。但是,在开始使用技术之前,应该学习该技术/框架的基础知识。请不要将此论坛视为学习基础知识的替代品。因此,我会降低您的问题等级。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接