C# ResrSharp将复杂模型发送到可以通过FromForm读取的API
我在ASP.NET Core 2.2 WebAPI中有一个非常简单的方法:C# ResrSharp将复杂模型发送到可以通过FromForm读取的API,c#,.net,asp.net-core,restsharp,C#,.net,Asp.net Core,Restsharp,我在ASP.NET Core 2.2 WebAPI中有一个非常简单的方法: [HttpPut] public async Task<IActionResult> Put([FromForm] SimpleRequest request, [FromForm] string param1) { if (request.ExtraData == null) return BadRequest("Please send data"); await Task.Complete
[HttpPut]
public async Task<IActionResult> Put([FromForm] SimpleRequest request, [FromForm] string param1)
{
if (request.ExtraData == null) return BadRequest("Please send data");
await Task.CompletedTask;
return Ok("Works");
}
当我向邮递员发出请求时,我的模型已正确绑定:
现在,我尝试使用RestSharp创建相同的。当我使用以下代码时,它工作正常:
var client = new RestClient("https://localhost:44325/api/values");
var request = new RestRequest(Method.PUT);
request.AddParameter("UserId", "Sample", ParameterType.GetOrPost);
request.AddParameter("RequestType", "Simple", ParameterType.GetOrPost);
request.AddParameter("Timestamp", DateTime.Now, ParameterType.GetOrPost);
request.AddParameter("Test", true, ParameterType.GetOrPost);
request.AddParameter("ExtraData.FirstName", "John", ParameterType.GetOrPost);
request.AddParameter("ExtraData.LastName", "Smith", ParameterType.GetOrPost);
request.AddParameter("ExtraData.Id", 1234, ParameterType.GetOrPost);
request.AddParameter("ExtraData.Nr", 1, ParameterType.GetOrPost);
request.AddParameter("ExtraData.RDate", DateTime.Now.AddDays(-2), ParameterType.GetOrPost);
request.AddParameter("param1", "YES", ParameterType.GetOrPost);
var response = client.Execute(request);
但是我想重用我的模型,因为它们在单独的DLL中共享
我创建的模型如下所示:
var model = new SimpleRequest
{
UserId = "Sample",
RequestType = RequestType.Simple,
Timestamp = DateTime.Now,
Test = true,
ExtraData = new ExtraData
{
FirstName = "John",
LastName = "Smith",
Id = 1234,
Nr = 1,
RDate = DateTime.Now.AddDays(-2)
}
};
但我无法通过请求传递此模型,以便它可以正确地反序列化到我的对象。
我尝试过使用request.AddJsonBody
,但失败了
通过RestSharp传递上述模型的正确方法是什么?
我应该如何序列化它(或添加为参数)以使其工作。对于
FromForm
,我们需要通过表单数据
或x-www-form-urlencoded
发送请求。您可以实现自己的方式将模型转换为x-www-form-urlencoded
,如:
public static class RestSharpExtension
{
public static IDictionary<string, string> ToKeyValue(this object metaToken)
{
if (metaToken == null)
{
return null;
}
JToken token = metaToken as JToken;
if (token == null)
{
return ToKeyValue(JObject.FromObject(metaToken));
}
if (token.HasValues)
{
var contentData = new Dictionary<string, string>();
foreach (var child in token.Children().ToList())
{
var childContent = child.ToKeyValue();
if (childContent != null)
{
contentData = contentData.Concat(childContent)
.ToDictionary(k => k.Key, v => v.Value);
}
}
return contentData;
}
var jValue = token as JValue;
if (jValue?.Value == null)
{
return null;
}
var value = jValue?.Type == JTokenType.Date ?
jValue?.ToString("o", CultureInfo.InvariantCulture) :
jValue?.ToString(CultureInfo.InvariantCulture);
return new Dictionary<string, string> { { token.Path, value } };
}
}
公共静态类扩展
{
公共静态IDictionary ToKeyValue(此对象元令牌)
{
if(metaToken==null)
{
返回null;
}
JToken token=作为JToken的元令牌;
if(标记==null)
{
返回ToKeyValue(JObject.FromObject(metaToken));
}
if(token.HasValues)
{
var contentData=new Dictionary();
foreach(token.Children().ToList()中的var child)
{
var childContent=child.ToKeyValue();
if(childContent!=null)
{
contentData=contentData.Concat(childContent)
.ToDictionary(k=>k.Key,v=>v.Value);
}
}
返回内容数据;
}
var jValue=标记为jValue;
if(jValue?.Value==null)
{
返回null;
}
var value=jValue?.Type==JTokenType.Date?
jValue?.ToString(“o”,CultureInfo.InvariantCulture):
jValue?.ToString(CultureInfo.InvariantCulture);
返回新字典{{token.Path,value}};
}
}
public async Task<IActionResult> Index()
{
var model = new SimpleRequest
{
UserId = "Sample",
RequestType = RequestType.Simple,
Timestamp = DateTime.Now,
Test = true,
ExtraData = new ExtraData
{
FirstName = "John",
LastName = "Smith",
Id = 1234,
Nr = 1,
RDate = DateTime.Now.AddDays(-2)
}
};
var keyValueContent = model.ToKeyValue();
keyValueContent.Add("param1", "YES");
var formUrlEncodedContent = new FormUrlEncodedContent(keyValueContent);
var urlEncodedString = await formUrlEncodedContent.ReadAsStringAsync();
var client = new RestClient("http://localhost:51420/api/values/Put");
var request = new RestRequest(Method.PUT);
request.AddParameter("application/x-www-form-urlencoded", urlEncodedString, ParameterType.RequestBody);
var response = client.Execute(request);
}
公共异步任务索引()
{
var模型=新的SimpleRequest
{
UserId=“Sample”,
RequestType=RequestType.Simple,
时间戳=日期时间。现在,
测试=真,
ExtraData=新的ExtraData
{
FirstName=“约翰”,
LastName=“史密斯”,
Id=1234,
Nr=1,
RDate=DateTime.Now.AddDays(-2)
}
};
var keyValueContent=model.ToKeyValue();
添加(“参数1”、“是”);
var formUrlEncodedContent=新formUrlEncodedContent(keyValueContent);
var urlEncodedString=wait formUrlEncodedContent.ReadAsStringAsync();
var client=新的RestClient(“http://localhost:51420/api/values/Put");
var请求=新的重新请求(Method.PUT);
request.AddParameter(“application/x-www-form-urlencoded”,urlEncodedString,ParameterType.RequestBody);
var response=client.Execute(请求);
}
您还需要共享有问题的代码。您所说的
失败是什么意思?你有什么错误吗?不要使用FromForm
尝试使用FromBody
@ChetanRanpariya by fails,我的意思是我在Put方法中得到空的request
和param1
。问题是我无法更改此属性。上面的代码只是为了说明我的问题,真正的代码更复杂,并且已经部署好了。我需要为已经在工作的API创建一个客户端。API希望有效负载以形式
属性而不是作为请求主体发送。因此,您不能将负载作为JSON请求主体发送。您只需要通过查询字符串发送所有数据。如果希望能够将负载作为JSON主体发送,则API需要更改其行为。和不是您问题的答案,但它们将帮助您理解API客户端在这里做不了什么。@ChetanRanpariya所以我的问题应该是如何将我的模型“转换”为FormData(查询字符串)这是否可能(内置)通过RestSharp?工作得很好。非常感谢。这应该是内置的功能。我认为我的用例是有效的,我不仅想重用模型。
public async Task<IActionResult> Index()
{
var model = new SimpleRequest
{
UserId = "Sample",
RequestType = RequestType.Simple,
Timestamp = DateTime.Now,
Test = true,
ExtraData = new ExtraData
{
FirstName = "John",
LastName = "Smith",
Id = 1234,
Nr = 1,
RDate = DateTime.Now.AddDays(-2)
}
};
var keyValueContent = model.ToKeyValue();
keyValueContent.Add("param1", "YES");
var formUrlEncodedContent = new FormUrlEncodedContent(keyValueContent);
var urlEncodedString = await formUrlEncodedContent.ReadAsStringAsync();
var client = new RestClient("http://localhost:51420/api/values/Put");
var request = new RestRequest(Method.PUT);
request.AddParameter("application/x-www-form-urlencoded", urlEncodedString, ParameterType.RequestBody);
var response = client.Execute(request);
}