2013-05-09 68 views
1

當創建WCF REST服務時,我在json中接收數據並且能夠保存在數據庫中。現在我需要選擇使用相同的服務上傳文件(可選,圖像或視頻)。我嘗試發送字節數組,但它可能是由於這種長陣列的序列化而導致錯誤的請求錯誤。我讀了上傳我需要使用流的大文件。我怎麼會發送其他參數呢?我正在創建此服務以接收來自移動設備的數據。這裏是我的服務接口
REST發佈請求與可選文件上傳

[WebInvoke(UriTemplate = "SaveFBPost", 
    Method = "POST", 
    BodyStyle = WebMessageBodyStyle.Wrapped, 
    RequestFormat = WebMessageFormat.Json, 
    ResponseFormat = WebMessageFormat.Json)] 
[OperationContract] 
void SaveFacebookPost(FBPostData fbPostData); 

公共類FBPostData:

[DataMember] 
public string scheduleDate { get; set; } 

[DataMember] 
public string userId { get; set; } 

[DataMember] 
public string groupId { get; set; } 

[DataMember] 
public string postText { get; set; } 

[DataMember] 
public byte[] file { get; set; } 

[DataMember] 
public string fileType { get; set; } 

[DataMember] 
public string accessToken { get; set; } 
+0

如果任何人有任何疑問,我不付出努力,那麼你可以看到它是一整天,我仍然處於同樣的問題。我在這裏發帖之前再搜索了一天。可能是正確方向的一點指導。任何人? – ali 2013-05-10 14:51:08

+0

你需要發佈一些更實際的代碼示例 - 你調整了maxBuffferSize和maxArrayLength嗎? – Ray 2013-05-13 16:17:27

+0

是的,我增加了maxBuffferSize和maxReceivedMessageSize。在網上有很多令人困惑和矛盾的東西(至少對於像我這樣的初學者來說)。就像在你提到的博客中說的那樣:「如果使用流,WCF不會讓你有任何其他參數」。它的確如此。您也可以將參數傳遞給Webinvoke,您當然可以使用REST發送流。我現在正在使用多部分文件上傳。似乎正在工作,但沒有完全測試。將在這裏更新 – ali 2013-05-14 09:54:16

回答

1

我想通過在web.config增加MAXBUFFERSIZE和的MaxArrayLength爲特定綁定開始,看看是否能解決問題。

您應該能夠針對錯誤提出一些更具體的細節,以便您明確知道爲什麼會出現400錯誤。

This blog article對我來說也是有用的 - 在底部也有一些很好的鏈接。

也看看Stream類。不確定你的意思是「發送其他參數」 - 如果你能澄清這一點,我們可以給你更多的方向。

+0

我在看你提到的博客,並會回覆給你。至於其他參數,就像我說的那樣,我正在用這個API調用發送其他數據,就像你在FBPostData類中看到的一樣。這隻適用於如果我刪除文件上傳文件字節數組。 – ali 2013-05-10 07:13:10

+0

這是非常有用的文章,但仍然沒有運氣。我正在使用webinvoke,但現在我正在使用SOAP instaed作爲蒸汽不能用REST完成?現在我的服務沒有受到任何影響。可能是我搞砸了我的配置。你能幫我解決嗎? – ali 2013-05-10 12:11:34

+0

在原帖中發佈一些代碼 – Ray 2013-05-10 19:21:26

1

我不得不使用流使用android和multipart解析器的多部分上傳來解決這個問題。我使用Apache的默庫上傳文件和發送參數是這樣的:從那以後,我使用C#多解析器來獲取文件和參數

HttpPost postRequest = new HttpPost(
       context.getString(R.string.url_service_fbpost)); 
     MultipartEntity reqEntity = new MultipartEntity(
       HttpMultipartMode.BROWSER_COMPATIBLE); 
     if(postData.data != null && !"".equals(postData.fileName)){ 
      ByteArrayBody bab = new ByteArrayBody(postData.data, postData.fileName); 
      reqEntity.addPart("uploaded", bab); 
     } 
     reqEntity.addPart("scheduleDate", new StringBody(postData.scheduleDate)); 
     reqEntity.addPart("userId", new StringBody(postData.userId)); 
     reqEntity.addPart("groupIds", 
       new StringBody(postData.groupIds.toString())); 
     reqEntity.addPart("postText", new StringBody(postData.postText)); 
     reqEntity.addPart("postType", new StringBody(postData.postType)); 
     reqEntity.addPart("accessToken", new StringBody(postData.accessToken)); 
     if(postData.postId != null && postData.postId.length() > 0) { 
      reqEntity.addPart("postId", new StringBody(postData.postId)); 
     } 
     postRequest.setEntity(reqEntity); 

。這裏是服務代碼:

[OperationContract] 
[WebInvoke(Method = "POST", 
     UriTemplate = "UploadFBPost", 
     BodyStyle = WebMessageBodyStyle.WrappedRequest)] 
void UploadFBPost(Stream stream); 

public void UploadFBPost(Stream stream) 
{ 
    MultipartParser parser = new MultipartParser(stream); 

    // Saves post data in database 
    if (parser.Success) 
    { 
     string fileName = null, userId = null, postText = null, postType = null, accessToken = null; 
     DateTime scheduleDate = DateTime.Now; 
     string[] groupIds = null; 
     int postId = 0; 

     // Other contents 
     foreach (MyContent content in parser.MyContents) 
     { 
      switch (content.PropertyName) 
      { 
       case "scheduleDate": 
        if (string.IsNullOrEmpty(content.StringData.Trim())) 
         scheduleDate = DateTime.Now; 
        else 
         scheduleDate = DateTime.ParseExact(content.StringData.Trim(), "M-d-yyyy H:m:s", CultureInfo.InvariantCulture); 
        break; 

       case "fileName": 
        fileName = content.StringData.Trim(); 
        break; 

       case "userId": 
        userId = content.StringData.Trim(); 
        break; 

       case "postText": 
        postText = content.StringData.Trim(); 
        break; 

       case "accessToken": 
        accessToken = content.StringData.Trim(); 
        break; 

       case "groupIds": 
        groupIds = content.StringData.Trim().Split(new char[] { ',' }); 
        break; 

       case "postType": 
        postType = content.StringData.Trim(); 
        break; 

       case "postId": 
        postId = Convert.ToInt32(content.StringData.Trim()); 
        break; 
      } 
     } 

     string videoFile = null, imageFile = null; 
     if (parser.FileContents != null) 
     { 
      string filePath = GetUniqueUploadFileName(parser.Filename); 
      File.WriteAllBytes(filePath, parser.FileContents); 
      if (postType == "photo") 
       imageFile = Path.GetFileName(filePath); 
      else 
       videoFile = Path.GetFileName(filePath); 
     } 
    } 
} 

您確實需要根據您要發送的數據修改多部分分析器。希望這會節省很少的時間。

感謝ray的幫助。

還有一件事。我不得不在網絡配置中添加這些行:

<httpRuntime maxRequestLength="2000000"/> 

<bindings> 
    <webHttpBinding> 
    <binding maxBufferSize="65536" 
      maxReceivedMessageSize="2000000000" 
      transferMode="Streamed"> 
    </binding> 
    </webHttpBinding> 
</bindings>