1

my Rest wcf service as below...

[ServiceContract]
public interface IWinPhoneService
{

[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "getkpimeasuredata", Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped)]
List<MeasureData> GetKpiMeasureData(DomainData data);


[OperationContract]
[WebGet(UriTemplate = "getdata/{value}", ResponseFormat = WebMessageFormat.Json)]
string GetData(string value);


// TODO: Add your service operations here
}

[DataContract]
public class DomainData
{
    [DataMember]
    public int? KPIId
    {
        get;
        set ;
    }

[DataMember]
public int? ScorecardId
{
    get;
    set;
}

[DataMember]
public short? CumulativeMonth
{
    get;
    set;
}

[DataMember]
public int? EngineeringOrgId
{
    get;
    set;
}

[DataMember]
public int? BusinessOrgId
{
    get;
    set;
}
[DataMember]
public int? DataValuetypeId
{
    get;
    set;
}

}

and when I consume this service using Restsharp as below

string URL = "http://<servername>:8085/WinPhoneService.svc";

            RestClient client = new RestClient(URL);

            RestRequest request = new RestRequest("getkpimeasuredata",Method.POST);
            DomainData data = new DomainData();
            data.KPIId = 1006;
            data.ScorecardId = 3;
            data.EngineeringOrgId = 11;
            data.DataValuetypeId = 1;
            data.CumulativeMonth = 463;
            data.BusinessOrgId = 1;

            string json = Newtonsoft.Json.JsonConvert.SerializeObject(data);

            json = "{\"data\" : " + json + "}";

            request.AddParameter("application/json; charset=utf-8", json, ParameterType.RequestBody);
            request.RequestFormat = DataFormat.Json;
 client.ExecuteAsync(request, response =>
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {



                }
                else
                {
                    //NOK
                }
            });

Even tried a webget method also as below..

 RestClient client1 = new RestClient(URL);
            RestRequest request1 = new RestRequest(string.Format("getdata/{0}", 1), Method.GET);
            request1.RequestFormat = DataFormat.Json;

            var x = client1.ExecuteAsync(request1, response =>
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {

                    }
                });

Im able to the response.StatusCode as NotFound and even when I checked fiddler the service is not hitting at all and when I verified the service url in composer im getting the error as "HTTP/1.1 405 Method Not Allowed"

and even when I tried with Webclient as below

string URL = "http://<servername>:8085/WinPhoneService.svc";
            WebClient wclient = new WebClient();
            wclient.UseDefaultCredentials = true;
            wclient.Headers["Content-Type"] = "application/json";


            DomainData kpidata = new DomainData();
            data.KPIId = 1006;
            data.ScorecardId = 3;
            data.EngineeringOrgId = 11;
            data.DataValuetypeId = 1;
            data.CumulativeMonth = 463;
            data.BusinessOrgId = 1;

            string json = SerializeJson(kpidata);
            String str = wclient.UploadString(new Uri(URL ),"getkpimeasuredata",json);

Even here im getting "HTTP/1.1 405 Method Not Allowed" but atleast in this case its hitting the service as shown in fiddler

PFB the webconfig for the same...

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation>
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>
    <!--<httpRuntime targetFramework="4.0" />-->
  </system.web>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="webCorpBinding">
          <!--<security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows"></transport>
          </security>-->
        </binding>
      </webHttpBinding>

    </bindings>
    <behaviors>

      <endpointBehaviors>
        <behavior name="RESTCorpBehavior">
          <webHttp/>
        </behavior>

      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true"  />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="WinPhoneService.WinPhoneService">
        <endpoint name="WinPhoneServiceeCorp" address="" binding="webHttpBinding" bindingConfiguration="webCorpBinding" behaviorConfiguration="RESTCorpBehavior"
         contract="WinPhoneService.IWinPhoneService" />
      </service>
    </services>
    <!--<protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>-->
    <!--<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />-->
  </system.serviceModel>
  <!--<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    --><!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      --><!--
    <directoryBrowse enabled="true" />
  </system.webServer>-->


  <connectionStrings>
    <add name="ScaasEntities" connectionString="metadata=res://*/Scaas.csdl|res://*/Scaas.ssdl|res://*/Scaas.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=<servername>;initial catalog=<catalog>;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  </entityFramework>
</configuration>

Please help me regarding the same..

the function which I use in win8 mobile app is

