美好的一天!

我正在开发一个ASP.NET Web API 2项目.在某一点上,需要上传一些文件.文件需要链接到某个FileModel(我们自己的类).因此,客户端需要将IEnumerable作为参数和文件作为内容发送.因为它是一个RESTful API,所以必须在同一请求中发送.

我们可以想出最好的是控制器操作:

public async Task<HttpResponseMessage> Add([FromUri] IEnumerable<FileModel> fileModels)
{
   // REQUEST INTEGRITY TESTING

   var streamProvider = new CustomMultipartFormDataStreamProvider(fileSavePath,fileModels);
   // Read the MIME multipart content using the stream provider we just created.
   var work = await Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(async t =>
        {
            // SOME WORK DONE AFTER SAVING THE FILES TO THE HARD DRIVE
        }

}

问题是:文件正在使用“multipart / form-data”Content-Type头文件上传.在操作服务器端的文件之前,我们需要知道FileModels的内容.如果我们使用MultipartFormDataStreamProvider,我们只能在文件已经保存到硬盘驱动器后才能访问非文件参数.

我们可以找到的唯一解决方法是发送IEnumerable< FileModel>参数在URL中.但是鉴于URL的最大长度有限,这不是一个可靠的方法.

问题是:有没有办法提交IEnumerable< FileModel> fileModels参数和请求正文中的文件,并在访问文件之前访问fileModels参数?我们也希望能够使用HttpContext.Current.Request.Files.Count;

我们目前的jQuery文件上传看起来像这样(为了早期测试的目的,它只支持一个文件上传):

$('#Upload').click(function(e) {
            e.preventDefault();

            var headers = new Array();
            headers["SessionId"] = sessionId;

            var files = $('#fileInput').get(0).files;
            var formData = new FormData();
            formData.append("files",files[0]);

            var fileModel = $('#fileSubmission').serialize();

            $.ajax({
                url: "api/Submissions/Add/?" + fileModel,headers: headers,type: 'POST',data: formData,cache: false,contentType: false,processData: false,dataType: 'json'
            });
        });

非常感谢你!

解决方法

对于迟到的答案我很抱歉,但是我们解决了这个问题(我忘了我没有在这里上传答案).基本上我们所做的就是在临时位置调用ReadAsMultiPartAsync方法,然后从请求中提取出其他参数.之后,我们验证了输入并将文件从临时移动到永久位置.

如果你想看到代码,这对我们的例子是有效的,我相信它很简单,以适应任何工作情况:

在客户端,我们有以下形式(是的,这个实现是为了演示目的,只支持发送一个文件…也是,输入type =“file”字段确实在窗体之外; fileId文本输入是在我们的案例中手动完成,仅用于测试目的)

<input type="file" name="data" id="fileInput" multiple="multiple" />

<form id="fileSubmission">            
    <input type="text" width="10" onchange="getFileDetails()" autocomplete="off" placeholder="FileId" name="files[0].Id" id="fileId" /> 
    <input type="hidden" name="files[0].FileName" id="FileName"/>
    <input type="hidden" name="files[0].Extension" id="Extension"/>
    <input type="hidden" name="files[0].EntityId" id="EntityId"/>
    <br /><br />
    <input type="submit" id="Upload" value="Upload" />
</form>

其中getFileDetails()填充其他输入字段.此外,表单通过使用以下jQuery / Javascript发送到服务器:

$('#Upload').click(function(e) {
            e.preventDefault();

            var courseId = $('#courseId').val();
            var fileId = $('#fileId').val();
            if (!courseId || !fileId) {
                return;
            }

            var headers = new Array();
            headers["SessionId"] = sessionId;
            headers["contentType"] = "application/json; charset=UTF-8";

            var formData = new FormData();
            var opmlFile = $('#fileInput').get(0).files;

            // this is like the model we're expecting on the server
            var files = [];
            files.push({ 'Id': $('#fileId').val(),'OriginalFileName': opmlFile[0].name,'FileName': $('#FileName').val(),'Extension': $('#Extension').val(),'EntityId': $('#EntityId').val() });

            formData.append("fileModels",JSON.stringify(files));
            formData.append("File_0",opmlFile[0]);


            $.ajax({
                url: "api/Courses/" + courseId + "/Submissions/Add/",dataType: 'json'
            });
        });

在服务器端,我们有以下几个:

// POST: api/Courses/{courseId}/Submissions/Add
[HttpPost]
[ValidateModelState]
[ValidateMimeMultipartContent]
[PermissionsAuthorize(CoursePermissions.CanCreateSubmissions)]
public async Task<HttpResponseMessage> Add(int courseId)
    {
        // the same as in the jQuery part
        const string paramName = "fileModels";

        // Put the files in a temporary location
        // this way we call ReadAsMultiPartAsync and we get access to the other data submitted
        var tempPath = HttpContext.Current.Server.MapPath("~/App_Data/Temp/" + Guid.NewGuid());
        Directory.CreateDirectory(tempPath);

        var streamProvider = new MultipartFormDataStreamProvider(tempPath);
        var readResult = await Request.Content.ReadAsMultipartAsync(streamProvider);

        if (readResult.FormData[paramName] == null)
        {
            // We don't have the FileModels ... delete the TempFiles and return BadRequest
            Directory.Delete(tempPath,true);
            return Request.CreateResponse(HttpStatusCode.BadRequest);
        }

        // The files have been successfully saved in a TempLocation and the FileModels are not null
        // Validate that everything else is fine with this command
        var fileModels = JsonConvert.DeserializeObject<IEnumerable<FileModelExtension>>(readResult.FormData[paramName]).ToList();

        // AT THIS POINT,ON THE SERVER,WE HAVE ALL THE FILE MODELS 
        // AND ALL THE FILES ARE SAVED IN A TEMPORARY LOCATION

        // NEXT STEPS ARE VALIDATION OF THE INPUT AND THEN 
        // MOVING THE FILE FROM THE TEMP TO THE PERMANENT LOCATION

        // YOU CAN ACCESS THE INFO ABOUT THE FILES LIKE THIS:
        foreach (var tempFile in readResult.FileData)
            {
                var originalFileName = tempFile.Headers.Contentdisposition.FileName.Replace("\"",string.Empty);

                var localTempPath = tempFile.LocalFileName;
            }

    }

我希望这将帮助任何人尝试通过使用Post请求一次提交文件和其他参数到服务器!

总结

以上是DEVMAX为你收集整理的c# – 如何将文件上传到Web API服务器并发送参数?全部内容。

如果觉得DEVMAX网站内容还不错,欢迎将DEVMAX网站推荐给好友。

c# – 如何将文件上传到Web API服务器并发送参数?的更多相关文章

  1. ios – 为什么Web Inspector向我显示“无检查应用程序”?

    什么可能是一个可能的原因,什么可以解决?解决方法我有同样的问题,这是因为我正在运行iOS8,通过将Safari更新到7.1来修复.

  2. Swift Web 开发之 Vapor - 入门一

    简介Vapor是一个基于纯Swift构建出的Web开发框架,目前可以运行在macOS和Ubuntu,用于构建出漂亮易用的网站或者API服务。组件VaporAuthSessionsCookiesRoutingVaporToolBoxFluentEngineHTTPURIWebSocketsSMTPLeafJSONConsoleTLSCryptoNodeSocksVapor使用SwiftPackageManager做依赖和包管理,不过以我个人目前的使用感受来看SwiftPackageManager还不是很好用

  3. Swift Web 开发之 Vapor - 模版 Leaf三

    Leaf作为Vapor官方提供的组件之一原生集成在Vapor中,Leaf模版文件以.leaf结尾,模版语法夹杂在HTML之间,我们可以直接使用而不需要引入其他外部依赖。#import()用来声明一个插入点在当前模版。这是[SwiftWeb开发之Vapor]系列的第三篇,说了说Vapor中自带的Leaf模版引擎,按照笔者目前的使用情况来看其实Leaf还不太成熟,虽然还有太多需要优化改进的地方,不过我相信之后一定会越来越好的。所以不要害怕,赶紧来写SwiftServerSide吧!

  4. android – 使用OkHttp或Retrofit将文件上传到AWS S3存储桶

    是否有使用Square的OkHttp库或Retrofit库将文件上传到S3存储桶的示例?我正在寻找一些示例,我可以使用预先签名的查询使用这些库上传文件.解决方法我或多或少地从一些预生产代码中复制了这个:

  5. android – Facebook Javascript SDK和Phonegap URL错误

    我目前正在尝试使用android应用程序中的phonegap开发facebook登录功能.我已经完成了所有必要的安装,并为我放在facebook上的应用程序生成了一个哈希键,但是我一直收到以下错误:GivenURLisnotallowedbytheApplicationconfiguration.:OneormoreofthegivenURLsisnotallowedbytheApp’ssetti

  6. android – 在Internet上发布我的RESTful Web服务

    什么是最好的方法?例如,我可以使用AmazonWebServices或ApacheHTTPServer吗?

  7. android – GoogleJsonResponseException:404 Not Found使用谷歌应用程序端点引擎后端

    我按照下面的教程.https://developers.google.com/eclipse/docs/running_and_debugging_2_0它基本上为我现有的应用程序添加了GAE后端.然后,我尝试下面的示例,在本地开发服务器上运行它,然后我得到下面发生的异常叫做.我的代码如下.解决方法导致此问题的另一个可能原因是未在appengine-web.xml中设置正确的application

  8. NodeJS使用formidable实现文件上传

    这篇文章主要为大家详细介绍了NodeJS使用formidable实现文件上传的相关方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. jQuery文件上传控件 Uploadify 详解

    本文主要介绍jQuery文件上传控件 Uploadify的用法,原作者做了非常详细的备注,有需要的朋友可以参考一下。

  10. spring boot实现文件上传

    这篇文章主要为大家详细介绍了spring boot实现文件上传,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

随机推荐

  1. c# – (wpf)Application.Current.Resources vs FindResource

    所以,我正在使用C#中的WPF创建一个GUI.它看起来像这样:它现在还没有完成.这两行是我尝试制作一种数据表,它们在XAML中是硬编码的.现在,我正在C#中实现添加新的水果按钮功能.我在XAML中有以下样式来控制行的背景图像应该是什么样子:因此,在代码中,我为每列col0,col1和col2创建一个图像,如果我使用以下代码,它添加了一个如下所示的新行:如你所见,它不太正确……为什么一个似乎忽略了一些属性而另一个没有?

  2. c# – 绑定DataGridTemplateColumn

    似乎我已经打了个墙,试图在DataGrid上使用DataTemplates.我想要做的是使用一个模板来显示每个单元格的两行文本.但是似乎无法以任何方式绑定列.以下代码希望显示我想做的事情.注意每个列的绑定:模板列没有这样的东西,因此,这个xaml不可能工作.我注定要将整个DataTemplate复制到每个列,只是对每个副本都有不同的约束?解决方法我不完全确定你想要做什么,但如果您需要获取整行的DataContext,可以使用RelativeSource绑定来移动视觉树.像这样:

  3. c# – 学习设计模式的资源

    最近我来到了这个设计模式的概念,并对此感到非常热情.你能建议一些帮助我深入设计模式的资源吗?

  4. c# – 是否有支持嵌入HTML页面的跨操作系统GUI框架?

    我想开发一个桌面应用程序来使用跨系统,是否有一个GUI框架,允许我为所有3个平台编写一次代码,并具有完全可脚本化的嵌入式Web组件?我需要它有一个API来在应用程序和网页之间进行交流.我知道C#,JavaScript和一些python.解决方法Qt有这样的事情QWebView.

  5. c# – 通过字符串在对象图中查找属性

    我试图使用任意字符串访问嵌套类结构的各个部分.给出以下(设计的)类:我想要从Person对象的一个实例的“PersonsAddress.HousePhone.Number”获取对象.目前我正在使用反思来做一些简单的递归查找,但是我希望有一些忍者有更好的想法.作为参考,这里是我开发的(crappy)方法:解决方法您可以简单地使用标准的.NETDataBinder.EvalMethod,像这样:

  6. c# – 文件下载后更新页面

    FamilyID=0a391abd-25c1-4fc0-919f-b21f31ab88b7&displaylang=en&pf=true它呈现该页面,然后使用以下元刷新标签来实际向用户提供要下载的文件:你可能需要在你的应用程序中做类似的事情.但是,如果您真的有兴趣在文件完全下载后执行某些操作,那么您的运气不佳,因为没有任何事件可以与浏览器进行通信.执行此操作的唯一方法是上传附件时使用的AJAXupload.

  7. c# – 如何在每个机器应用程序中实现单个实例?

    我必须限制我的.net4WPF应用程序,以便每台机器只能运行一次.请注意,我说每个机器,而不是每个会话.我使用一个简单的互斥体实现单实例应用程序,直到现在,但不幸的是,这样一个互斥是每个会话.有没有办法创建机器互连,还是有其他解决方案来实现每个机器应用程序的单个实例?

  8. c# – WCF和多个主机头

    我的雇主网站有多个主机名,都是同一个服务器,我们只是显示不同的皮肤来进行品牌宣传.不幸的是,在这种情况下,WCF似乎不能很好地工作.我试过overridingthedefaulthostwithacustomhostfactory.这不是一个可以接受的解决方案,因为它需要从所有主机工作,而不仅仅是1.我也看过thisblogpost,但是我无法让它工作,或者不是为了解决我的问题.我得到的错误是“这

  9. c# – ASP.NET MVC模型绑定与表单元素名称中的虚线

    我一直在搜索互联网,试图找到一种方式来容纳我的表单元素的破折号到ASP.NET的控制器在MVC2,3或甚至4中的默认模型绑定行为.作为一名前端开发人员,我更喜欢在我的CSS中使用camelCase或下划线进行破折号.在我的标记中,我想要做的是这样的:在控制器中,我会传入一个C#对象,看起来像这样:有没有办法通过一些正则表达式或其他行为来扩展Controller类来适应这种情况?我讨厌这样的事实,我必须这样做:甚至这个:思考?

  10. c# – 用户界面设计工具

    我正在寻找一个用户界面设计工具来显示文档中可能的GUI.我不能生成代码.我知道MicrosoftVisio提供了一个功能.但有什么办法吗?您使用哪种软件可视化GUI?

返回
顶部