使用Uri模板进行简单的WCF POST

时间:2011-10-10 08:16:32

标签: wcf http-post

我认为这会非常简单,但我必须遗漏一些东西。我正在尝试与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,返回字符串而不是流等,而且没有运气。

感觉就像我错过了一些可以使这项工作变得微不足道的小东西,因为我已经在网上看到了无数的这样的例子。他们的工作,我的没有。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

我不确定出了什么问题,但在尝试了所有内容之后,我通过创建一个新项目并将所有代码复制完毕来解决这个问题。从来没有弄清楚差异是什么,也许是有些东西被破坏了

编辑:最后我们发现我们必须在Service.svc中指定WebServiceHostFactory。默认情况下,这是新项目

答案 1 :(得分:0)

答案 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类型,您仍然可以读取原始内容。