WCF "Raw" programming model (Web) – receiving arbitrary data


The previous post mentioned how to return arbitrary data from WCF services. To receive data, however, there is one extra step, which I’ll try to explain here.

Like returning arbitrary data, the key for accepting arbitrary (in any format) data is for a method to have a parameter with type System.IO.Stream. This parameter needs to be the single parameter which is passed in the body of the request. By that we mean that the operation can have other parameters beside the Stream one, as long as they’re used in the address (UriTemplate) for the operation. For example, this program below will simulate an UploadFile operation:

public class BlogPostRaw2
{
    [
ServiceContract]
    public interface ITest
    {
        [
OperationContract, WebInvoke(UriTemplate = “UploadFile/{fileName}”)]
        void UploadFile(string fileName, Stream fileContents);
    }
    public class Service : ITest
    {
        public void UploadFile(string fileName, Stream fileContents)
        {
            byte[] buffer = new byte[10000];
            int bytesRead, totalBytesRead = 0;
            do
            {
                bytesRead = fileContents.Read(buffer, 0, buffer.Length);
                totalBytesRead += bytesRead;
            }
while (bytesRead > 0);
            Console.WriteLine(“Uploaded file {0} with {1} bytes”, fileName, totalBytesRead);
        }
    }
    public static void Test()
    {
        string baseAddress = “http://” + Environment.MachineName + “:8000/Service”;
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(
typeof(ITest), new WebHttpBinding(), “”).Behaviors.Add(new WebHttpBehavior());
        host.Open();
        Console.WriteLine(“Host opened”);

       
HttpWebRequest
req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + “/UploadFile/Test.txt”);
        req.Method =
“POST”;
        req.ContentType =
“text/plain”;
        Stream reqStream = req.GetRequestStream();
        byte[] fileToSend = new byte[12345];
        for (int i = 0; i < fileToSend.Length; i++)
        {
            fileToSend[i] = (
byte)(‘a’ + (i % 26));
        }
        reqStream.Write(fileToSend, 0, fileToSend.Length);
        reqStream.Close();
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        Console.WriteLine(“HTTP/{0} {1} {2}”, resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
        host.Close();
    }
}

Notice that the (POST) HTTP request was sent to http://machine_name:8000/Service/UploadFile/<name_of_the_file_to_be_uploaded>; on the body of the request were the file contents.

One important note about the line in bold about Content-Type: when returning arbitrary data, specifying the content type is advisable, but not (necessarily) required. When sending arbitrary data to WCF, it is required. That is because the WebMessageEncoder (the inner piece of WCF, which is created when the endpoint uses the WebHttpBinding), needs it to be able to decode the message.

So this appears to works fine, until I decided to send a XML file to the server (showing only part of the client code):

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + “/UploadFile/Test.xml”);
req.Method =
“POST”;
req.ContentType =
“text/xml”;
Stream reqStream = req.GetRequestStream();
string fileContents = “<hello>world</hello>”;
byte[] fileToSend = Encoding.UTF8.GetBytes(fileContents);
reqStream.Write(fileToSend, 0, fileToSend.Length);
reqStream.Close();
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Console.WriteLine(“HTTP/{0} {1} {2}”, resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);