public async void  LoadKpiData()
        {
                       string URL = "http://rr1biscdevsql01:8085/WinPhoneService.svc/getkpimeasuredata;
            WebClient wclient = new WebClient();
            wclient.UseDefaultCredentials = true;
            wclient.Headers["Content-Type"] = "application/json";

            DomainData kpidata = new DomainData();
            kpidata.KPIId = 1006;
            kpidata.ScorecardId = 3;
            kpidata.EngineeringOrgId = 11;
            kpidata.DataValuetypeId = 1;
            kpidata.CumulativeMonth = 463;
            kpidata.BusinessOrgId = 1;

            string json = SerializeJson(kpidata);
            wclient.UploadStringAsync(new Uri(URL), json);

            wclient.UploadStringCompleted += (s, e) =>
                {

                };

        }

and when I check in response for Restclient call got error as below

 {"ErrorCode":"1001","ErrorMessage":"System.Data.EntityCommandExecutionException: The data reader is incompatible with the specified 'ScaasModel.GetKPIMeasureData_Result'. A member of the type, 'ParamName', does not have a corresponding column in the data reader with the same name.\u000d\u000a   at System.Data.Query.InternalTrees.ColumnMapFactory.GetColumnMapsForType(DbDataReader storeDataReader, EdmType edmType, Dictionary`2 renameList)\u000d\u000a   at System.Data.Query.InternalTrees.ColumnMapFactory.CreateColumnMapFromReaderAndType(DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet, Dictionary`2 renameList)\u000d\u000a   at System.Data.Query.InternalTrees.ColumnMapFactory.CreateFunctionImportStructuralTypeColumnMap(DbDataReader storeDataReader, FunctionImportMapping mapping, EntitySet entitySet, StructuralType baseStructuralType)\u000d\u000a   at System.Data.EntityClient.EntityCommandDefinition.FunctionColumnMapGenerator.System.Data.EntityClient.EntityCommandDefinition.IColumnMapGenerator.CreateColumnMap(DbDataReader reader)\u000d\u000a   at System.Data.Objects.ObjectContext.CreateFunctionObjectResult[TElement](EntityCommand entityCommand, EntitySet entitySet, EdmType edmType, MergeOption mergeOption)\u000d\u000a   at System.Data.Objects.ObjectContext.ExecuteFunction[TElement](String functionName, MergeOption mergeOption, ObjectParameter[] parameters)\u000d\u000a   at System.Data.Objects.ObjectContext.ExecuteFunction[TElement](String functionName, ObjectParameter[] parameters)\u000d\u000a   at ScaasWinPhone.Model.ScaasEntities.GetKPIMeasureData(Nullable`1 kPIID, Nullable`1 scorecardID, Nullable`1 cumulativeMonthCount, Nullable`1 engineeringOrgID, Nullable`1 businessOrgID, Nullable`1 dataValueTypeID, Nullable`1 debug, ObjectParameter errorText)\u000d\u000a   at ScaasWinphoneRepository.ScaasRepository.GetKpiMeasureData(Nullable`1 kpiId, Nullable`1 scorecardId, Nullable`1 cumulativeMonth, Nullable`1 engineeringOrgId, Nullable`1 businessOrgId, Nullable`1 dataValuetypeId)\u000d\u000a   at SCaaSWinPhoneService.SCaaSWinPhoneService.GetKpiMeasureData(KpiDomainData kpidata)"}

Rajesh when I added [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] in service and

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

in webconfig im getting error as The service cannot be activated because it does not support ASP.NET compatibility. ASP.NET compatibility is enabled for this application. Turn off ASP.NET compatibility mode in the web.config or add the AspNetCompatibilityRequirements attribute to the service type with RequirementsMode setting as 'Allowed' or 'Required'.

Actually its working fine when I run service in localhost but its throwing the error when I host the service..Please help ....

shiv455
  • 7,384
  • 19
  • 54
  • 93
  • Can you first try to see if you can hit the REST service by accessing the GET resource from a browser and getting the response back. Make sure to capture the request in Fiddler and please do post your Fiddler raw request – Rajesh Sep 03 '13 at 08:51
  • yeah im getting the json result as "You entered: 1" when invoked in browser http://:8085/WinPhoneService.svc/getdata/1 – shiv455 Sep 03 '13 at 09:33
  • And when I gave "http://:8085/WinPhoneService.svc/getkpimeasuredata" for URL instead of mentioning the method name in Uploadstring its working ...if I use webclient but if I use Restclient its not at all working .Please help – shiv455 Sep 03 '13 at 09:35
  • If you try to access getkipmeasuredata via browser you should have got some exception as your method is configured for POST and not GET. Can you try to capture the raw request using Fiddler and post it for us to have a look at the POST request. – Rajesh Sep 03 '13 at 09:41
  • I didn't access getkipmeasuredata via browser from code itself im trying...and as I said in fiddler im not getting any service call when I used Restclient ..and when I use webclient and modified URL parameter as http://:8085/WinPhoneService.svc/getkpimeasuredata instead passing method name in uploadstring everything works fine...but I need the solution in Restclient.Please help – shiv455 Sep 03 '13 at 09:47

