Hi following is Operation Contract , where im trring to insert some data , so im using WebInvoke POST method, but when im calling this method its giving me an error saying "Method not allowed"
do i have to change any configuration settings for allowing POST calls in web.config?
[OperationContract]
[WebInvoke(
UriTemplate = "/Album/PostData?name={name}&CrBy={createdBy}" ,
Method="POST")]
void PostUserData(string name, string createdBy);
and im calling my service as below
http://localhost:2170/MySampleService.svc/xml/Album/PostData?name=devpost&CrBy=postadmin
Well you should use Method="GET" if you want to call your service like this. Also the definition of the method name and arguments don't seem to match your query string.
If you want to use POST verb then you need to send a POST request and you will not be able to invoke the service by directly typing the url in the browser.
you need to add in web.config
1.
<endpoint address="customBinding" binding="customBinding" bindingConfiguration="basicConfig" contract="WcfRest.IService1"/>
2.
<bindings>
<customBinding>
<binding name="basicConfig">
<binaryMessageEncoding/>
<httpTransport transferMode="Streamed" maxReceivedMessageSize="67108864"/>
</binding>
</customBinding>
</bindings>
Change your method in the interface as
public class InputClass
{
public string Name{get;set;}
public string CreatedBy{get;set}
}
[OperationContract]
[WebInvoke(
UriTemplate = "PostUserData" ,
Method="POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json))]
void PostUserData(InputClass input);
See the link for more info.http://fszlin.dymetis.com/post/2010/05/10/Comsuming-WCF-Services-With-Android.aspx
Are you calling your service from javascript in a browser?
Does the html page reside in the same domain as the wcf service?
If they are not in the same domain, then I would say that it is a cross-site-scripting issue. I belive GET is allowed cross-sites, but POST are not. http://en.wikipedia.org/wiki/JSONP would be a solution, if it's supported server-side (by WCF)
Related
I'm trying to implement a WCF client in a VS2005 project. In VS2010 it is all working fine, because I just can add the service reference. For the VS2005 I've builded the .config and the Service1.cs with the svcutil. The two files are added in the project and I also added the service reference as a web reference.
Further you find the two files of that were generated.
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="SDTRfServerClass.WCFService.WSHttpBinding_IService1" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.0.102:8732/Design_Time_Addresses/Calc/Service1/"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="SDTRfServerClass.WCFService.IService1" name="WSHttpBinding_IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
This is the app.config which I also tried to change to web.config, but that doesn't make any difference.
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName = "IService1")]
public interface IService1
{
[System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService1/Add", ReplyAction = "http://tempuri.org/IService1/AddResponse")]
double Add(double n1, double n2);
[System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService1/Substract", ReplyAction = "http://tempuri.org/IService1/SubstractResponse")]
double Substract(double n1, double n2);
[System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService1/Multiply", ReplyAction = "http://tempuri.org/IService1/MultiplyResponse")]
double Multiply(double n1, double n2);
[System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService1/Divide", ReplyAction = "http://tempuri.org/IService1/DivideResponse")]
double Divide(double n1, double n2);
}
This is a part of the Service1.cs.
When I try to call the service with the following code I get the error "Could not find the endpointelement with the name WSHttpBinding_IService1 and contract IService1 in the configuration part of the ServiceMode-client. This can be caused if the configuration of the applicaton is not found or that there was found an endpoint which equalize the name.
I've tried to change the name with the full solution name at all places.
Does anyone as a solution?
client = new Service1Client("WSHttpBinding_IService1");
double result = client.Add(Double.Parse("2"), Double.Parse("4"));
I also tried to use the plug-in for VS2005 to add service reference which create a .map and a .cs file, but I'm keep getting the same error.
I think you have some typo problem or you have wrong namespace because error means that .NET cannot find information about your endpoint.
Try post your complete web.config and I've look at it
Or you can use dynamic channel factory like this and don't worry about linking to your web.config
WSHttpBinding myBinding = new WSHttpBinding();
//define endpoint url (where service is deployed)
EndpointAddress myEndpoint = new EndpointAddress("http://192.168.0.102:8732/Design_Time_Addresses/Calc/Service1/"); //change to real endpoint
//Use channel factory instead of generated one
ChannelFactory<IService1> myChannelFactory = new ChannelFactory<IService1>(myBinding, myEndpoint); //Change to you WCF interface
IService1 myServiceClient = myChannelFactory.CreateChannel();
//and call it
var result = myServiceClient.Add(1,1); //input to your method
//other methods
((IClientChannel)myServiceClient).Close();
myChannelFactory.Close();
I've been trying to create a simple WCF RESTful web service, but it seems to work only in SOAP mode. I'm hosting my service with the local IIS.
It looks really standard:
[ServiceContract]
public interface IMyService
{
[OperationContract]
Guid Login(string username, string password);
...
and:
public class MyService : IMyService
{
[WebGet(UriTemplate = "login?user={user}&password={password}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
public Guid Login(string username, string password)
{
return Guid.Empty;
}
I also included the behavior in the config file and was using it in:
<endpoint address="" binding="webHttpBinding" contract="MyService" behaviorConfiguration="webHttp"/>
according to all of the examples I know...
Now the thing is when invoking the login from a stub client which uses ServiceReference, it looks just fine in Fiddler, but it is SOAPy.
From some reason I cannot invoke my service in a RESTy way, even the /help seems to return a 400 Bad Request.
(I'm invoking http://localhost:8080/MyService.svc/help or /login etc.)
What is preventing the REST to take action?
Thanks in advance :)
Edit: I found an answer.
It turns out one must define Routings...
After adding this to Global.asax :
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("MyService",
new WebServiceHostFactory(), typeof(MyService)));
}
It went through just fine.
Plus I earned that the ".svc" is now not part of the URL.
Your code looks good to me. Can you try couple of things
[OperationContract]
[WebGet(UriTemplate = "/Login/{username}/{password}", ResponseFormat = WebMessageFormat.Xml)]
Guid Login(string username, string password);
At the same time please remove the WebGet attribute from MyService.Login function.
-OR-
Put this block in your web.config under system.web
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
Hope this helps.
I had the same issue
the reason was my posting xml had the below on top
<?xml version="1.0" encoding="utf-16"?>
I removed it and it just worked!
I have a WCF service with custom binding, hosted in IIS (IIS Express in development) with following service contract:
[ServiceContract]
public interface IServer
{
[OperationContract]
StreamCollection GetStreams(Guid poolKey);
[OperationContract]
PoolCollection GetPools();
[OperationContract]
StreamEntity GetStream(Guid poolKey, string localIndex);
}
It works OK (from client and also I can see it's metadata discovered ok in WCFTestClient).
I have to expose its functionality as REST, so I created a new contract as below
[ServiceContract]
public interface IRestServer
{
[OperationContract(Name="GetStreamsREST")]
[WebGet(UriTemplate = "pool/{poolKey}/streams")]
StreamCollection GetStreams(string poolKey);
[OperationContract(Name = "GetPoolsREST")]
[WebGet(UriTemplate = "pools")]
PoolCollection GetPools();
[OperationContract(Name = "GetStreamREST")]
[WebGet(UriTemplate = "pool/{poolKey}/stream/{localIndex}")]
StreamEntity GetStream(string poolKey, string localIndex);
}
I have both interfaces implemented in the same service class.
The web.config file is
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="CustomBinding">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="655360" />
</binding>
</customBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyServ.Server.Server">
<endpoint address="" binding="customBinding" bindingConfiguration="CustomBinding" contract="MyServ.Server.IServer" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="rest" behaviorConfiguration="webHttp" binding="webHttpBinding" contract="MyServ.Server.IRestServer" />
</service>
</services>
However, when I browse to access the service using rest, witha url like
http://localhost:<myport>/Service.svc/pools
http://localhost:<myport>/Service.svc/pool/somekey/streams
http://localhost:<myport>/Service.svc/pool/somekey/streams
I get error 404.
I put a break-point in some methods and attached debugger to IIS process, but it seems nothing gets called.
If I check the service metadata with WCFTestClient, it just sees IService, but not IRestService. Is this normal? EDIT: Yes, it seems it is (check this)
Thanks for any suggestion.
REST endpoints do not expose metadata in a way which can be consumed by the WCFTestClient, which explains why you can't access it. And the address you're browsing is incorrect, since you specified the endpoint address for the REST endpoint as "rest", you need to access them in something like
http://localhost:port/Service.svc/rest/pool/myPoolKey/streams
http://localhost:port/Service.svc/rest/pools
http://localhost:port/Service.svc/rest/myPoolKey/stream/1
Another thing: the Name attribute in the [OperationContract] attribute doesn't matter for REST endpoints, so you can drop it (it doesn't hurt having it there, though). Also, if you're using .NET 4.0, you don't even need the [OperationContract] attribute at all, given that you already have [WebGet], so your interface can be defined as
[ServiceContract]
public interface IRestServer
{
[WebGet(UriTemplate = "pool/{poolKey}/streams")]
StreamCollection GetStreams(string poolKey);
[WebGet(UriTemplate = "pools")]
PoolCollection GetPools();
[WebGet(UriTemplate = "pool/{poolKey}/stream/{localIndex}")]
StreamEntity GetStream(string poolKey, string localIndex);
}
Are you able to post your code on how you are calling the WCF service? I had a similar problem the other day where the client app was calling the page with a HTTP POST instead of a HTTP GET, and thus getting a 404 error.
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GuessWhat")]
vs
[WebGet(UriTemplate = "/GuessWhat/{variable}", ResponseFormat = WebMessageFormat.Json)]
Im not sure if your service has this or not but make sure the service that is implementing your Service Contract has this attribute.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
Thanks all for all suggestions.
However, I solved the issue finally.
The problem is I don't know still what was the problem, but I decided to take a different and more "clean" way.
So what I did was to create a different service SVC file, RestServer, where I implemented the REST methods
And I modified the settings in web config to have two different services, one for original one (pure WCF) and one for REST one, as below
<service name="MyServ.Server.RestServer" >
<endpoint address="" name="RESTEndpoint" behaviorConfiguration="webHttp" binding="webHttpBinding" contract="MyServ.Server.IRestServer" />
</service>
And this did the trick.
Actually, I should use this approach from the very beginning, to comply with single responsability principle ...
Editing this to refocus on the actual issue. I've preserved the origional question at the bottom of the message but changing the title and content to reflect what was really happening.
I need to override the maxReceivedMessageSize for a WCF service added to an MVC3 project via the ServiceRoute mechanism. Specifing the binding in the web.config doesn't work. How does one do this.
Initial question is below this line but is misleading based on lots of false positives I was seeing.
Hi I have used some examples to add a file streaming upload service to my MVC3 project. If I use the default bindings (i.e., not defined in web.config) the service works as long as I don't exceed the 64k default size. When I try and define my own binding to increase the size I get a content-type mismatch in my trace and a HTTP415 Unsupported Media Type in the response. I'm trying to call this via fiddler via HTTP and am not using a WCF client.
Here is the error in the trace:
Content Type image/jpeg was sent to a service expecting multipart/related;type="application/xop+xml". The client and service bindings may be mismatched.
Here is the web.config service model section
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="NewBehavior0" />
</endpointBehaviors>
</behaviors>
<services>
<service name="AvyProViewer.FileService">
<endpoint address="UploadFile" binding="basicHttpBinding" bindingConfiguration=""
contract="AvyProViewer.FileService" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<bindings>
<basicHttpBinding>
<binding name="NewBinding0" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Mtom" transferMode="StreamedRequest">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
Here is the service:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class FileService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "UploadFile")]
public string UploadFile(Stream fileStream)
{
string path = HostingEnvironment.MapPath("~");
string fileName = Guid.NewGuid().ToString() + ".jpg";
FileStream fileToupload = new FileStream(path + "\\FileUpload\\" + fileName, FileMode.Create);
byte[] bytearray = new byte[10000];
int bytesRead, totalBytesRead = 0;
do
{
bytesRead = fileStream.Read(bytearray, 0, bytearray.Length);
totalBytesRead += bytesRead;
} while (bytesRead > 0);
fileToupload.Write(bytearray, 0, bytearray.Length);
fileToupload.Close();
fileToupload.Dispose();
return fileName;
}
}
And here is where I expose it in my MVC3 routes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(new ServiceRoute("FileService", new WebServiceHostFactory(), typeof(FileService)));
. . .
}
I think the issue is with the mtom declaration for messageEncoding in your binding. Try changing messageEncoding to Text.
Answer ended up being a combination of three different stack overflow posts. None by themselves solved the question but each provided crucial clues as to what was happing.
It seems that if you add a ServiceRoute the web.config binding information is ignored. This SO post clued me in to what seems to be undocumented behavior of this function: Unable to set maxReceivedMessageSize through web.config
I then used this post to determine how to programatically override the maxreceivedmesssagesize for the binding: Specifying a WCF binding when using ServiceRoute.
Unfortunately the code form #2 didn't work out of the box (not sure if the binding behavior for ServiceRoute has changed or what makes the difference). Turns out that if you specify a ServiceRoute its automatically created as a CustomBinding which can't be cast to the WebHTTPBinding type used in #2. So this post: How to set the MaxReceivedMessageSize programatically when using a WCF Client? helped me determine how to change the code in #2 to add this capability to a custom binding.
I’m having a WCF REST service hosted in IIS using .NET 4 RC. The POST calls to the service are serialized using JSON. Everything works fine until the size of one of the DataMember (string) is longer than 8K. In this case I receive the error described below indicating the MaxStringContentLength has been exceeded. The maxStringContentLength attribute for the endPoint has been increased and it is correctly read from the config file.
Web config is:
<services>
<service name="MyServiceServer" >
<endpoint address="http://localhost/MyService" kind="webHttpEndpoint" endpointConfiguration="serviceEndPoint" contract="IMyService">
</endpoint>
</service>
</services>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="serviceEndPoint" maxReceivedMessageSize="2048000" maxBufferSize="2048000" maxBufferPoolSize="0">
<readerQuotas maxStringContentLength="2048000" maxArrayLength="2048000" maxDepth ="65000"/>
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
IMyService interface is defined as:
public interface IMyService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/request", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
void MyMehod(<Class Type> obj);
}
Complete Error Message is:
“The server encountered an error processing the request. The exception message is 'There was an error deserializing the object of type . The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader.'. See server logs for more details. The exception stack trace is: at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName) at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.DeserializeRequest(Message message, Object[] parameters) at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters) at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)”
This works, just make sure to have a full absolute URL as your endpoint address. If you get crafty and try to use a relative path, or if you omit .svc it will bomb with the strange reader quota error once the request gets too large --
I would file this under a Bug for WCF because either:
relative URLs should be disallowed (and an appropriate exception thrown)
or
the reader quota should work with relative paths as well
Insert into your web.config:
<configuration>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingConfig">
<readerQuotas maxStringContentLength="2048000" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
and insert attribute bindingConfiguration="webHttpBindingConfig" into your endpoint
I had similar problems but with .NET 3.5
I had no problems on the server log, so the problem was on the client.
Seems that the configuration with the max values increased was not read and used...
So I solved passing the name of the endpoint EXPLICITLY in the constructor of the WebChannelFactory, using another overload.
WAS:
WebChannelFactory<IWKRestTest> factory = new WebChannelFactory<IWKRestTest>(new Uri(XXX));
factory.Credentials.UserName.UserName = K_USERNAME;
factory.Credentials.UserName.Password = K_PASSWORD;
IWKRestTest proxy = factory.CreateChannel();
IS:
WebChannelFactory<IWKRestTest> factory = new WebChannelFactory<IWKRestTest>("IWKRestTestService");
and in the app.config there's:
The Uri is indicated in the endpoint node but there you find also the bindingConfiguration and so on, so all the new increased limits now works.