When this request is sent to the server, the client gets a “400 Bad Request” response. A look at the server traces (enabled via instructions at http://msdn2.microsoft.com/en-us/library/ms733025.aspx) shows the following error:

System.InvalidOperationException: Incoming message for operation ‘UploadFile’ (contract ‘ITest’ with namespace ‘http://tempuri.org/’) contains an unrecognized http body format value ‘Xml’. The expected body format value is ‘Raw’. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.

This is right on target. Basically, as I mentioned before, the WebMessageEncoder is actually composed of three “inner” encoders: XML, JSON and Raw. For content-types which map to the first two, the requests will be processed by then; only if neither the XML or the JSON encoder can process the content-type, the Raw will be used. For the first example it worked fine, since text/plain content cannot be processed by XML or JSON. So we need a way to “force” the encoder to always use Raw. As mentioned in the exception, the WebContentTypeMapper is the solution. The code below can now handle all content-types on request (modified parts in bold). Notice that we need to use a custom binding, since the mapper is only accessible via the WebMessageEncodingBindingElment directly, not in the standard WebHttpBinding.

public class BlogPostRaw2
{
    [
ServiceContract]
    public interface ITest
    {
        [
OperationContract, WebInvoke(UriTemplate = “UploadFile/{fileName}”)]
        void UploadFile(string fileName, Stream fileContents);
    }
    public class Service : ITest
    {
        public void UploadFile(string fileName, Stream fileContents)
        {
            byte[] buffer = new byte[10000];
            int bytesRead, totalBytesRead = 0;
            do
            {
                bytesRead = fileContents.Read(buffer, 0, buffer.Length);
                totalBytesRead += bytesRead;
            }
while (bytesRead > 0);
            Console.WriteLine(“Uploaded file {0} with {1} bytes”, fileName, totalBytesRead);
        }
    }
    public class MyMapper : WebContentTypeMapper
    {
        public override WebContentFormat GetMessageFormatForContentType(string
contentType)
        {
            return WebContentFormat.Raw;
// always
        }
    }
    static Binding
GetBinding()
    {
        CustomBinding result = new CustomBinding(new WebHttpBinding
());
        WebMessageEncodingBindingElement webMEBE = result.Elements.Find<WebMessageEncodingBindingElement
>();
        webMEBE.ContentTypeMapper =
new MyMapper
();
        return
result;
    }
    public static void Test()
    {
        string baseAddress = “http://” + Environment.MachineName + “:8000/Service”;
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(
typeof(ITest), GetBinding(), “”).Behaviors.Add(new WebHttpBehavior());
        host.Open();
        Console.WriteLine(“Host opened”);

        HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + “/UploadFile/Test.xml”);
        req.Method =
“POST”;
        req.ContentType =
“text/xml”;
        Stream reqStream = req.GetRequestStream();
        string fileContents = “<hello>world</hello>”;
        byte[] fileToSend = Encoding.UTF8.GetBytes(fileContents);
        reqStream.Write(fileToSend, 0, fileToSend.Length);
        reqStream.Close();
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        Console.WriteLine(“HTTP/{0} {1} {2}”, resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
        host.Close();
    }
}

 


Comments (34)

  1. eggshelly says:

    Awesome article Carlos – it helped me almost solve my seeming insurmountable wcf file upload problem.

    But of course, I have a problem:

    I’ve implemented your code from above but I’m trying to use the browser as a client.  I used YUI from a simple HTML page to submit a form containing a file upload control.  When I upload any kind of file, the web service receives the request but when it saves the file, the end result is surrounded with meta-data:

    —————————–1654974419512

    Content-Disposition: form-data; name="upFile"; filename="amazon phone number.txt"

    Content-Type: text/plain

    [file content here – perfectly reproduced (if I remove the surrounding junk)]

    —————————–1654974419512–

    So there must be some difference between how the POST is coming across from YUI and how it’s coming across from the HttpWebRequest class, but I can’t figure out what that is.  Any ideas?

    My web config is set up like:

     <system.serviceModel>

       <behaviors>

         <endpointBehaviors>

           <behavior name="TestBehavior">

             <webHttp/>

           </behavior>

         </endpointBehaviors>

       </behaviors>

       <bindings>

         <webHttpBinding>

           <binding name="fileUploadCapable" maxReceivedMessageSize="500000000" transferMode="Streamed"/>

         </webHttpBinding>

       </bindings>

       <services>

         <service name="Test">

           <endpoint address="ajax" behaviorConfiguration="TestBehavior"

             binding="webHttpBinding" bindingConfiguration="fileUploadCapable"

             contract="ITest" />

         </service>

       </services>

     </system.serviceModel>

    And my service has the following interface:

           [OperationContract]

           [WebInvoke(UriTemplate = "UploadFile?upFile={fileName}")]

           void UploadFile(string fileName, Stream fileContents);

    and implementation:

           public void UploadFile(string fileName, Stream fileContents)

  2. BlogSvc News says:

    I’ve put a new release up on codeplex. This release includes an implementation of Atom…

  3. jimblust says:

    Carlos, this is a great example, and I have it working in a console app. I’ve managed to modify the example so that the service can be hosted in IIS, but my tests indicate that IIS always waits to receive the entire request before handing it off to WCF for processing. Do you know if there’s any way to make IIS hand off the streaming request to the service as soon as the request starts coming in? I’ve also asked on the WCF msdn forum here:

    http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/cfe625b2-1890-471b-a4bd-94373daedd39

  4. Philipp Sumi says:

    Carlos,

    Thanks for the snippet (and your efforts in general – your blog is a great resource!).

    I’m having a few problems with this one though. For starters, I noticed that – although streaming is configured for my services – my service method is not hit unless the GetResponse method is being invoked, causing the client to gather the whole data in memory.

    The resolution seems to be to set the AllowWriteStreamBuffering to false (SendChunked didn’t help at all), but strange enough, this completely breaks the sample. While the memory consumption on the client stays low this time, the service method is still not hit (which bears the question what happens with the streamed data), and the client finally causes an exception as soon as GetResponse is being invoked:

    System.Net.WebException: This request requires buffering data to succeed.

    I tried to fiddle with the parameters but given my service is not invoked anyway until GetResponse (rather than every time I write to the request stream), I think the problem starts earlier than with GetResponse.

    Any advice on this?

  5. cvalero says:

    jimblust, could you provide your changes tolet this sniped be deployed under iis. I have the sample running as a console application, but deploying it to IIS hasn’t been successfully. I am getting a bad request.

  6. Omar Qadan says:

    if we host the service on IIS we should change the host tag to look like this

    <%@ ServiceHost Language="C#" Debug="true" Service="SADADNET.Services.Receiver.RouterService" Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>

    or if you are using Windsor to Activate you service it should look like this

    <%@ ServiceHost Language="C#" Debug="true" Service="SADADNET.Services.Receiver.RouterService" Factory="Castle.Facilities.WcfIntegration.WindsorServiceHostFactory`1[[Castle.Facilities.WcfIntegration.Rest.RestServiceModel,

    Castle.Facilities.WcfIntegration]], Castle.Facilities.WcfIntegration"%>

  7. Mitani says:

    Is it possible to use WebInvoke using the Asynchronous Programming Model.

    I tried the following but contract

           [OperationContract]

           [WebInvoke(UriTemplate = "/", Method="POST", BodyStyle = WebMessageBodyStyle.WrappedRequest)]

           IAsyncResult BeginWebPost(XElement input, AsyncCallback callback, object userState);

           Stream EndWebPost(IAsyncResult asyncResult);

    but I keep getting this exception

    System.Runtime.Serialization.SerializationException occurred

     Message=OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'BeginWebPost' and namespace 'http://tempuri.org/&#39;. Found node type 'Element' with name 's:Envelope' and namespace 'schemas.xmlsoap.org/…/&

     Source=System.ServiceModel

     StackTrace:

          at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)

     InnerException:

    I have no control over the client. The client will be sending SOAP requests.

  8. @Mitani, try using Bare (not WrappedRequest) so you'll be able to receive any XML (including SOAP) requests in your operation. WebInvoke should work in this case. But at this point you'll have to parse the XML yourself (since you're using REST, not SOAP) and decide what to return to the caller.

  9. Johan Nilsson says:

    Hi,

    I get the same problem as "eggshelly" describes and no one seams to have answered his/her question. Does anyone know what to do?

    I'm receiveing an image and cannot just strip away the surrounding text, since it will not end up with a valid image.

    Regards,

    Johan

  10. @Johan, in this case the client isn't sending "raw" file, it's sending it in an encoded way. WCF doesn't provide any out-of-the-box way of extracting the file, although based on the example of eggshelly it doesn't seem too hard – parse the separator (———————-12345678), the "header" lines (Content-Type, Content-Disposition), and then read the file until you find the separator at the end.

  11. vicky says:

    I get this error when i open the host:

    For request in operation UploadFile to be a stream the operation must have a single parameter whose type is Stream.

    ..can some one please let me know if it is possible to have more than one parameter in your operation if you have stream as one 0f the parameters

  12. vicky, do you get this error when you open the host, or when you browse to the service address? If the latter, you may be hitting a known bug in WCF (the metadata generation code in WCF isn't aware of the special case for Stream parameters composed with UriTemplate ones). If the former, make sure that all non-Stream parameters in the operation are bound to the UriTemplate – the WCF runtime will treat all of them as URL parameters (i.e., extract them from the request URI), and deliver all the request body to the Stream parameter.

  13. WCFRestUser says:

    Hi, So is there a way to POST XML to a WCF REST service in .NET 4.0 or should we still use raw streams? Also if raw stream is used to parse this data: <User><Id>SomeID</Id></User> , can this data be then mapped or "deserialized" back into an entity (for e.g. the following)?

    public class User

    {

     public string Id { get; set;}

    }

  14. WCFRestUser, if you want to receive XML, then you don't need to use raw streams – WCF has some built-in support for it. If you want to work in an untyped way, you can just replace the Stream parameter with an XElement (or XmlElement), and the whole request body will be mapped to it:

    [OperationContract]

    void ReceiveXml(XElement input);

    Or you can also map it to a "strong" type. In your case, you'd have something like

    [WebInvoke]

    [XmlSerializerFormat]

    void ReceiveXml(User User);

  15. WCFRestUser says:

    Thanks for the Response. I have been trying to write a simple WCF REST POST using VS 2008 SP1 using Jmeter for GET and POST without any luck. The GET works but the POST fails.

    Assuming Sevice.svc is wired to the ServiceHandler.

    This works:

    GET http://domainname/Service.svc/users

    returns:

    <User xmlns="ns"><ID>MyId</ID>..</User>

    This returns 400 Bad Request. I am unable to hit the breakpoint on the AddNewUser method.

    POST http://domainname/Service.svc/users

    POST Data:

    <User xmlns="ns"><ID>MyId</ID>..</User>

    ========================================================

    [CollectionDataContract(Name = "Users", Namespace = "ns")]

       public class Users : List<User>

       {

       }

       [DataContract(Name = "User", Namespace = "")]

       public class User

       {

           [DataMember(Name = "ID", Order = 1)]

           public string m_Id;

           [DataMember(Name = "FirstName", Order = 2)]

           public string m_FirstName;

           [DataMember(Name = "LastName", Order = 3)]

           public string m_LastName;

           [DataMember(Name = "Email", Order = 4)]

           public string m_Email;

       }

       [ServiceContract]

       public interface IServiceHandler

       {

           [OperationContract]

           [WebGet(UriTemplate = "/users", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml)]

           [Description("Gets All the Users.")]

           Users GetAllUsers();

           [OperationContract]

           [WebInvoke(UriTemplate = "/users",

               BodyStyle = WebMessageBodyStyle.Bare,

               RequestFormat = WebMessageFormat.Xml,

               ResponseFormat = WebMessageFormat.Xml,

               Method = "POST")]

           [Description("Creates a new User.")]

           User AddNewUser(User user);

       }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

       public sealed class ServiceHandler : IServiceHandler

       {

    private static Users s_Users

           {

               get

               {

                   return new Users()

               {

                   new User() { m_Email ="Test1@test1.com", m_FirstName="FirstNaam1", m_Id="FirstId1", m_LastName="LastNAam1"},

                   new User() { m_Email ="Test2@test2.com", m_FirstName="FirstNaam2", m_Id="FirstId2", m_LastName="LastNAam2"}

               };

               }

           }

           public Users GetAllUsers()

           {

               return s_Users;

           }

    public User AddNewUser(User user)

           { return null;

    }

    }

  16. If you get a "Bad Request", you should enable tracing at the server (msdn.microsoft.com/…/ms733025.aspx). The traces will have an exception explaining why the request was considered to be "bad".

  17. WCFRestUser says:

    I will try to enable the tracing. On a different note, what happens when we want products by both Id and Name? The scenarios below will give WCF 500 errors as these will resolve to the same URITemplates, right?

    /Products/{id}

    /Products/{name}

    Even the querystrings wont work in this case:

    /Products?id={id}

    /Products?name={name}

  18. In this case you'll need to either have a different template ("/Products/{id}" and "/ProductsByName/{name}), or have both on the query string (/Products?id={id}&name={name}). In the latter case, you'd choose how to filter the products depending on which parameter is populated (any parameter not passed to the query string will be null for ref types).

    The query string option which you mentioned (/Products?id={id} and /Products?name={name}) doesn't work because the operation for a request such as http://…/Products (no query string) would be ambiguous.

  19. WCFRestUser says:

    Thanks. I was thinking of either using this (notice the "Products" and "Product")

    /Products?id={id}

    /Product?name={name}

    OR use this:

    /Products/ProductId/{Id}

    /Products/ProductName/{name}

    Is there any design standard on this? For e.g. when to use a QS and when not to. I know the important thing would be to be consistent.

  20. Since the ID is (I suppose) some sort of primary key for the product, I've seen most cases where you have

    /Product/{id}

    Since this is the location of the product resource. Using a name is equivalent to a search operation in the resource collection of products, so I've seen things like

    /Products?name={name}

    But I don't know whether there is a cut and dry standard for this.

  21. Nic says:

    Thanks so much for this! Life saving work! (well, not quite, but close!)

    Cheers,

    -Nic

  22. James says:

    I thought this would be incredibly simple, but I must be missing something. I am trying to make a simple WCF POST request in conjunction with a UriTemplate. I have read numerous examples where people use a stream paramater as the last paramater, and this is supposed to pick up the POST body. I can only get this to work if the stream is the only paramater.

    I've gone back to basics with a simple Hello World service.

    Here is my code on the client

       static string Test()

       {

           HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://localhost:1884/MyAPI/Service.svc/HelloWorld&quot;);

           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();

       }

    And this is the code on the service

       [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));

       }

    This all works fine. Then I make this change:

       [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));

       }

    And change the client code to hit HelloWorld/test/sometext

    I get a 500 Internal Server Error. I've tried about 10 different variations including using a ?key=value type UriTemplate, returning strings instead of streams etc, and no luck.

    Feels like I'm missing some tiny little thing that is going to make this work, as I have seen countless examples of exactly this all over the web. Theirs works, mine doesn't.

    Any ideas?

  23. James says:

    Sorry about the double post, but I've got some more information. The 500 error I am getting is showing up in event viewer as:

    For request in operation UploadFile to be a stream the operation must have a single parameter whose type is Stream.

    Every non stream paramater is declared in the UriTemplate… this is driving me nuts!

  24. Hi James, I've created some code at http://codepaste.net/s5hwyv and http://codepaste.net/xtx3ho similar to your scenario and it worked out fine; take a look at the samples, and see if there is anything different from your code.

  25. James says:

    Success!

    I created a new WCF service, and copied all the code over from the old one. I remember this was the most common fix to unsolvable code mysteries back in my Uni days. Gotta love Visual Studio.

    Thanks for your help Carlos. Glad that 4 day headache has come to an end.

  26. hi all , can i upload the zip file ? says:

    hi all , can i upload the zip file ?

  27. You can upload zip files as well; as far as WCF is concerned, it's just a bunch of bytes coming over the wire, it doesn't care what format those bytes are in.

  28. Konstantin P says:

    Is there a way to enable raw request processing for individual OperationContracts?

    In general, I'm okay with using the DataContractJsonSerializer, but for some objects that are passed in as parameters to the OperationContact methods, I need to use JSON.NET. The problem is that in these cases, I don't want the client to have be aware that it should be setting Content-Type: text/plain instead of application/json (which is used in every other case).

  29. Jorge says:

    When trying this, I get a blank output from IE.

    When running fiddler, I can see the response properly, but I have noticed the following:

    The Content-Type reported is application/xml instead the value I have forced through

    req.ContentType = "application/octet-stream".Any suggestion? thanks in advance…;

  30. Hi Konstantin P, this setting is done at the encoder level, so that's not trivial to have a per-operation content-type mapper. You can still implement it, though, and I've done so at github.com/…/PerOperationContentTypeMapper (I'll write a post about it tomorrow, it will be online at blogs.msdn.com/…/supporting-raw-requests-for-individual-operations.aspx when it's published).

  31. Hi Jorge, I don't understand your problem. In the example shown in the post, the operation doesn't return anything, so it's expected that you won't see any response from the browser, but you'll still get the HTTP headers, which is likely what you see in Fiddler. Is that the case?

  32. Thank you!!   I realise this is a rather old post, but it was a becon after banging my head for hours trying to understand the BadRequest response i was getting.

  33. Pratap says:

    i am getting " For request in operation RecieveImage to be a stream the operation must have a single parameter whose type is Stream error. " while passing parameters with post url…

    but it is working if pass the stream and it is saving the image….

    I am unable to paste my code due to text length.

    Here i have posted my question please check it..

    stackoverflow.com/…/unable-to-upload-an-image-with-parameters-to-wcf-rest-service

    or

    social.msdn.microsoft.com/…/unable-to-upload-an-image-with-parameters-to-wcf-rest-service

  34. Karthik says:

    Please help me regarding following issse.

    By adding Factory ,I got to know issue with endpoint because . I am getting error as "Error in endpoint" .

    Code

    [WebInvoke(Method = "POST",

              ResponseFormat = WebMessageFormat.Json,

              RequestFormat = WebMessageFormat.Json,

              BodyStyle = WebMessageBodyStyle.Wrapped)]

           string Test(string msg);

    public string Test(string msg)

           {

               return msg;

           }

    Config

    <configuration>

     <system.web>

       <compilation debug="true" targetFramework="4.0" />

       <customErrors mode="Off"/>

     </system.web>

     <system.serviceModel>

       <behaviors>

         <endpointBehaviors>

           <behavior name="httpBehavior">

             <webHttp />

             <dataContractSerializer maxItemsInObjectGraph="2147483647" />

           </behavior>

         </endpointBehaviors>

         <serviceBehaviors>

           <behavior name="NotifyServiceBehavior">

             <serviceMetadata httpGetEnabled="true"/>

             <serviceDebug includeExceptionDetailInFaults="true"/>

           </behavior>

         </serviceBehaviors>

       </behaviors>

       <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

       <bindings>

         <webHttpBinding>

           <binding name="webHttpBindingWithJson" crossDomainScriptAccessEnabled="true" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">

             <readerQuotas

                     &nbsp;maxDepth=&quot;2147483647&quot;
    
                     &nbsp;maxStringContentLength=&quot;2147483647&quot;
    
                     &nbsp;maxArrayLength=&quot;2147483647&quot;
    
                     &nbsp;maxBytesPerRead=&quot;2147483647&quot;
    
                     &nbsp;maxNameTableCharCount=&quot;2147483647&quot; /&gt;
    

             <security mode="None" />

           </binding>

         </webHttpBinding>

       </bindings>

       <services>

         <service name="Notify.Service1" behaviorConfiguration="NotifyServiceBehavior">

           <endpoint address="" behaviorConfiguration="httpBehavior" bindingConfiguration="webHttpBindingWithJson" binding="webHttpBinding" contract="Notify.IService1" bindingName="LargeWeb" />

         </service>

       </services>

     </system.serviceModel>

     <system.webServer>

       <modules runAllManagedModulesForAllRequests="true"/>

       <httpProtocol>

         <customHeaders>

           <add name="Access-Control-Allow-Origin" value="*" />

           <add name="Access-Control-Allow-Headers" value="Content-Type" />

         </customHeaders>

       </httpProtocol>

     </system.webServer>

    </configuration>

Skip to main content