WCF服务从android使用Multipart数据

时间:2017-10-09 09:42:21

标签: c# regex wcf multipartform-data matcher

我使用android okhttp将多部分数据,即图像和文本发送到wcf服务。我可以使用提到的here自定义MultipartParser类在服务器上发送和解析部分数据。

当我的文件被写入服务器时,由于来自Multipart数据的一些不需要的字符被写入字节而被破坏[我通过打开记事本++中显示编码字节和不需要的字符的图像来发现这一点]。 我可以通过为contentLenMatch添加正则表达式匹配器来删除它们,但仍然在文件的开头写入换行符,因此显示它已损坏。

我需要知道如何在将数据写入文件之前从数据中删除空格或\ n。

代码:

     public class MultipartParser    {
     public IDictionary<string, string> Parameters = new Dictionary<string, string>();
     public MultipartParser(Stream stream)        {
        this.Parse(stream, Encoding.UTF8);
    }
    public MultipartParser(Stream stream, Encoding encoding)        {
        this.Parse(stream, encoding);
    }
    public string getcontent(Stream stream, Encoding encoding)        {
        byte[] data = ToByteArray(stream);
        string content = encoding.GetString(data);
        string delimiter = content.Substring(0, content.IndexOf("\r\n"));
        string[] sections = content.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string s in sections)       {
            Match nameMatch = new Regex(@"(?<=name\=\"")(.*?)(?=\"")").Match(s);
            string name = nameMatch.Value.Trim().ToLower();
            if (!string.IsNullOrWhiteSpace(name))        {
                int startIndex = nameMatch.Index + nameMatch.Length + "\r\n\r\n".Length;    
            }            
        string strRet = ""; //Parameters["name"];
        return strRet;
    }
    private void Parse(Stream stream, Encoding encoding)        {
        this.Success = false;
        byte[] data = ToByteArray(stream);
        string content = encoding.GetString(data);
        int delimiterEndIndex = content.IndexOf("\r\n");
        if (delimiterEndIndex > -1)    {
            string delimiter = content.Substring(0, content.IndexOf("\r\n"));
            Regex re = new Regex(@"(?<=Content\-Type:)(.*?)");
            Match contentTypeMatch = re.Match(content);
            re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")");
            Match filenameMatch = re.Match(content);


            // to match Content-Length and remove ***Unwanted chars***
            re = new Regex(@"(?<=Content\-Length:)(.*)");
            Match contentLenMatch = re.Match(content);
            if(contentLenMatch.Success){
                contentLenMatch = contentLenMatch.NextMatch();
            }


            if (contentTypeMatch.Success && filenameMatch.Success)    {
                this.ContentType = contentTypeMatch.Value.Trim();
                this.Filename = filenameMatch.Value.Trim();


                // changed from contentTypeMatch to contentLenMatch
                // startIndex must point to the 1st byte 
                // from where the file needs to be written
                // Need to remove extra \n that gets written to the file
                int startIndex = contentLenMatch.Index + contentLenMatch .Length + "\r\n\r\n".Length;


                byte[] delimiterBytes = encoding.GetBytes("\r\n" + delimiter);
                int endIndex = IndexOf(data, delimiterBytes, startIndex);
                int contentLength = endIndex - startIndex;
                byte[] fileData = new byte[contentLength];
                Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength);
                this.FileContents = fileData;
                this.Success = true;                }
        }        }
    private int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex)       {
        int index = 0;
        int startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex);
        if (startPos != -1)          {
            while ((startPos + index) < searchWithin.Length)             {
                if (searchWithin[startPos + index] == serachFor[index])                   {
                    index++;
                    if (index == serachFor.Length)                        {
                        return startPos;
                    }
                }    else      {
                    startPos = Array.IndexOf<byte>(searchWithin, serachFor[0], startPos + index);
                    if (startPos == -1)      {
                       return -1;
                    }
                    index = 0;
                }
            }
        }
        return -1;
    }
    private byte[] ToByteArray(Stream stream)        {
        byte[] buffer = new byte[32768];
        using (MemoryStream ms = new MemoryStream())           {
            while (true)       {
                int read = stream.Read(buffer, 0, buffer.Length);
                if (read <= 0)
                    return ms.ToArray();
                ms.Write(buffer, 0, read);
            }
        }
    }
    public bool Success        {
        get;
        private set;
    }
    public string ContentType        {
        get;
        private set;
    }
    public string Filename        {
        get;
        private set;
    }
    public byte[] FileContents        {
        get;
        private set;
    }
    public string Imgname        {
        get;
        private set;
    }    

