c# - WCF method call from browser returns 400 bad request -
i using asp.net 3.5 c# in visual studio 2008. naive wcf. have created sample wcf application , run on asp.net development server in visual studio. calling getdata() method i.e. auto-generated while creating applicaiton , getting 400 bad request. have tried lot result frustrating.
my interface iservice1.cs below :
using system; using system.collections.generic; using system.linq; using system.runtime.serialization; using system.servicemodel; using system.text; using system.servicemodel.web; using system.servicemodel.activation; namespace wcfservice1 { // note: if change interface name "iservice1" here, must update reference "iservice1" in web.config. [servicecontract] public interface iservice1 { [operationcontract] [webinvoke(requestformat=webmessageformat.json,responseformat=webmessageformat.json,method="get",uritemplate="/getdata/{}")] string getdata(int value); [operationcontract] compositetype getdatausingdatacontract(compositetype composite); // todo: add service operations here } // use data contract illustrated in sample below add composite types service operations. [datacontract] public class compositetype { bool boolvalue = true; string stringvalue = "hello "; [datamember] public bool boolvalue { { return boolvalue; } set { boolvalue = value; } } [datamember] public string stringvalue { { return stringvalue; } set { stringvalue = value; } } } } and class service1.svc.cs file below :
using system; using system.collections.generic; using system.linq; using system.runtime.serialization; using system.servicemodel; using system.text; namespace wcfservice1 { // note: if change class name "service1" here, must update reference "service1" in web.config , in associated .svc file. public class service1 : iservice1 { public string getdata(int value) { return string.format("you entered: {0}", value); } public compositetype getdatausingdatacontract(compositetype composite) { if (composite.boolvalue) { composite.stringvalue += "suffix"; } return composite; } } } and web.config below :
<?xml version="1.0"?> <!-- note: alternative hand editing file can use web admin tool configure settings application. use website->asp.net configuration option in visual studio. full list of settings , comments can found in machine.config.comments located in \windows\microsoft.net\framework\v2.x\config --> <configuration> <configsections> <sectiongroup name="system.web.extensions" type="system.web.configuration.systemwebextensionssectiongroup, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"> <sectiongroup name="scripting" type="system.web.configuration.scriptingsectiongroup, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"> <section name="scriptresourcehandler" type="system.web.configuration.scriptingscriptresourcehandlersection, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35" requirepermission="false" allowdefinition="machinetoapplication"/> <sectiongroup name="webservices" type="system.web.configuration.scriptingwebservicessectiongroup, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"> <section name="jsonserialization" type="system.web.configuration.scriptingjsonserializationsection, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35" requirepermission="false" allowdefinition="everywhere"/> <section name="profileservice" type="system.web.configuration.scriptingprofileservicesection, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35" requirepermission="false" allowdefinition="machinetoapplication"/> <section name="authenticationservice" type="system.web.configuration.scriptingauthenticationservicesection, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35" requirepermission="false" allowdefinition="machinetoapplication"/> <section name="roleservice" type="system.web.configuration.scriptingroleservicesection, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35" requirepermission="false" allowdefinition="machinetoapplication"/> </sectiongroup> </sectiongroup> </sectiongroup> </configsections> <appsettings/> <connectionstrings/> <system.web> <!-- set compilation debug="true" insert debugging symbols compiled page. because affects performance, set value true during development. --> <compilation debug="true"> <assemblies> <add assembly="system.core, version=3.5.0.0, culture=neutral, publickeytoken=b77a5c561934e089"/> <add assembly="system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"/> </assemblies> </compilation> <!-- <authentication> section enables configuration of security authentication mode used asp.net identify incoming user. --> <authentication mode="none"/> <!-- <customerrors> section enables configuration of if/when unhandled error occurs during execution of request. specifically, enables developers configure html error pages displayed in place of error stack trace. <customerrors mode="remoteonly" defaultredirect="genericerrorpage.htm"> <error statuscode="403" redirect="noaccess.htm" /> <error statuscode="404" redirect="filenotfound.htm" /> </customerrors> --> <pages> <controls> <add tagprefix="asp" namespace="system.web.ui" assembly="system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"/> </controls> </pages> <httphandlers> <remove verb="*" path="*.asmx"/> <add verb="*" path="*.asmx" validate="false" type="system.web.script.services.scripthandlerfactory, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"/> <add verb="*" path="*_appservice.axd" validate="false" type="system.web.script.services.scripthandlerfactory, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"/> <add verb="get,head" path="scriptresource.axd" type="system.web.handlers.scriptresourcehandler, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35" validate="false"/> </httphandlers> <httpmodules> <add name="scriptmodule" type="system.web.handlers.scriptmodule, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"/> </httpmodules> </system.web> <system.codedom> <compilers> <compiler language="c#;cs;csharp" extension=".cs" warninglevel="4" type="microsoft.csharp.csharpcodeprovider, system, version=2.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089"> <provideroption name="compilerversion" value="v3.5"/> <provideroption name="warnaserror" value="false"/> </compiler> </compilers> </system.codedom> <system.web.extensions> <scripting> <webservices> <!-- uncomment section enable authentication service. include requiressl="true" if appropriate. <authenticationservice enabled="true" requiressl = "true|false"/> --> <!-- uncomment these lines enable profile service, , choose profile properties can retrieved , modified in asp.net ajax applications. <profileservice enabled="true" readaccessproperties="propertyname1,propertyname2" writeaccessproperties="propertyname1,propertyname2" /> --> <!-- uncomment section enable role service. <roleservice enabled="true"/> --> </webservices> <!-- <scriptresourcehandler enablecompression="true" enablecaching="true" /> --> </scripting> </system.web.extensions> <!-- system.webserver section required running asp.net ajax under internet information services 7.0. not necessary previous version of iis. --> <system.webserver> <validation validateintegratedmodeconfiguration="false"/> <modules> <add name="scriptmodule" precondition="integratedmode" type="system.web.handlers.scriptmodule, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"/> </modules> <handlers> <remove name="webservicehandlerfactory-integrated"/> <add name="scripthandlerfactory" verb="*" path="*.asmx" precondition="integratedmode" type="system.web.script.services.scripthandlerfactory, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"/> <add name="scripthandlerfactoryappservices" verb="*" path="*_appservice.axd" precondition="integratedmode" type="system.web.script.services.scripthandlerfactory, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"/> <add name="scriptresource" precondition="integratedmode" verb="get,head" path="scriptresource.axd" type="system.web.handlers.scriptresourcehandler, system.web.extensions, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"/> </handlers> </system.webserver> <system.servicemodel> <services> <service name="wcfservice1.service1" behaviorconfiguration="wcfservice1.service1behavior"> <!-- service endpoints --> <endpoint address="" binding="wshttpbinding" contract="wcfservice1.iservice1"> <!-- upon deployment, following identity element should removed or replaced reflect identity under deployed service runs. if removed, wcf infer appropriate identity automatically. --> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexhttpbinding" contract="imetadataexchange"/> </service> </services> <behaviors> <servicebehaviors> <behavior name="wcfservice1.service1behavior"> <!-- avoid disclosing metadata information, set value below false , remove metadata endpoint above before deployment --> <servicemetadata httpgetenabled="true"/> <!-- receive exception details in faults debugging purposes, set value below true. set false before deployment avoid disclosing exception information --> <servicedebug includeexceptiondetailinfaults="false"/> </behavior> </servicebehaviors> </behaviors> </system.servicemodel> </configuration> the url below :
http://localhost:51671/service1.svc/getdata/1 can help?
there 4 things wrong:
first, should using webhttpbinding instead of wshttpbinding. wshttpbinding soap services - not rest services.
second, need add endpoint behaviour.
so, endpoint this:
<endpoint address="" binding="webhttpbinding" contract="wcfservice1.iservice1" behaviorconfiguration="webbehavior"> and in behaviors section should have
<endpointbehaviors> <behavior name="webbehavior"> <webhttp /> </behavior> </endpointbehaviors> third, uri template should be
uritemplate="/getdata/{value}" rather than
uritemplate="/getdata/{}" and finally, parameters use in uri template must of type string, so
string getdata(string value); rather than
string getdata(int value); inside service operation have parse string value correct type.
overall, much easier rest asp.net webapi rather wcf rest. if can move .net 4 instead of 3.5 make quicker progress , working supported platform.
also, development should set
<servicedebug includeexceptiondetailinfaults="true"/> so can more information on goes wrong. remember set false production though.
Comments
Post a Comment