如何从Web控制器操作向API控制器操作发送文件(IFormFile)?

时间:2017-09-11 13:42:35

标签: c# asp.net-core asp.net-core-webapi iformfile

我们说我想上传一些文件。

Razor View中的我的HTML表单如下所示:

@model SequereMe.Onboarding.Web.ViewModels.Branding.TenantBrandingViewModel
@{
}

<form asp-controller="BrandingSettings" asp-action="Save" asp-method="post" enctype="multipart/form-data">
    <div class="form-group">
        <input asp-for="TenantId" value=@Model.TenantId />
    </div>
    <div class="form-group">
        <label for="logoFileUrl">Logo File Upload:</label>
        <input asp-for="LogoFile" type="file" class="form-control-file" id="logoFileUrl" aria-describedby="fileHelp">
        <h1>@Model.LogoFileUrl</h1>
    </div>
    <div class="form-group">
        <label for="backgroundFileUrl">Background File Upload:</label>
        <input asp-for="BackgroundFile" type="file" class="form-control-file" id="backgroundFileUrl" aria-describedby="fileHelp">
        <h1>@Model.BackgroundFileUrl</h1>
    </div>
    <button type="submit" class="btn btn-primary">Save</button>
</form>

此HTML表单将在提交时触发的控制器操作是此Web控制器操作:

public async Task<IActionResult> Save(TenantBranding tenantBranding)
{
    var result =
        await _apiClient.PostAsync("/BrandingSettings", tenantBranding);

    switch (result.Status)
    {
        case HttpStatusCode.NotFound:
        case HttpStatusCode.BadRequest:
            return new RedirectResult("~/Error/404");
        case HttpStatusCode.OK:
            //return View("Edit", result.Message.Content);
        default:
            return new RedirectResult("~/Error/500");
    } 
}

我进一步使用Pathoschild.Http.Client.IClient接口的FluentClient实现来对此Post方法进行API调用:

[HttpPost]
public async Task<IActionResult> Post([FromBody] TenantBranding tenantBranding)
{
    if (tenantBranding == null)
    {
        return new BadRequestObjectResult("Invalid Parameter: The incoming tenantBranding parameter is null");
    }

    if (tenantBranding.TenantId == Guid.Empty)
    {
        return new BadRequestObjectResult("Invalid Parameter: The tenantId in the incoming parameter tenantBranding is empty");
    }

    var result = _brandingLogic.Save(tenantBranding).Result;

    if (!result)
    {
        return new JsonResult(500);
    }
    return Ok(); 
}

由于某些奇怪的原因,Api Post方法中的tenantbranding参数为null。从Web控制器到Api控制器的ModelBinding有问题。

这就是我的TenantBranding模型(Api)的样子:

public class TenantBranding
{
    public Guid TenantId { get; set; }
    public IEnumerable<FormFile> LogoFile { get; set; }
    public IEnumerable<FormFile> BackgroundFile { get; set; }
    public string DocumentType { get; set; }
}

这就是我在网上的TenantBranding的样子:

public class TenantBranding
{
    public Guid TenantId { get; set; }
    public IFormFile LogoFile { get; set; }
    public IFormFile BackgroundFile { get; set; }
}

但API方法中的tenantBranding参数显示为null,所以我不确定为什么会发生这种情况?可能与IFormFile

有关

1 个答案:

答案 0 :(得分:0)

首先尝试在输入中添加name属性。

<input asp-for="BackgroundFile" type="file" name="BackgroundFile" class="form-control-file" id="backgroundFileUrl" aria-describedby="fileHelp">

但我建议你走另一条路,并为你的api控制器使用ajax请求:

$(form).on("submit", function(){
    $.ajax({
       url:"api/controller/action",
       type:"POST",
       //here will be your data from FORM
       data:{
                TenantId:$("#tenantid input id").val(),
                LogoFile :$("#LogoFile input id").val(),
                BackgroundFile :$("#BackgroundFile input id").val(),                
            },
      content-type:"application/json",
      success:function(response){// do on success},
      error:function(){// do somesthig on error}
    });
})

当您提交表格时,js向api控制器发送邮件请求。这是使用WebApi的更好方法。