2 个答案:

答案 0 :(得分:0)

好的,所以我早就用一些尝试和错误的基础解决了这个问题,但是因为没有人回答我发布我的解决方案。

public class MultipartParser
{
    public IDictionary<string, string> Parameters = new Dictionary<string, string>();
    public MultipartParser(Stream stream)
    {
        this.Parse(stream, Encoding.UTF8);
    }
    public MultipartParser(Stream stream, Encoding encoding)
    {
        this.Parse(stream, encoding);
    }
    public string getcontent(Stream stream, Encoding encoding)
    {
        // Read the stream into a byte array
        byte[] data = ToByteArray(stream);
        // Copy to a string for header parsing
        string content = encoding.GetString(data);
        string delimiter = content.Substring(0, content.IndexOf("\r\n"));
        string[] sections = content.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string s in sections)
        {
            Match nameMatch = new Regex(@"(?<=name\=\"")(.*?)(?=\"")").Match(s);
            string name = nameMatch.Value.Trim().ToLower();
            if (!string.IsNullOrWhiteSpace(name))
            {
                int startIndex = nameMatch.Index + nameMatch.Length + "\r\n\r\n".Length;
            }
        }
        string strRet = ""; //Parameters["name"];
        return strRet;
    }
    private void Parse(Stream stream, Encoding encoding)
    {
        this.Success = false;            
        byte[] data = ToByteArray(stream);            
        string content = encoding.GetString(data);

        string s_no = content.Substring(content.IndexOf("s_no"), 100);                       
        string[] lines = s_no.Split(new[] { "\r\n", "\r\n\r\n" }, StringSplitOptions.None);
        this.S_NO = lines[3];            

        string count = content.Substring(content.IndexOf("Count"), 100);            
        string[] linescount = count.Split(new[] { "\r\n", "\r\n\r\n" }, StringSplitOptions.None);
        this.Count = linescount[3];   

        int delimiterEndIndex = content.IndexOf("\r\n");
        if (delimiterEndIndex > -1)
        {
            string delimiter = content.Substring(0, content.IndexOf("\r\n"));
            // Look for Content-Type
            Regex re = new Regex(@"(?<=Content\-Type:)(.*?)");
            Match contentTypeMatch = re.Match(content);
            // Look for filename
            re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")");
            Match filenameMatch = re.Match(content);
            re = new Regex(@"(?<=Content\-Length:)(.*)");
            Match contentLenMatch = re.Match(content);

            if (contentLenMatch.Success)
            {
                contentLenMatch = contentLenMatch.NextMatch();
            }
            if (contentLenMatch.Success)
            {
                contentLenMatch = contentLenMatch.NextMatch();
            }
            //re = new Regex(@"(?<=name\=\"")(.*?)(?=\"")");
            //Match nameMatch = re.Match(content);
            // Did we find the required values?
            if (contentTypeMatch.Success && filenameMatch.Success)
            {
                // Set properties
                this.ContentType = contentTypeMatch.Value.Trim();
                this.Filename = filenameMatch.Value.Trim();
                // Get the start & end indexes of the file contents
                int startIndex = contentLenMatch.Index + contentLenMatch.Length + "\r\n".Length + 1;
                byte[] delimiterBytes = encoding.GetBytes("\r\n" + delimiter);
                int endIndex = IndexOf(data, delimiterBytes, startIndex);
                int contentLength = endIndex - startIndex;
                // Extract the file contents from the byte array
                byte[] fileData = new byte[contentLength];
                Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength);
                this.FileContents = fileData;
                this.Success = true;
            }
        }
    }
    private int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex)
    {
        int index = 0;
        int startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex);
        if (startPos != -1)
        {
            while ((startPos + index) < searchWithin.Length)
            {
                if (searchWithin[startPos + index] == serachFor[index])
                {
                    index++;
                    if (index == serachFor.Length)
                    {
                        return startPos;
                    }
                }
                else
                {
                    startPos = Array.IndexOf<byte>(searchWithin, serachFor[0], startPos + index);
                    if (startPos == -1)
                    {
                        return -1;
                    }
                    index = 0;
                }
            }
        }
        return -1;
    }
    private byte[] ToByteArray(Stream stream)
    {
        byte[] buffer = new byte[32768];
        using (MemoryStream ms = new MemoryStream())
        {
            while (true)
            {
                int read = stream.Read(buffer, 0, buffer.Length);
                if (read <= 0)
                    return ms.ToArray();
                ms.Write(buffer, 0, read);
            }
        }
    }
    public bool Success
    {
        get;
        private set;
    }
    public string ContentType
    {
        get;
        private set;
    }
    public string Filename
    {
        get;
        private set;
    }
    public byte[] FileContents
    {
        get;
        private set;
    }
    public string Imgname
    {
        get;
        private set;
    }
    public string S_NO
    {
        get;
        private set;
    }
    public string Count
    {
        get;
        private set;
    }
}
// End of Wcf rest Service Code