2 Answers2

2
[WebInvoke(... , Method = "POST" ... )]List<MeasureData> GetKpiMeasureData(DomainData data);

Above code you used POST method , but you must use GET method Because POST method only is used if you will add data.

Http verbs are POST , GET , Delete and PUT(Update) . You must learn firstly.

I used Get method and RestSharp.dll for my project if You want to use my project for POST method , below code you can use

Client side

 var client1 = new RestClient("http://localhost:61111/Service1.svc");
            var request1 = new RestRequest("/AddPerson", Method.POST);
            Person person1 = new Person();
            person1.PersonID = 2;
            person1.Name = "Robert";
            person1.SurName = "Dan";
            JsonSerializer serial = new JsonSerializer();

            string temp = serial.Serialize(person1);
            Console.WriteLine(temp);
            Person tempPerson1 = new JavaScriptSerializer().Deserialize<Person>(temp);
            Console.WriteLine(tempPerson1.PersonID + " " + tempPerson1.Name + " " + tempPerson1.SurName);

Server side

public class Service1 : IService1
{       
    private Person person = new Person() { PersonID = 1, Name = "John", SurName = "Albert" };
    public Person GetPerson()
    {
        return person;
    }
    public Person AddPerson(Person person)
    {
        return person;
    }
}


[ServiceContract]
public interface IService1
{

    [OperationContract]
    [WebInvoke(Method="GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetPerson")]
    Person GetPerson();
    [OperationContract]
    [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "/AddPerson")]
    Person AddPerson(Person person);
}
Trimax
  • 2,413
  • 7
  • 35
  • 59
Cihan
  • 31
  • 3
1

Look at this code

My server code as below

[ServiceContract]
    public interface IWinPhoneService
    {
        [OperationContract]
        [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "getkpimeasuredata")]
        List<String> GetKpiMeasureData(DomainData data);
    }

[DataContract]
    public class DomainData
{
    [DataMember]
    public int? KPIId { get; set; }

    [DataMember]
    public int? ScorecardId { get; set; }

    [DataMember]
    public short? CumulativeMonth { get; set; }

    [DataMember]
    public int? EngineeringOrgId { get; set; }

    [DataMember]
    public int? BusinessOrgId { get; set; }

    [DataMember]
    public int? DataValuetypeId { get; set; }
}

Now my implementation of the interface as below

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class WinPhoneService : IWinPhoneService
    {
        public List<string> GetKpiMeasureData(DomainData data)
        {
            if (data != null)
            {
                return new List<string>()  {"Sample 1","Sample 2"};
            }
            return new List<string>() {"No data recieved"};
        }
    }

My server side web.config for endpoint element configuration

<system.serviceModel>
<services>
    <service name="WinPhoneService.WinPhoneService">
            <endpoint address="" binding="webHttpBinding" behaviorConfiguration="web" bindingConfiguration="defaultRestJsonp" contract="WinPhoneService.IWinPhoneService">
            </endpoint>
          </service>
    </services>
    <behaviors>
    <endpointBehaviors>
            <behavior name="web">
              <webHttp />
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>        
    </endpointBehaviors> 
    </behaviors>
    <bindings>   
    <webHttpBinding>
            <binding name="defaultRestJsonp" crossDomainScriptAccessEnabled="true">
              <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="64" maxNameTableCharCount="2147483647" />
              <security mode="None" />
            </binding>
  </webHttpBinding>
  </bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />     
 </system.serviceModel>  

Now with all the above set find my client code below using RestSharpClient:

private static string ToStringUsingDataContractJsonSer<T>(T requestBody)
        {
            var serializer = new DataContractJsonSerializer(typeof(T));
            var ms = new MemoryStream();
            serializer.WriteObject(ms, requestBody);
            ms.Position = 0;
            var reader = new StreamReader(ms);
            return reader.ReadToEnd();
        }

private string UseRestSharpApproach(string serviceBaseUrl, string resourceUrl, Method method, object requestBody)
        {
            var client = new RestClient();
            client.BaseUrl = serviceBaseUrl;
            var request = new RestRequest(method) { DateFormat = DataFormat.Xml.ToString(), Resource = resourceUrl };
            request.AddParameter("application/json", requestBody, ParameterType.RequestBody);            
            var response = client.Execute(request);

            string responseString;
            if (response.StatusCode == HttpStatusCode.OK)
            {
                responseString = HttpUtility.HtmlDecode(response.Content);
            }
            else
            {
                responseString = response.StatusDescription + " --------------------" + HttpUtility.HtmlDecode(response.Content);
            }
            return responseString;
        }

