jus*_*eve 0 asp.net-mvc modelbinders
我有一个第三方应用程序向我的网站进行 POST 提交,正文中包含application/json 。我可以捕获强类型对象:
公共字符串回发([FromBody]MyResponse myResponse)
我的问题是,在完成这么多工作之后,我被指示在同一端点支持第二种类型。因此,我需要接受一个字符串值(而不是模型绑定器的结果),然后 JsonConvert 将该字符串转换为两种可能类型中的一种或另一种。
所以我想我应该将方法的签名更改为:
公共字符串回发([FromBody]字符串_sfResponse)
但该字符串始终显示为空(带或不带 [FromBody] 指令)。看来 ModelBinder 坚持要参与。无论如何要说服他不要这么做?
以防万一有关于路由的事情:
routes.MapRoute(
"MyPostback",
url: "rest/V1/sync/update",
defaults: new { controller = "Admin", action = "MyPostback" }
);
Run Code Online (Sandbox Code Playgroud)
控制器动作:
[System.Web.Mvc.HttpPost]
[System.Web.Mvc.AllowAnonymous]
public string MyPostback([System.Web.Http.FromBody][ModelBinder(typeof(MyResponseModelBinder))] MyResponseToProduct _sfResponse)
{
//stuff
}
Run Code Online (Sandbox Code Playgroud)
发送的 json 比平均值更复杂,但请记住,当控制器的签名引用与该 json 匹配的强类型对象时,一切正常。(重复一遍——我必须适应两种不同的传入类型,这就是为什么我需要在开头使用字符串而不是模型)。
{
"results": [
{
"errors": {
"error": "No Error"
},
"sku": "70BWUS193045G81",
"status": "success",
"productId": "123"
},
{
"errors": {
"error": "No Error"
},
"sku": "70BWUS193045G82",
"status": "success",
"productId": "123"
}
],
"validationType": "products",
"messageId": "ac5ed64f-2957-51b4-8fbb-838e0480e7ad"
}
Run Code Online (Sandbox Code Playgroud)
我添加了一个自定义模型绑定器,以便能够在控制器被击中之前查看值:
public class MyResponseModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
HttpRequestBase request = controllerContext.HttpContext.Request;
int id = Convert.ToInt32(request.Form.GetValues("Id"));
return new MyResponseToProduct()
{
results = new List<MyResponseToProduct.Result>()
};
}
}
Run Code Online (Sandbox Code Playgroud)
当我检查自定义模型绑定器中的值时,controllerContext.HttpContext.Request.Form 为空(这是 POST 提交,因此主体确实应该在那里,不是吗?)
我可以在bindingContext.PropertyMetadata中看到我的位数据,但我无法想象我应该走得那么深。
很奇怪为什么Request.Form是空的。
ASP.NET 核心:
您可以将控制器操作参数声明为object然后调用ToString()它,如下所示:
[HttpPost]
public IActionResult Foo([FromBody] object arg)
{
var str = arg?.ToString();
...
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,str变量将包含请求正文中的 JSON 字符串。
ASP.NET MVC:
由于前一个选项在旧的 ASP.Net MVC 中不起作用,因此您可以直接从Request控制器操作中的属性读取数据。以下扩展方法将帮助您:
public static string GetBody(this HttpRequestBase request)
{
var requestStream = request?.InputStream;
requestStream.Seek(0, System.IO.SeekOrigin.Begin);
using (var reader = new StreamReader(requestStream))
{
return reader.ReadToEnd();
}
}
Run Code Online (Sandbox Code Playgroud)
你的行动将如下所示:
[HttpPost]
[Route("test")]
public ActionResult Foo()
{
string json = Request.GetBody();
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2230 次 |
| 最近记录: |