我的Android代码如下所示使用Okhttp

public static ResultVO uploadIMGMultipart(String s_no, int noOfDocs, String filepath, String url) {
    ResultVO resultVO = new ResultVO();
    OkHttpClient client = new OkHttpClient().newBuilder()
            .retryOnConnectionFailure(false)
            .connectTimeout(10000, TimeUnit.MILLISECONDS)
            .build();

    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("s_no",s_no.toString())
            .addFormDataPart("Count", ""+noOfDocs)
            .addFormDataPart("filestream", new File(filepath).getName().toString(), RequestBody.create(MEDIA_TYPE_PNG, new File(filepath)))
            .build();

    Request request = new Request.Builder()
            .url(url)
            .addHeader("content-type", "multipart/form-data;")
            .cacheControl(CacheControl.FORCE_NETWORK)
            .post(requestBody)
            .build();

    Response response = null;
    try {
        response = client.newCall(request).execute();
        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

        resultVO.setStatus(response.code());
        resultVO.setResult(response.body().string());
    } catch (Exception e) {
        e.printStackTrace();
    }

    return resultVO;
}

从您的类中调用AsyncTask中的上述方法....

答案 1 :(得分:0)

你去......

<强> MyService.cs

[OperationContract]
[WebInvoke(Method = "POST",ResponseFormat = WebMessageFormat.Json,BodyStyle = WebMessageBodyStyle.Wrapped,UriTemplate = "/UPLOAD_DOCUMENTS")]
    string UPLOAD_DOCUMENTS(Stream fileStream);

<强> IMyService.svc.cs

public string UPLOAD_DOCUMENTS(Stream fileStream) 
{
    string ResponseMessage = "Documents Not Uploaded";  
    string strRet = string.Empty;
    string strpdffile = string.Empty;
    string VAR_CLAIM_INWARD_NO = "";
    string response = string.Empty;
    int i = 0;
    string tempFolderPath = string.Empty;
    string UPLOADED_BY = string.Empty;
    string VAR_NEXT_FILE_NO = "";
    string s_no = string.Empty;
    string count = string.Empty;

    try
    {
        MultipartParser parser = new MultipartParser(fileStream);
        if (parser.Success)
        {
            string fileName = parser.Filename;
            string contentType = parser.ContentType;
            byte[] fileContent = parser.FileContents;
            Encoding encoding = Encoding.UTF8;
            s_no = parser.S_NO;
            count = parser.Count;

            string savepathImg = @"Your path" + fileNameToBeSaved + ".jpg";
            FileStream fileToupload = new FileStream(savepathImg, FileMode.Create);
            fileToupload.Write(fileContent, 0, fileContent.Length);
            fileToupload.Close();
            fileToupload.Dispose();
            fileStream.Close();
            strRet = fileName;
            tempFolderPath = @"Your path";                                              

        }
        else
        {

        }
    }
    catch (Exception ex)
    {

    }

    return ResponseMessage;
}