如何通过FromBody将DataTable传递到Web API POST方法(C#) [英] How to pass DataTable via FromBody to Web API POST method (C#)

查看:83
本文介绍了如何通过FromBody将DataTable传递到Web API POST方法(C#)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经成功地从Winforms客户端中的Web API应用程序中调用了POST方法,该客户端方法为存储过程传递了一些参数.

I am successfully calling a POST method in a Web API app from a Winforms client that passes some parameters for a Stored Procedure.

但是,如果可能的话,我希望将存储过程的结果(必须首先在客户端上运行)通过FromBody功能传递给POST方法.

I would prefer, though, to pass the results of the Stored Procedure (which I have to run on the client first) to the POST method via the FromBody functionality, if possible.

要通过网络发送大量数据,但是我现在的方式是必须两次运行SP-首先在客户端Winforms应用程序上运行,然后在Web API服务器应用程序上运行,并同时进行调用该SP有时似乎会引起一些问题.

It's a lot of data to send over the wire, but the way I'm doing it now I have to run the SP twice - first on the client Winforms app, then on the Web API server app, and the simultaneous calling of this SP seems to sometimes cause some problems.

因此,我想在可行的情况下,通过"FromBody"发送DataTable,或者,如果可以的话,通过数据的XML化或jsonized版本发送DataTable(然后在另一端解压,将其转换为html,用于在调用相应的GET方法时进行检索.

So, I'd like to, if feasible, either send the DataTable via "FromBody" or, if preferable, an XMLized or jsonized version of the data (and then unpack it on the other end, where I convert it into html for retrieval when the corresponding GET method is called.

有人可以显示此代码吗?

Does anybody have any code that does this that they could display?

可以看到我刚刚通过参数的现有代码

My existing code that just passes the params can be seen here.

好的,根据阿米特·库玛·戈什(Amit Kumar Ghosh)的回答,我将代码更改为:

Okay,based on Amit Kumar Ghosh's answer, I changed my code to this:

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;
    }
}

CONTROLLER

[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;"中的断点永远不会到达.

...but the Controller is still not reached; specifically, the breakpoint in "DataTable dt = dtPassedAsJson;" is never reached.

实际上,当传递字符串时,它不会崩溃,这让我感到惊讶,但在那里声明的数据类型是"DataTable"

Actually, it kind of surprises me that it doesn't crash, as a string is being passed, yet the data type there declared is "DataTable"

我也尝试过这一点,在意识到它不是我从客户端传递来的不是经过字符串化/jsonized的DataTable,而是经过字符串化/jsonized的通用列表:

I also tried this, after realizing it's not really a stringified/jsonized DataTable that I'm passing from the client, but a stringified/jsonized generic list:

[Route("{unit}/{begindate}/{enddate}/{stringifiedjsondata}")]
[HttpPost]
public void Post(string unit, string begindate, string enddate, List<ProduceUsage> stringifiedjsondata)
{
    List<ProduceUsage> _produceUsageList = stringifiedjsondata;

WebApiConfig.cs

我将此添加到了Register方法:

WebApiConfig.cs

I added this to the Register method:

config.Formatters.Add(new GenericProduceUsageListMediaTypeFormatter());

...以及这个新类:

...and this new class:

// 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中的主要断点行:

Still, though, the main breakpointed line in the Controller:

List<ProduceUsage> _produceUsageList = stringifiedjsondata;

...未达到.

推荐答案

请参阅Hernan Guzman的答案

See Hernan Guzman's answer here.

基本上,您必须在服务器上的方法中添加"[FromBody]",然后传递来自客户端的数据,并将其添加到URL参数之后.

Basically, you have to add "[FromBody]" to the method on the server, and then pass the data from the client, adding it after the URL param.

这篇关于如何通过FromBody将DataTable传递到Web API POST方法(C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