none
WCF Rest Service with Message as return type not working RRS feed

  • Question

  •      

         We have some WCF Restful web services, running in ,NET FrameWork 4.0. When we are trying to execute, we are getting the following error :

    "System.InvalidOperationException: The operation 'Login' could not be loaded because it has a parameter or return type of type System.ServiceModel.Channels.Message or a type that has MessageContractAttribute and other parameters of different types. When using System.ServiceModel.Channels.Message or types with MessageContractAttribute, the method must not use any other types of parameters."

           The details about WCF service has been mentioned below :

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Web;
    using System.Text;
    
    namespace MASTService
    {
        [ServiceContract]
        public interface IMAST
        {                       
            /// <summary>
            /// Check login with parameters -- version 1
            /// </summary>
            /// <param name="UserName"></param>
            /// <param name="Password"></param>
            /// <returns></returns>
            [OperationContract]
            [WebInvoke(Method = "GET",
                ResponseFormat = WebMessageFormat.Json,
                BodyStyle = WebMessageBodyStyle.WrappedResponse,
                UriTemplate = "login?UserName={UserName}&Password={Password}")]
            Message Login(string UserName, string Password);
    
            /// <summary>
            /// Two step login authentication with IMEI number --version 2
            /// </summary>
            /// <param name="UserName"></param>
            /// <param name="Password"></param>
            /// <param name="IMEI"></param>
            /// <returns></returns>
            [OperationContract]
            [WebInvoke(Method = "GET",
                ResponseFormat = WebMessageFormat.Json,
                BodyStyle = WebMessageBodyStyle.WrappedResponse,
                UriTemplate = "login2step?UserName={UserName}&Password={Password}&IMEI={IMEI}")]
            Message Login2step(string UserName, string Password,string IMEI);       
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Security.Cryptography;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Web;
    using System.Text;
    using MASTBusinessLogic;
    using Newtonsoft.Json;
    using System.Collections;
    using System.IO;
    using Newtonsoft.Json.Linq;
    using System.Globalization;
    using System.Web.Hosting;
    using System.Threading.Tasks;
    using Microsoft.Exchange.WebServices.Data;
    using System.Net;
    using System.Configuration;
    using System.Web.Script.Serialization;
    using System.Net.Mail;
    using System.Data.SqlClient;
    
    namespace MASTService
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "MAST" in code, svc and config file together.
        // NOTE: In order to launch WCF Test Client for testing this service, please select MAST.svc or MAST.svc.cs at the Solution Explorer and start debugging.
        public class MAST : IMAST
        {
            clsAppSettings objAppSettings = new clsAppSettings();
            const string constalone = "Alone";
            const string constmanagingdirector = "Managing Director";
            const string constvicepresident = "Vice President";
            const string constgeneralmanager = "General Manager";
            const string constsalesmanager = "Sales Manager";
            const string constareasalesmanager = "Area Sales Manager";
            const string constothers = "Others";
            const string constterritorysalesexecutive = "Territory Sales Executive";
    
            public string[] workingTypes = new string[] { constalone, constmanagingdirector, constvicepresident, constgeneralmanager, constsalesmanager, constareasalesmanager, constothers };
            public string[] workingTypesNew = new string[] { constalone, constareasalesmanager, constsalesmanager, constgeneralmanager, constvicepresident, constmanagingdirector, constothers };
            public string[] workingTypesNew1 = new string[] { constalone, constterritorysalesexecutive, constareasalesmanager, constsalesmanager, constgeneralmanager, constvicepresident, constmanagingdirector, constothers };
            public string[] FreshnessType = new string[] { "0-30", "31-60", "61-90", "91-120", ">120" };
            MastAuthorization objMastAuthorization = new MastAuthorization();
          
                   
            /// <summary>
            /// Getting encrypted string for username and password -- version-1
            /// </summary>
            /// <param name="Username"></param>
            /// <param name="Password"></param>
            /// <returns></returns>
            public Message Login(String Username, String Password)
            {
                BasicAuthorization basic = new BasicAuthorization();
                string output = "BASIC " + basic.EncryptString(Username + ":" + Password);
                return WebOperationContext.Current.CreateTextResponse(output, "application/json;charset=utf-8", System.Text.Encoding.UTF8);
    
            }
    
            /// <summary>
            /// Getting encrypted string for username, password and IMEI -- version-2
            /// </summary>
            /// <param name="Username"></param>
            /// <param name="Password"></param>
            /// <returns></returns>
            public Message Login2step(String Username, String Password, String IMEI)
            {
                BasicAuthorization basic = new BasicAuthorization();
                string output = "BASIC " + basic.EncryptString(Username + ":" + Password + ":" + IMEI);
                return WebOperationContext.Current.CreateTextResponse(output, "application/json;charset=utf-8", System.Text.Encoding.UTF8);
    
            }    
        }
    
    }
    

      My Configuration file : 

    <?xml version="1.0"?>
    <configuration>
    
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
    
      </appSettings>
      <connectionStrings>
        <add name="Connection" connectionString="myConnectionString"  providerName="System.Data.SqlClient"/>
      </connectionStrings>
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
        <httpRuntime targetFramework="4.0"/>
      </system.web>
      <system.serviceModel>
        <services>
          <service name="MASTService.MAST" behaviorConfiguration="ServiceBehaviour">
            <endpoint address=""  binding="webHttpBinding" contract="MASTService.IMAST" bindingConfiguration="TransferService"  behaviorConfiguration="web">
            </endpoint>
          </service>
        </services>
        <behaviors>
          <endpointBehaviors>
            <behavior name="web">
              <webHttp />
            </behavior>
          </endpointBehaviors>
          <serviceBehaviors>
            <behavior name="ServiceBehaviour">
              <serviceMetadata httpsGetEnabled="false" httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
    
            </behavior>
            <behavior name="">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
          </serviceBehaviors>
    
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="false"
          multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
        <bindings>
          <webHttpBinding>
            <binding name="TransferService"
           maxReceivedMessageSize="2147483647"
           maxBufferSize="2147483647" transferMode="Streamed" >
              <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                   maxArrayLength="2147483647" maxBytesPerRead="2147483647"
                   maxNameTableCharCount="2147483647"/>
              <security mode="None">
                <transport clientCredentialType="None"/>
              </security>
            </binding>
          </webHttpBinding>
        </bindings>
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
    </configuration>
    

              We got following suggestion related to this issue, which is recommending us for the code changes. However we want to know anything can be done by changing the configurations or adding any references.

    We can use the Message class as an input parameter of an operation, the return value of an operation, or both. If Message is used anywhere in an operation, the following restrictions apply:
    -The operation cannot have any out or ref parameters.
    -There cannot be more than one input parameter. If the parameter is present, it must be either Message or a message contract type.
    -The return type must be either void, Message, or a message contract type.

       If we can run this service only by changing the method input parameters or return type then let us know.

       It will be helpful, if we get a solutions for this problem with out code changes in the Service Interface and Implementation.          




    Thursday, August 6, 2015 2:30 PM

Answers

  • Hi Abhishek B,

    According to this case, Form your web.config file,I saw you configure your transfer mode  is stream.So that means 

    when we Use the operationContract ,only can pass one parameter.If you want to pass multiple streams, I suggest you can use message contract to define a message,like below:

    [MessageContract]
        public class LoginMessage
        {
            [MessageHeader]
            public string UserName { get; set; }
            [MessageBodyMember]
            public string Password { get; set; }
        }
    [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            Message Login(LoginMessage msg);
        }

    For more information, please refer to the following articles:

    1.Passing multiple streams in WCF

    2.WCF Service operations can’t be loaded due to mixing of message contract types and primitive types

    I hope that will be helpful to you.

    Best Regards,

    Tracy Grady

    Saturday, August 8, 2015 2:48 AM
    Moderator

All replies

  •  We got following suggestion related to this issue, which is recommending us for the code changes. However we want to know anything can be done by changing the configurations or adding any references.

    The .NET code is blowing up because invalid parms are being passed into a method with the possibility of bad return of an object out of a method.   

    You have to run the client and service code on a VS development machine in debug mode and let it blow up in debug mode so that it blows up on the line of code that is causing the problem,  and you start looking into what it should or should not be doing while code is executing.

    Thursday, August 6, 2015 8:36 PM
  • Thank you for your valuable response.

    We are unable to hit the services. When we are trying to browse the ".svc" file from the Solution Explorer there only we are getting the error, which we highlighted in our problem description in red color.

    We are not getting any compile time issues and this problem is coming at run time.

    Friday, August 7, 2015 10:44 AM
  • Hi Abhishek B,

    According to this case, Form your web.config file,I saw you configure your transfer mode  is stream.So that means 

    when we Use the operationContract ,only can pass one parameter.If you want to pass multiple streams, I suggest you can use message contract to define a message,like below:

    [MessageContract]
        public class LoginMessage
        {
            [MessageHeader]
            public string UserName { get; set; }
            [MessageBodyMember]
            public string Password { get; set; }
        }
    [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            Message Login(LoginMessage msg);
        }

    For more information, please refer to the following articles:

    1.Passing multiple streams in WCF

    2.WCF Service operations can’t be loaded due to mixing of message contract types and primitive types

    I hope that will be helpful to you.

    Best Regards,

    Tracy Grady

    Saturday, August 8, 2015 2:48 AM
    Moderator