UploadFile get error

    [ServiceStack.Route("/images/webuploader")]
    public class WebUploaderImage : IReturn<string>
    {
        public string id { get; set; }
        public string name { get; set; }
        public string type { get; set; }
        public string lastModifiedDate { get; set; }
        public int size { get; set; }
        //public int referid { get; set; }
        public Guid? referimgid { get; set; }
    }
 [Authenticate]
    public class UploadImageService : AppService
    {
        public async Task<string> Post(WebUploaderImage request)
        {
            if (request.referimgid == default)
                throw new Exception("not found ");
            //logger.Info(request.SerializeToString());
            var newImageName = Guid.NewGuid().ToString("N").Substring(0, 20) + ".jpg";
            var folderName = DateTime.Now.ToString("yyyyMMdd");
            var savedDirectory = f.WebRootPath.CombineWith($"/wx_images/{folderName}/");
            var thumbDirectory = f.WebRootPath.CombineWith($"/wx_images/thumbnail/{folderName}/");
            savedDirectory.AssertDir();
            thumbDirectory.AssertDir();
            var savedFilePath = savedDirectory.CombineWith(newImageName);
            var thumbFilePath = thumbDirectory.CombineWith(newImageName);
            string imageFileName;
            if (ImageFileHelper.IsImage(request.name))
            {
                var bytes = Request.InputStream.ToBytes();
                var uploadImage = Image.FromStream(new MemoryStream(bytes));
                var savedImage = uploadImage;
                var thumbImage = uploadImage.Scale((double)240 / uploadImage.Width);

                savedImage.Save(savedFilePath, ImageFormat.Jpeg);
                thumbImage.Save(thumbFilePath, ImageFormat.Jpeg);
                imageFileName = $"/{folderName}/{newImageName}";
            }
            else
            {
                var bytes = Request.InputStream.ToBytes();
                var fileExtension = Path.GetExtension(request.name.ToLower());
                if (fileExtension.IsNullOrWhiteSpace())
                {
                    fileExtension = ".jpg";
                }
                var allowedFileExtensions = new string[] { ".jpg", ".jpeg", ".png", ".bmp", ".rar", ".ppt", ".pptx", ".doc", ".docx", ".xls", ".xlsx", ".pdf", ".txt", ".mp4" };
                if (allowedFileExtensions.Contains(fileExtension) == false)
                {
                    logger.Error($"not allowed, :{ fileExtension}, request.name: {request.name}");
                    throw new Exception($"not allowed, :{ fileExtension}, request.name: {request.name}");
                }
                var newFileName = $"{Guid.NewGuid().ToString("N").Substring(0, 20) + fileExtension}";
                savedFilePath = savedDirectory.CombineWith(newFileName);
                try
                {
                    using var ms = new MemoryStream(bytes);
                    using var fs = new FileStream(savedFilePath, FileMode.OpenOrCreate);
                    ms.WriteTo(fs);
                    ms.Close();
                    fs.Close();
                }
                catch (Exception ex)
                {
                    logger.Error("upload error:" + request.SerializeToString() + ex.Message);
                }
                imageFileName = $"/{folderName}/{newFileName}";
            }
            return imageFileName;
        }
}

Used PC to upload Image, works fine. when used iphone Upload Image, some times is ok , but some times get error, below image is the logfile when get error. after 2020-11-28 07:26:57.1015 【DEBUG】 【HttpAsyncTaskHandler】 CreateRequestAsync/requestParams:referimgid,id,name,type,lastModifiedDate,size has lot of unrecognizable code, why will receive lots of these? how to reject it or not receive it ? thanks.

The response indicates this is a malformed request which is already rejected by ServiceStack since it can’t deserialize into the Request DTO so it fails and returns the appropriate 400 response.

Note this isn’t a proper HTTP multipart/form-data File Upload request if it was the uploaded files would be in Request.Files.

As it looks like it’s just posting the raw file binary contents to the Request Body you should implement IRequiresRequestStream on your Request DTO:

