You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms调用WCF传图遇413(RequestEntityTooLarge)错误求助

解决WCF 413(RequestEntityTooLarge)错误及Xamarin.Forms文件上传最优方案

先排查413错误的核心问题

你遇到的413错误是因为请求实体大小超过了服务器允许的上限,虽然你调整了WCF的配置,但可能还有几个关键配置没到位:

1. 补充IIS和ASP.NET的请求大小限制

你的web.config里的<httpRuntime>节点缺少maxRequestLength配置(这个参数单位是KB,默认仅4096KB=4MB),需要添加并设置足够大的值:

<system.web>
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1" maxRequestLength="2097152" /> <!-- 设置为2GB -->
</system.web>

同时还要检查IIS站点的请求筛选设置:

  • 打开IIS管理器,找到你的服务站点
  • 点击「请求筛选」→「编辑功能设置」
  • 把「最大允许内容长度」(单位是字节)调整为足够大的值,比如2147483648(2GB)

2. 修正WCF绑定的配置错误

你的web.config存在绑定配置不匹配的问题:

  • 你定义了basicHttpBinding的配置BasicHttpBinding_IQuery_service,但客户端节点用的是webHttpBinding,并且绑定配置指向了BasicHttpBinding的配置,这会导致WCF服务实际没有使用到你设置的大消息限制。
  • 配置中缺少<services>节点,没有明确将服务与你定义的绑定配置关联,WCF会使用默认的basicHttpBinding(默认maxReceivedMessageSize仅65536字节)。

需要补充<services>节点,示例如下(替换YourNamespace为你实际的服务命名空间):

<system.serviceModel>
    <!-- 其他原有配置保持不变 -->
    <services>
        <service name="YourNamespace.Query_service" behaviorConfiguration="GlobalBehavior">
            <endpoint 
                address="" 
                binding="basicHttpBinding" 
                bindingConfiguration="BasicHttpBinding_IQuery_service"
                contract="YourNamespace.IQuery_service"
                behaviorConfiguration="GlobalEndpoint" />
        </service>
    </services>
    <!-- 其他原有配置保持不变 -->
</system.serviceModel>

3. 优化服务端上传代码

你的上传方法存在资源泄漏风险,fileStream被赋值后又在using里重复引用,会导致双重Dispose。建议直接在using中创建文件流,同时用Path.Combine避免路径拼接错误:

public bool UploadToFolder(byte[] file_bytes, string file_name) {
    bool isSuccess = false;
    string strFolderPath = System.Configuration.ConfigurationManager.AppSettings.Get(@"dest\path");
    try {
        if (!string.IsNullOrEmpty(strFolderPath) && !string.IsNullOrEmpty(file_name)) {
            string strFileFullPath = Path.Combine(strFolderPath, file_name);
            using (var fs = new FileStream(strFileFullPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) {
                fs.Write(file_bytes, 0, file_bytes.Length);
                isSuccess = true;
            }
        }
    } catch (Exception ex) {
        // 建议记录日志而非直接抛出原始异常,避免泄露敏感信息
        throw new FaultException("文件上传失败,请稍后重试");
    }
    return isSuccess;
}

Xamarin.Forms文件上传的最优方案

WCF虽然可用,但现在更推荐REST API(如ASP.NET Core Web API)+ HttpClient的组合,跨平台支持更好、更轻量、生态更丰富。以下是具体建议:

1. 替换WCF为ASP.NET Core Web API

将上传服务改成ASP.NET Core Web API,它天生支持大文件上传,配置更简单:

  • 在Program.cs中配置请求大小限制:
builder.Services.Configure<FormOptions>(options =>
{
    options.MultipartBodyLengthLimit = 2147483648; // 设置为2GB
});
  • 编写上传接口:
[ApiController]
[Route("api/upload")]
public class UploadController : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> Upload(IFormFile file)
    {
        var uploadPath = Path.Combine(Directory.GetCurrentDirectory(), "uploads");
        Directory.CreateDirectory(uploadPath);
        var filePath = Path.Combine(uploadPath, file.FileName);
        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }
        return Ok(new { success = true });
    }
}

2. 客户端用HttpClient流式上传

Xamarin.Forms中用HttpClient上传,支持流式传输(避免把整个文件读进内存)和进度监控:

using var httpClient = new HttpClient();
using var content = new MultipartFormDataContent();
// 从MediaPicker获取文件流
var result = await MediaPicker.PickPhotoAsync();
if (result != null)
{
    using var stream = await result.OpenReadAsync();
    var fileContent = new StreamContent(stream);
    fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
    content.Add(fileContent, "file", result.FileName);

    // 监控上传进度
    var progressHandler = new ProgressMessageHandler();
    progressHandler.HttpSendProgress += (sender, args) =>
    {
        double progress = args.ProgressPercentage;
        // 更新UI进度条
        MainThread.BeginInvokeOnMainThread(() =>
        {
            // progressBar.Progress = progress / 100;
        });
    };
    var client = HttpClientFactory.Create(progressHandler);

    var response = await client.PostAsync("http://your-server/api/upload", content);
    if (response.IsSuccessStatusCode)
    {
        await DisplayAlert("成功", "文件上传完成", "OK");
    }
    else
    {
        await DisplayAlert("错误", "上传失败", "OK");
    }
}

3. 额外优化建议

  • 图片压缩:上传前在客户端压缩图片,减少文件大小。可以用SkiaSharp库调整分辨率和质量:
using SkiaSharp;
// 图片压缩示例
public byte[] CompressImage(byte[] imageData, int quality = 70, int maxWidth = 1920)
{
    using var inputStream = new MemoryStream(imageData);
    using var originalBitmap = SKBitmap.Decode(inputStream);
    int newWidth = originalBitmap.Width > maxWidth ? maxWidth : originalBitmap.Width;
    int newHeight = (int)((float)newWidth / originalBitmap.Width * originalBitmap.Height);
    using var resizedBitmap = originalBitmap.Resize(new SKImageInfo(newWidth, newHeight), SKFilterQuality.High);
    using var image = SKImage.FromBitmap(resizedBitmap);
    using var outputStream = new MemoryStream();
    image.Encode(SKEncodedImageFormat.Jpeg, quality).SaveTo(outputStream);
    return outputStream.ToArray();
}
  • 分块上传:对于超大文件,分成多个小块上传,实现断点续传,避免因网络问题重新上传整个文件。
  • HTTPS传输:确保上传请求用HTTPS,保障数据安全。

内容的提问来源于stack exchange,提问作者Leonardo Bassi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:33:14