C# 带可选文件上载的REST post请求
在创建WCF REST服务时,我接收到json格式的数据,并能够保存在数据库中。现在我需要给选项上传文件(可选,图像或视频)与相同的服务。我尝试发送字节数组,但它给出了错误的请求错误,可能是因为序列化了如此长的数组。我读到,上传大文件,我需要使用流。在发送其他参数时,我将如何做到这一点?我创建此服务是为了从移动设备接收数据。这是我的服务界面C# 带可选文件上载的REST post请求,c#,wcf,C#,Wcf,在创建WCF REST服务时,我接收到json格式的数据,并能够保存在数据库中。现在我需要给选项上传文件(可选,图像或视频)与相同的服务。我尝试发送字节数组,但它给出了错误的请求错误,可能是因为序列化了如此长的数组。我读到,上传大文件,我需要使用流。在发送其他参数时,我将如何做到这一点?我创建此服务是为了从移动设备接收数据。这是我的服务界面 [WebInvoke(UriTemplate = "SaveFBPost", Method = "POST", BodyStyle =
[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; }
首先,我将在web.config中增加特定绑定的maxBufferSize和maxArrayLength,看看这是否解决了问题 您还应该能够获取有关错误的更多详细信息,这样您就可以确切地了解出现错误的原因 在过去对我也很有用-在底部也有一些很好的链接
再看看这个班。不确定“发送其他参数”是什么意思-如果你能澄清这一点,我们可以给你更多的指导。我不得不使用来自android的多部分上传流和多部分解析器来解决这个问题。我使用Apache mime库上传文件并发送如下参数:
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);
之后,我使用c#多部分解析器来获取文件和参数。以下是服务代码:
[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);
}
}
}
您确实需要根据发送的数据修改多部分解析器。希望这能节省少数人的时间
谢谢雷的帮助
还有一件事。我必须在web配置中添加以下行:
<httpRuntime maxRequestLength="2000000"/>
<bindings>
<webHttpBinding>
<binding maxBufferSize="65536"
maxReceivedMessageSize="2000000000"
transferMode="Streamed">
</binding>
</webHttpBinding>
</bindings>
我正在查看您提到的博客,稍后会回复您。至于其他参数,就像我说的,我用这个api调用发送了其他数据,正如你们在FBPostData类中看到的。这只适用于我删除文件上传的文件字节数组。这是非常有用的文章,但仍然没有运气。我使用的是webinvoke,但现在我使用的是SOAP instaed,因为steam不能用REST完成?现在我的发球一点也没有被击中。可能是我把配置搞砸了。你能帮我一下吗?如果有人怀疑我没有付出努力,那么你可以看到这已经是一整天了,我仍然面临着同样的问题。在这里发布之前,我又搜索了一天。可能是正确方向上的一点指引。有人吗?你需要发布更多的代码示例-你调整了MaxBufferSize和maxArrayLength吗?是的,我增加了MaxBufferSize和maxReceivedMessageSize。网上有很多令人困惑和矛盾的信息(至少对于像我这样的初学者来说)。就像在你提到的一个博客中说的,“如果使用流,WCF不会让你有任何其他参数”。是的。您还可以将参数传递给Webinvoke,当然也可以使用REST发送流。我现在正在使用多部分文件上传。似乎正在工作,但没有完全测试。将在此更新,并对迟交的回复表示歉意。我也在安卓方面工作,其间有一个周末:)我已经给出了这个问题的解决方案。谢谢你的帮助和跟进