Asp.net mvc 3 MVC3 REST服务-如何访问PUT或POST请求的请求正文内容?

Asp.net mvc 3 MVC3 REST服务-如何访问PUT或POST请求的请求正文内容?,asp.net-mvc-3,rest,request,Asp.net Mvc 3,Rest,Request,我正在创建一个ASP.NET MVC3 restful web服务,以允许从一组服务器上载报告。创建新报告时,我希望客户端应用程序执行PUT to 在请求主体中以XML形式传递报告内容 我的问题是:如何在控制器中访问报告的内容?我可以想象它在HttpContext.Request对象中的某个地方是可用的,但是我不愿意从我的控制器访问它,因为不可能(?)对它进行单元测试。是否可以调整路由以允许内容作为一个或多个参数传递到控制器方法中?结果需要是RESTful的,也就是说,它必须放置或发布到类

我正在创建一个ASP.NET MVC3 restful web服务,以允许从一组服务器上载报告。创建新报告时,我希望客户端应用程序执行PUT to

在请求主体中以XML形式传递报告内容

我的问题是:如何在控制器中访问报告的内容?我可以想象它在HttpContext.Request对象中的某个地方是可用的,但是我不愿意从我的控制器访问它,因为不可能(?)对它进行单元测试。是否可以调整路由以允许内容作为一个或多个参数传递到控制器方法中?结果需要是RESTful的,也就是说,它必须放置或发布到类似上面的URL

目前我的路线是:

routes.MapRoute(
    "SaveReport",
    "Servers/{serverName}/Reports/{reportTime",
    new { controller = "Reports", action = "Put" },
    new { httpMethod = new HttpMethodConstraint("PUT") });
有没有任何方法可以修改它以将内容从HTTP请求主体传递到控制器方法? 控制器方法当前为:

public class ReportsController : Controller
{
    [HttpPut]
    public ActionResult Put(string serverName, string reportTime)
    {
        // Code here to decode and save the report
    }
}
我试图将对象放入URL的对象是:

public class Report
{
    public int SuccessCount { get; set; }
    public int FailureOneCount { get; set; }
    public int FailureTwoCount { get; set; }
    // Other stuff
}
看起来很相似,但没有任何答案。
“提前感谢”

似乎您只需要使用标准功能,而不需要使用更常见的HTTP POST。这有一些很好的示例来了解如何使用模型绑定

您的控制器代码如下所示:

public class ReportsController : Controller
{
    [HttpPut]
    public ActionResult Put(Report report, string serverName, string reportTime)
    {
        if (ModelState.IsValid)
        {
            // Do biz logic and return appropriate view
        }
        else
        {
            // Return invalid request handling "view"
        }
    }
}
编辑:======================>>

Jon将此代码添加到他的注释中作为修复的一部分,因此我将其添加到其他人的答案中:

创建自定义ModelBinder:

public class ReportModelBinder : IModelBinder
{
    public object BindModel(
        ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        var xs = new XmlSerializer(typeof(Report));
        return (Report)xs.Deserialize(
            controllerContext.HttpContext.Request.InputStream);
    }
}
修改Global.asax.cs以根据报告类型注册此模型绑定器:

ModelBinders.Binders[typeof(Report)] = new Models.ReportModelBinder();

似乎您只需要使用标准功能,而不需要使用更常见的HTTP POST。这有一些很好的示例来了解如何使用模型绑定

您的控制器代码如下所示:

public class ReportsController : Controller
{
    [HttpPut]
    public ActionResult Put(Report report, string serverName, string reportTime)
    {
        if (ModelState.IsValid)
        {
            // Do biz logic and return appropriate view
        }
        else
        {
            // Return invalid request handling "view"
        }
    }
}
编辑:======================>>

Jon将此代码添加到他的注释中作为修复的一部分,因此我将其添加到其他人的答案中:

创建自定义ModelBinder:

public class ReportModelBinder : IModelBinder
{
    public object BindModel(
        ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        var xs = new XmlSerializer(typeof(Report));
        return (Report)xs.Deserialize(
            controllerContext.HttpContext.Request.InputStream);
    }
}
修改Global.asax.cs以根据报告类型注册此模型绑定器:

ModelBinders.Binders[typeof(Report)] = new Models.ReportModelBinder();

谢谢你。这足以让我停止搅动,让我朝着正确的方向前进。您的建议也对我有所帮助。我将报告添加到控制器方法签名中,然后创建了自定义ModelBinder:public类ReportModelBinder:IModelBinder{public object BindModel(ControllerContext ControllerContext,ModelBindingContext bindingContext){var xs=new XmlSerializer(typeof(Report));return(Report)xs.Deserialize(controllerContext.HttpContext.Request.InputStream);}}}最后,我修改了Global.asax.cs以根据报告类型注册此模型绑定器:ModelBinders.Binders[typeof(Report)]=new Models.ReportModelBinder();谢谢Sixto。这足以停止我的搅动,让我朝着正确的方向前进。你的建议也让我明白了这一点。我将报告添加到控制器方法签名中,然后创建了自定义ModelBinder:public类ReportModelBinder:IModelBinder{public object BindModel(ControllerContext ControllerContext,ModelBindingContext bindingContext){var xs=new XmlSerializer(typeof(Report));返回(Report)xs.Deserialize(ControllerContext.HttpContext.Request.InputStream);}最后,我修改了Global.asax.cs以根据报告类型注册此模型绑定器:ModelBinders.Binders[typeof(Report)]=new Models.ReportModelBinder();