【发布时间】:2016-04-10 03:37:51
【问题描述】:
我成功地从 Winforms 客户端调用 Web API 应用程序中的 POST 方法,该客户端为存储过程传递一些参数。
不过,如果可能的话,我希望通过 FromBody 功能将存储过程(我必须首先在客户端上运行)的结果传递给 POST 方法。
通过网络发送大量数据,但我现在这样做的方式是我必须运行 SP 两次 - 首先在客户端 Winforms 应用程序上,然后在 Web API 服务器应用程序上,然后同时调用这个 SP 似乎有时会引起一些问题。
所以,如果可行,我想通过“FromBody”发送数据表,或者如果更可取,发送数据的 XML 化或 json 化版本(然后在另一端解压,我将其转换为调用相应的 GET 方法时检索的 html。
有没有人有任何可以显示的代码?
可以看到我现有的仅通过参数的代码here。
更新
好的,根据 Amit Kumar Ghosh 的回答,我将代码更改为:
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new
HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.Add(new DataTableMediaTypeFormatter());
}
public class DataTableMediaTypeFormatter : BufferedMediaTypeFormatter
{
public DataTableMediaTypeFormatter()
: base()
{
SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("test/dt"));
}
public override object ReadFromStream(Type type, Stream readStream,
HttpContent content, IFormatterLogger formatterLogger, System.Threading.CancellationToken cancellationToken)
{
var data = new StreamReader(readStream).ReadToEnd();
var obj = JsonConvert.DeserializeObject<DataTable>(data);
return obj;
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
}
控制器
[Route("{unit}/{begindate}/{enddate}/{stringifiedjsondata}")]
[HttpPost]
public void Post(string unit, string begindate, string enddate, DataTable stringifiedjsondata)
{
DataTable dt = stringifiedjsondata;
. . .
客户
private async Task SaveProduceUsageFileOnServer(string beginMonth, string beginYear, string endMonth, string endYear)
{
string beginRange = String.Format("{0}{1}", beginYear, beginMonth);
string endRange = String.Format("{0}{1}", endYear, endMonth);
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:52194");
string dataAsJson = JsonConvert.SerializeObject(_rawAndCalcdDataAmalgamatedList, Formatting.Indented);
String uriToCall = String.Format("/api/produceusage/{0}/{1}/{2}/{3}", _unit, beginRange, endRange, @dataAsJson);
HttpResponseMessage response = await client.PostAsync(uriToCall, null);
}
...但是仍然没有到达控制器;具体来说,“DataTable dt = dtPassedAsJson;”中的断点永远达不到。
实际上,它并没有崩溃,这让我有点惊讶,因为正在传递一个字符串,但其中声明的数据类型是“DataTable”
更新 2
我也试过这个,在意识到它不是我从客户端传递的真正的字符串化/jsonized DataTable,而是一个字符串化/jsonized 通用列表之后:
WEB API 控制器
[Route("{unit}/{begindate}/{enddate}/{stringifiedjsondata}")]
[HttpPost]
public void Post(string unit, string begindate, string enddate, List<ProduceUsage> stringifiedjsondata)
{
List<ProduceUsage> _produceUsageList = stringifiedjsondata;
WebApiConfig.cs
我在注册方法中添加了这个:
config.Formatters.Add(new GenericProduceUsageListMediaTypeFormatter());
...还有这个新课程:
// adapted from DataTableMediaTypeFormatter above
public class GenericProduceUsageListMediaTypeFormatter : BufferedMediaTypeFormatter
{
public GenericProduceUsageListMediaTypeFormatter()
: base()
{
SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("test/dt"));
}
public override object ReadFromStream(Type type, Stream readStream,
HttpContent content, IFormatterLogger formatterLogger, System.Threading.CancellationToken cancellationToken)
{
var data = new StreamReader(readStream).ReadToEnd();
var obj = JsonConvert.DeserializeObject<List<ProduceUsage>>(data);
return obj;
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
}
不过,Controller 中的主要断点行仍然是:
List<ProduceUsage> _produceUsageList = stringifiedjsondata;
...未达到。
【问题讨论】:
-
您可以发送序列化的 json 字符串并在控制器处反序列化。
-
我认为这个难题的答案是 Hernan Guzman 在stackoverflow.com/questions/34639830/… 发布的内容
标签: c# winforms asp.net-web-api frombodyattribute