WCF Restful WS post方法和HTML表单

时间:2013-03-26 10:26:04

标签: javascript html .net wcf wcf-rest

我在IIS上发布了简单的.net restful Web服务:

    [OperationContract]
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "formTestGET?firstInput={firstInput}&socondInput={socondInput}")]
    string formTestGET(string firstInput, string socondInput);

    [OperationContract]
    [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "formTestPOST")]
    string formTestPOST(string testInput);

方法的实施:

 public string formTestGET(string firstInput, string socondInput)
        {
        try
            {
            return "First Input value: " + firstInput + " Second Input value: " + socondInput;
            }
        catch (Exception e)
            {
            return e.Message;
            }
        }

    public string formTestPOST(string testInput)
        {
        try
            {
            return "Post paramether value: " + testInput;
            }
        catch (Exception e)
            {
            return e.Message;
            }
        }

我的HTML格式:

   <form method="post" action="http://localhost/HTML5RestfulService/Service1.svc/formTestPOST">
        <fieldset>
        <legend>Form Post Request</legend>
            <input name="testInput"/>
            <button>Make Post Request</button>
        </fieldset> 
  </form>

我只想通过html表单使用此服务。我的POST方法有问题。当我用Ajax(来自java脚本)调用它时它工作正常,但是通过表单我无法得到响应。 我收到“400 Bad Request”作为错误。

当我想通过FORM调用它时,我应该以不同的方式配置我吗?

请提出任何建议。

1 个答案:

答案 0 :(得分:4)

如果你想从没有ECMAScript(JavaScript),Silverlight或Flash的基本形式调用WCF服务,那么我认为你应该遵循Cheng先生的建议,并将formTestPOST操作的输入参数更改为单个Stream参数。

有关详细信息,请参阅以下代码:

// File: IService1.cs
//       (Based on work by Milos, Shawn Eary, Steven Cheng, and 
//        Web Community)
// 
// References
// [1] - Cheng, Steven (MSFT); Bill2010
//       How would I do the following form POST with WCF REST?
//       MSDN Forums: August 12, 2010 
//       http://social.msdn.microsoft.com/Forums/vstudio/en-US/dde73561-29c0-4c34-b18a-990ae114b92c/how-would-i-do-the-following-form-post-with-wcf-rest
//       [Cited: September 27, 2013]
using System.ServiceModel;
using System.ServiceModel.Web; 
using System.IO; 

[ServiceContract]
public interface IService1
{   
   // To post a basic HTML Form to a WCF Operation, I *think* Mr. Cheng
   // of Microsoft suggests that users put WCF into "Raw Data Transfer"
   // Mode by replacing all input parameters with a single Stream [1]
   [OperationContract]
   [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "formTestPOST")]
   string formTestPOST(Stream testInput);
}

// File: Service1.cs
//       (Based on work by: Milos; Shawn Eary; all those listed 
//        in the References Section below; and, the Web Community)
// 
// References
// [1] - Brian; Coderer; Kopp, Darren; James; user1749204     
//       How do you get a string from a MemoryStream?
//       Stack Overflow: September 29, 2008 
//       http://stackoverflow.com/questions/78181/how-do-you-get-a-string-from-a-memorystream
//       [Cited: September 27, 2013]
// 
// [2] - Atlas, Mike; HaggleLad; Gravell, Marc
//       Parsing “multipart/form-data” in .NET/C#
//       Stack Overflow: November 11, 2009
//       http://stackoverflow.com/questions/1716868/parsing-multipart-form-data-in-net-c
//       [Cited: September 27, 2013]
//
// [3] - antscode 
//       Multipart Form Data Parser
//       CodePlex: 2009-2012
//       http://multipartparser.codeplex.com/SourceControl/list/changesets
//       [Cited: September 27, 2013]
// 
// [4] - Polidori, Lorenzo; Ed. S.; Woods, Jake
//       Uploading file from Flex to WCF REST Stream issues (how to decode multipart form post in REST WS)
//       Stack Overflow: January 20, 2012
//       http://stackoverflow.com/questions/5423031/uploading-file-from-flex-to-wcf-rest-stream-issues-how-to-decode-multipart-form
//       [Cited: September 27, 2013]
using System;
using System.IO; 
using System.Web; 

public class Service1 : IService1
{
   public string formTestPOST(Stream testInput)
   {
      // Get the post data out of the Stream testInput
      // Now that your form sucessfully fired this operation, you 
      // can use Brian's technique mentioned at [1] to convert the 
      // stream into a string
      StreamReader someReader = new StreamReader(testInput); 
      String theInput = someReader.ReadToEnd(); 

      // Unfortunately, various places on the internet seem to 
      // indicate that data that you now have in your string
      // theInput is multipart form data.  If you were willing
      // to use ASP.NET Compatibility Mode in your Interface, 
      // then you could have used the trick here mentioned by 
      // Mike Atlas and Mark Gravel in [2] but let's assume
      // you cannot use compatibilty mode.  Then you might 
      // try a multipart parser like the one written by antscode
      // at [3] or you can just do what I did and guess your 
      // way through.  Since you have a simple form, you can 
      // just guess your way through the parsing by replacing
      // "testInput" with nothing and UrlDecoding what is left.
      // That won't work on more complex forms but it works on 
      // this example.  You get some more backround on this 
      // and why UrlDecode is necessary at [4]
      theInput = theInput.Replace("testInput=", ""); 
      theInput = HttpUtility.UrlDecode(theInput); 
      return "Post paramether value: " + theInput;
   }
}