//Request DTO
public class RawBytes : IRequiresRequestStream
{
    /// <summary>
    /// The raw Http Request Input Stream
    /// </summary>
    Stream RequestStream { get; set; }
}

Which tells ServiceStack to skip trying to deserialize the request so you can read in the raw HTTP Request body yourself, e.g:

public object Post(RawBytes request)
{
    byte[] bytes = request.RequestStream.ReadFully();
    string text = bytes.FromUtf8Bytes(); //if text was sent
}

follow your code, I modified the code

    [ServiceStack.Route("/images/webuploader")]
    public class WebUploaderImage : IRequiresRequestStream, IReturn<string>
    {
        public string id { get; set; }
        public string name { get; set; }
        public string type { get; set; }
        public string lastModifiedDate { get; set; }
        public int size { get; set; }
        //public int referid { get; set; }
        public Guid? referimgid { get; set; }
        /// <summary>
        /// The raw Http Request Input Stream
        /// </summary>
        public Stream RequestStream { get; set; }
    }
 public async Task<string> Post(WebUploaderImage request)
        {
            logger.Info($"WebUploaderImage.request:{request.SerializeToString()}");
            if (request.referimgid == default)
                throw new Exception("没有对应的ReferImgID");
 
            var newImageName = Guid.NewGuid().ToString("N").Substring(0, 20) + ".jpg";
            var folderName = DateTime.Now.ToString("yyyyMMdd");
            var savedDirectory = f.WebRootPath.CombineWith($"/wx_images/{folderName}/");
            var thumbDirectory = f.WebRootPath.CombineWith($"/wx_images/thumbnail/{folderName}/");
            savedDirectory.AssertDir();
            thumbDirectory.AssertDir();
            var savedFilePath = savedDirectory.CombineWith(newImageName);
            var thumbFilePath = thumbDirectory.CombineWith(newImageName);
            string imageFileName;
                logger.Info($"WebUploaderImage.request.name: {request.name}");
                var bytes = request.RequestStream.ReadFully();
                if (bytes.Length == 0)
                {
                    logger.Info($"WebUploaderImage.request.name: {request.name} is empty");
                    if (Request.Files.Length > 0)  
                    {
                        var uploadedFile = Request.Files[0];
                        uploadedFile.SaveTo($"D:\\{GuidHelper.NewGuid()}.jpg");
                        logger.Info($"WebUploaderImage.Request.Files[0] Saved To ");
                    }
                    return string.Empty;
                }
                var uploadImage = Image.FromStream(new MemoryStream(bytes));

                Image savedImage;
                if (uploadImage.Width > 1280)
                {
                    savedImage = uploadImage.Scale((double)1280 / uploadImage.Width);
                }
                else
                {
                    savedImage = uploadImage;
                }
                var thumbImage = uploadImage.Scale((double)240 / uploadImage.Width);

                savedImage.Save(savedFilePath, ImageFormat.Jpeg);
                thumbImage.Save(thumbFilePath, ImageFormat.Jpeg);

                imageFileName = $"/{folderName}/{newImageName}";
            } 
            return imageFileName;
        }

Followed your code, there are also had lot of unrecognizable code, and the request.RequestStream.ReadFully() is Empty and Request.Files length is zero, can’t upload image.

Then the HTTP Request is invalid, can you post the raw HTTP Request Headers so we can see what Content-Type it’s trying to post the file as.

Actually I can see a application/x-www-form-urlencoded Content-Type in the URL log
which is what HTML Form Posts use to post Key/Value pairs which is invalid for a binary file.

HTTP File Uploads should use a multipart/form-data Content-Type but it needs to be sent with a valid format, please see this answer for an example of a valid multipart/form-data request.

If you’re using ServiecStack libraries we have File Upload APIs on both the C# typed .NET Service Clients as well as the generic .NET HttpWebRequest which handles sending the appropriate file upload request.