Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在使用Asp.NET Core 3.1 framework将文件上载到服务器时,如何将IFormFile用作属性?_C#_Asp.net Core_Asp.net Core 2.0_Asp.net Core Webapi_Asp.net Core 3.0 - Fatal编程技术网

C# 在使用Asp.NET Core 3.1 framework将文件上载到服务器时,如何将IFormFile用作属性?

C# 在使用Asp.NET Core 3.1 framework将文件上载到服务器时,如何将IFormFile用作属性?,c#,asp.net-core,asp.net-core-2.0,asp.net-core-webapi,asp.net-core-3.0,C#,Asp.net Core,Asp.net Core 2.0,Asp.net Core Webapi,Asp.net Core 3.0,我正在尝试创建一个Web API来处理文件的存储 Asp.NETCore1.0+框架附带了允许将文件绑定到视图模型的接口。缔约国声明如下: IFormFile可以直接用作操作方法参数或 绑定模型属性 当我使用ifformfile作为操作方法的参数时,它没有任何问题。但在我的例子中,我希望将其用作模型上的属性,因为除了包含自定义验证规则之外,我还希望绑定其他值。这是我的视图模型 public class NewFile { [Required] [MinFileSize(125),

我正在尝试创建一个Web API来处理文件的存储

Asp.NETCore1.0+框架附带了允许将文件绑定到视图模型的接口。缔约国声明如下:

IFormFile可以直接用作操作方法参数或 绑定模型属性

当我使用
ifformfile
作为操作方法的参数时,它没有任何问题。但在我的例子中,我希望将其用作模型上的属性,因为除了包含自定义验证规则之外,我还希望绑定其他值。这是我的视图模型

public class NewFile
{
    [Required]
    [MinFileSize(125), MaxFileSize(5 * 1024 * 1024)]
    [AllowedExtensions(new[] { ".jpg", ".png", ".gif", ".jpeg", ".tiff" })]
    public IFormFile File { get; set; }

    [Required]
    public int? CustomField1 { get; set; }

    [Required]
    public int? CustomField2 { get; set; }

    [Required]
    public int? CustomField3 { get; set; }
}
下面是我的客户机请求代码和接受该文件的服务器代码。为了简单起见,这两种方法都放在同一个控制器中。但实际上,“客户机”方法将被放置在一个单独的应用程序中,该应用程序通过文件进行发送

[ApiController, Route("api/[controller]")]
public class FilesController : ControllerBase
{
    [HttpGet("client")]
    public async Task<IActionResult> Client()
    {
        using HttpClient client = new HttpClient();

        // we need to send a request with multipart/form-data
        var multiForm = new MultipartFormDataContent
        {
            // add API method parameters
            { new StringContent("CustomField1"), "1" },
            { new StringContent("CustomField2"), "1234" },
            { new StringContent("CustomField3"), "5" },
        };

        // add file and directly upload it
        using FileStream fs = System.IO.File.OpenRead("C:/1.jpg");
        multiForm.Add(new StreamContent(fs), "file", "1.jpg");

        // send request to API
        var responce = await client.PostAsync("https://localhost:123/api/files/store", multiForm);

        return Content("Done");
    }

    [HttpPost("store")]
    public async Task<IActionResult> Store(NewFile model)
    {
        if (ModelState.IsValid)
        {
            try
            {
                var filename = MakeFileName(model, Path.GetFileName(model.File.FileName));

                Directory.CreateDirectory(Path.GetDirectoryName(filename));

                using var stream = new FileStream(filename, FileMode.Create);
                await model.File.CopyToAsync(stream);

                return PhysicalFile(filename, "application/octet-stream");
            }
            catch (Exception e)
            {
                return Problem(e.Message);
            }
        }

        // Are there a better way to display validation errors when using Web API?
        var errors = string.Join("; ", ModelState.Values.SelectMany(v => v.Errors).Select(v => v.ErrorMessage));

        return Problem(errors);
    }
}
[ApiController,Route(“api/[controller]”)
公共类FileController:ControllerBase
{
[HttpGet(“客户”)]
公共异步任务客户端()
{
使用HttpClient=new HttpClient();
//我们需要发送一个包含多部分/表单数据的请求
var multiForm=新的MultipartFormDataContent
{
//添加API方法参数
{new StringContent(“CustomField1”),“1”},
{new StringContent(“CustomField2”),“1234”},
{new StringContent(“CustomField3”),“5”},
};
//添加文件并直接上传
使用FileStream fs=System.IO.File.OpenRead(“C:/1.jpg”);
添加(新的StreamContent(fs),“文件”,“1.jpg”);
//向API发送请求
var response=wait client.PostAsync(“https://localhost:123/api/files/store“,多种形式);
返回内容(“完成”);
}
[HttpPost(“商店”)]
公共异步任务存储(新文件模型)
{
if(ModelState.IsValid)
{
尝试
{
var filename=MakeFileName(model,Path.GetFileName(model.File.filename));
CreateDirectory(Path.GetDirectoryName(filename));
使用var stream=newfilestream(文件名,FileMode.Create);
等待model.File.CopyToAsync(流);
返回物理文件(文件名,“应用程序/八位字节流”);
}
捕获(例外e)
{
返回问题(e.Message);
}
}
//在使用Web API时,是否有更好的方法显示验证错误?
var errors=string.Join(“;”,ModelState.Values.SelectMany(v=>v.errors.Select(v=>v.ErrorMessage));
返回问题(错误);
}
}
当我发出请求时,我得到了以下错误,但是请求从未到达
存储
方法,因为我在那里放置了一个断点,但它从未到达那里

状态代码:415,原因短语:“不支持的媒体类型”,版本:1.1, 内容:System.Net.Http.HttpConnectionResponseContent


如何将文件正确地发送到服务器并将其绑定到视图模型上的
文件
属性?

ApiController
默认情况下需要JSON,除非另有明确说明

用于使用请求正文中的表单数据绑定模型

public async Task<IActionResult> Store([FromForm]NewFile model) {
    //...
}. 

使用
[FromForm]
绑定模型
公共异步任务存储([FromForm]新文件模型)
ApiController
默认情况下需要JSON,除非明确告诉其他人我根据您的建议添加了
[FromForm]
,但仍然不起作用。我从控制器中删除了
[ApiController]
属性,并按预期向
存储
方法发出了请求。但是,
CustomField1
、CustomField2
CustomField3`即使如您在我的原始问题中所看到的那样一起发送,它们也是空的。@John客户端没有正确发送这些其他字段。您已经切换了内容和名称如何在postman或Fiddler中测试这种类型的API?你能推荐一下吗。
var multiForm = new MultipartFormDataContent {
    // add API method parameters
    { new StringContent("1"), "CustomField1" },
    { new StringContent("1234"), "CustomField2" },
    { new StringContent("5"), "CustomField3" },
};