我认为这会非常简单,但我必须遗漏一些东西。我正在尝试与UriTemplate一起制作一个简单的WCF POST请求。我已经阅读了很多例子,其中人们使用流参数作为最后一个参数,这应该是接收POST主体。如果流是唯一的参数,我只能让它工作。
我已经通过简单的Hello World服务回归基础。
这是我在客户端上的代码
static string Test()
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://localhost:1884/MyAPI/Service.svc/HelloWorld");
req.Method = "POST";
req.ContentType = "text/plain";
Stream reqStream = req.GetRequestStream();
byte[] fileToSend = System.Text.UTF8Encoding.UTF8.GetBytes("sometext");
reqStream.Write(fileToSend, 0, fileToSend.Length);
reqStream.Close();
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
var sr = new StreamReader(resp.GetResponseStream());
return sr.ReadToEnd();
}
这是服务上的代码
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "HelloWorld")]
Stream HelloWorld(Stream content);
}
public Stream HelloWorld(Stream content)
{
var sr = new StreamReader(content);
string text = sr.ReadToEnd();
return new System.IO.MemoryStream(Encoding.UTF8.GetBytes("Hello World! " + text));
}
一切正常。然后我做了这个改变:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "HelloWorld/test/{test}")]
Stream HelloWorld(string test, Stream content);
}
public Stream HelloWorld(string test, Stream content)
{
var sr = new StreamReader(content);
string text = sr.ReadToEnd();
return new System.IO.MemoryStream(Encoding.UTF8.GetBytes("Hello World! " + text + test));
}
将客户端代码更改为HelloWorld / test / sometext
我收到500内部服务器错误。我尝试了大约10种不同的变体,包括使用?key = value类型UriTemplate,返回字符串而不是流等,而且没有运气。
感觉就像我错过了一些可以使这项工作变得微不足道的小东西,因为我已经在网上看到了无数的这样的例子。他们的工作,我的没有。
有什么想法吗?
答案 0 :(得分:2)
我不确定出了什么问题,但在尝试了所有内容之后,我通过创建一个新项目并将所有代码复制完毕来解决这个问题。从来没有弄清楚差异是什么,也许是有些东西被破坏了
编辑:最后我们发现我们必须在Service.svc中指定WebServiceHostFactory。默认情况下,这是新项目
答案 1 :(得分:0)
流式传输时,Stream必须是唯一的参数:http://msdn.microsoft.com/en-us/library/ms789010.aspx
您可以使用邮件标题:Add filename and length parameter to WCF stream when Transfermode = Stream
答案 2 :(得分:0)
您可以使用新的单文件WCF模型来配置和调整端点行为。我将您的合同和服务类合并到一个文件中,向您展示如何执行此操作。
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
namespace StreamService
{
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MergedEndpoint
{
[WebGet(RequestFormat = WebMessageFormat.Xml, UriTemplate = "Data/{someid}",
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public string GetData(string someid)
{
return string.Format("You entered: {0}", someid);
}
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, UriTemplate = "HelloWorld",
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public Stream HelloWorld1(Stream content)
{
var sr = new StreamReader(content);
string text = sr.ReadToEnd();
return new System.IO.MemoryStream(Encoding.UTF8.GetBytes("Hello World from single file! " + text));
}
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, UriTemplate = "HelloWorld/test/{testparam}",
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public Stream HelloWorld2(string testparam, Stream content)
{
var sr = new StreamReader(content);
string text = sr.ReadToEnd();
return new System.IO.MemoryStream(Encoding.UTF8.GetBytes("Hello World from single file! " + testparam+ text));
}
}
}
输入参数必须与方法参数同名。他们的类型也是字符串。如果你想要不同的输入参数,你需要进行转换。
您需要创建WCf项目并添加Global.asax文件以及此文件的路由信息。您可能需要添加对System.ServiceModel.Activation的引用以设置路由。 例如:
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("MergedEndpoint", new WebServiceHostFactory(), typeof(MergedEndpoint)));
}
您的客户端代码对内容类型进行了一处更改。
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://localhost:55166/MergedEndpoint/HelloWorld/test/234");
req.Method = "POST";
//req.ContentType = "text/plain";
req.MediaType = "HTTP/1.1";
req.ContentType = "application/json; charset=utf-8";
Stream reqStream = req.GetRequestStream();
byte[] fileToSend = System.Text.UTF8Encoding.UTF8.GetBytes("sometext");
reqStream.Write(fileToSend, 0, fileToSend.Length);
reqStream.Close();
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
var sr = new StreamReader(resp.GetResponseStream());
string outp = sr.ReadToEnd();
Console.WriteLine("Response:"+outp);
即使将原始内容设置为Json类型,您仍然可以读取原始内容。