我正在创建一个ASP.NET MVC3 restful Web服务,以允许从一组服务器上载报告。创建新报告时,我希望客户端应用程序执行PUT
将报告内容作为XML传递到请求正文中。
我的问题是:如何在控制器中访问报告的内容?我可以想象它在HttpContext.Request对象的某处可用,但我不愿意从我的控制器访问它,因为它不可能(?)进行单元测试。是否可以调整路由以允许将内容作为一个或多个参数传递到控制器方法中?结果需要是RESTful,即它必须PUT或POST到如上所述的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
}
}
我尝试PUT到URL的对象是:
public class Report
{
public int SuccessCount { get; set; }
public int FailureOneCount { get; set; }
public int FailureTwoCount { get; set; }
// Other stuff
}
This question看起来很相似,但没有任何答案。 提前致谢
答案 0 :(得分:1)
似乎你只需要使用标准的ASP.NET MVC model binding功能,并使用HTTP PUT而不是更常见的HTTP POST。这个article series有一些很好的样本,可以看看如何使用模型绑定。
您的控制器代码将如下所示:
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();