public void CallRESTService()
{
       UseRestSharpApproach(serviceBaseUrl, resourceUrl, Method.POST, ToStringUsingDataContractJsonSer<DomainData>(objDomainData));
}

Make sure that the DomainData object when using on the client side is in the same namespace as on server so that the serialization and de-serialization happens without problems.

Now my raw request from Fiddler looks as below:

POST http://servername/Sample/WinPhoneService.svc/GetKpiMeasureData HTTP/1.1
Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml
User-Agent: RestSharp 102.0.0.0
Content-Type: application/json
Host: servername
Content-Length: 112
Accept-Encoding: gzip, deflate

{"BusinessOrgId":1,"CumulativeMonth":463,"DataValuetypeId":1,"EngineeringOrgId":11,"KPIId":1006,"ScorecardId":3}

And the response looks as below:

HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 23
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS
X-AspNet-Version: 4.0.30319
Set-Cookie: ASP.NET_SessionId=123450p12rvdmnh3qrx2ocip; path=/; HttpOnly
Date: Tue, 03 Sep 2013 10:11:51 GMT

["Sample 1","Sample 2"]
Rajesh
  • 7,766
  • 5
  • 22
  • 35
  • Thanks for ur reply ,ur URI template is getkpimeasuredata but in the url you mentioned GetKpiMeasureData ,and can you please let me know how u pass the parameters for UseRestSharpApproach function – shiv455 Sep 03 '13 at 11:49
  • Please see this SO post which might be helpful : http://stackoverflow.com/questions/6312970/restsharp-json-parameter-posting – Rajesh Sep 03 '13 at 12:05
  • Rajesh one more thing actually I need to perform rest call from windows phone 8 project its a mobile app..when I used webclient rest calls are working from console app but when I run the same code from mobile app im getting System.Net.WebException: The remote server returned an error: NotFound. error im using async function see above for updated code – shiv455 Sep 03 '13 at 12:23
  • Can you try first to run them in Sync and see if that works. I am not sure if there are any emulators from win phone 8 for me to provide a sample. Try to enable tracing on your Server and then inspect the trace file to see a more detailed info. Why are you using default credentials when you dont have any authentication on your service. – Rajesh Sep 03 '13 at 14:16
  • Actually the issue is from winphone 8 the hosted wcf urls were not recogniaed but when I integrated servicebus it is working(if I give service bus url instead of hosted wcf url) with Webclient but not with Restclient ,actually im using entity and the sp which im using dynamic sql to return the result set ..im getting the error in Restclient call as mentioned in the edited question above.Please help – shiv455 Sep 04 '13 at 05:44
  • Have you checked if the port 8085 is opened for traffic or there is something on your mobile that is blocking the calls i.e. antivirus etc... – Rajesh Sep 04 '13 at 08:39
  • Rajesh its working properly when i use webclient but with restclient i have some issue which i clearly explained in http://stackoverflow.com/questions/18620917/rest-sharp-sends-null-data-to-wcf-service thread ...can u pls look and reply me there please....and i have another issue in impersonation in wcf rest i have posted in http://stackoverflow.com/questions/18620581/impersonation-in-wcf-rest-service can u pls see this also if possible... – shiv455 Sep 05 '13 at 02:37
  • Rajesh can u see my updated question once ...I have a query on asp.net compatibility mode – shiv455 Sep 06 '13 at 07:18
  • You can just add the aspnetcompatiblity mode attribute on your service implementation class and that should be enough. Look at my sample code where I have the same attribute as well – Rajesh Sep 06 '13 at 09:21
  • Rajesh even though I added im getting the error.. actually I came to know that as im integrating servicebus eventhough I add attribute it wont work as per this link http://blogs.msdn.com/b/avkashchauhan/archive/2011/11/17/wcf-rest-http-application-connecting-azure-service-bus-using-webhttprelaybinding-causes-aspnetcompatibilityenabled-error.aspx and I need to implement caching and as per below link that attribute is required msdn.microsoft.com/en-us/library/ee230443.aspx – shiv455 Sep 06 '13 at 11:33
  • Are you trying to cache something for which you need that attribute set. Alternatively you can remove the attribute and change the value in config to false and try if it works then look on how to get it solved with aspnet compatiblity mode – Rajesh Sep 06 '13 at 12:33
  • if I remove its working but to implement caching that is required it seems as per msdn article which I posted in my earlier comment....actually I need to implement caching, is there any other way to implement without using this attribute – shiv455 Sep 06 '13 at 12:35
  • So the problem is with servicebus integration. Are you using Azure servicebus or nservicebus? – Rajesh Sep 06 '13 at 13:04
  • Im using Azure Servicebus – shiv455 Sep 11 '13 at 05:54