Suppose I have a web service which accept email id and password as parameter in url . I have to authenticate user by email id and password. using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Serialization;using System.ServiceModel;using System.Text;using System.ServiceModel.Web;namespace WebApp.Services{[ServiceContract]public interface IService { [WebInvoke(Method = "GET", UriTemplate = "/authenticate/{emailId}/{password}", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)] [OperationContract] Boolean Authenticate(string emailId, string password); }}
we call web service like it :
http://localhost:14176/Services/Service.svc/Authenticate/sushant.bhatnagar#greatdevelopers.com/123
because email contain '.' which is not encoded by the web browser , so web service function is not called .
There is any solution to pass email id in url other than query string .
If You could use POST:
[ServiceContract]
public interface IMyService
{
[OperationContract]
bool Authenticate(EmailCredential request);
}
[DataContract]
public class EmailCredential
{
[DataMember]
public string EmailId {get; set;}
[DataMember]
public string Password {get; set;}
}
and call service using WebClient or WebHttpRequest with that xml (i don't know now how json looks like for this so xml)
<EmailCredential >
<EmailId >sushant.bhatnagar#greatdevelopers.com</EmailId >
<Password >123</Password >
</EmailCredential >
Related
This is my first post.
I am building a restful wcf service using post to accept an XML message (truncated from the real one). I am having trouble getting WCF to parse the XML due to the way the message is using namespaces. I cannot change the format of the XML message.
I have tried various combinations of namespace attributes on the Service and datacontract but either get a parsing error or segments that are missing or NULL.
If I was able to change the message I can get it to work by either removing the namespace or by applying the namespace prefix to all the fields. Unfortunately, it is not possible to get the vendor to change the format of the message being sent.
Is there a way to get this to work with the message being sent.
Sample Request
<m:MYMESSAGE xmlns:m="my.report">
<MESSAGEHEADER>
<MESSAGETYPE>GoodReport</MESSAGETYPE>
<MESSAGEDATE>20160203134445</MESSAGEDATE>
<MESSAGEACTION>UPDATE</MESSAGEACTION>
</MESSAGEHEADER>
<PATIENT>
<LASTNAME>Last</LASTNAME>
<FIRSTNAME>First</FIRSTNAME>
<MIDDLENAME>Middlename</MIDDLENAME>
</PATIENT>
</m:MYMESSAGE>
Sample Incorrect Response
<MYMESSAGE xmlns="my.report" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<MESSAGEHEADER i:nil="true"/>
<PATIENT i:nil="true"/>
</MYMESSAGE>
WCF Code
[ServiceContract]
public interface IPDF
{
[OperationContract ]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Xml,
RequestFormat = WebMessageFormat.Xml
)]
MYMESSAGE GetPdf(MYMESSAGE mymessage);
}
[DataContract(Name = "MYMESSAGE", Namespace = "my.report")]
public class MYMESSAGE
{
[DataMember (Name ="MESSAGEHEADER",Order=0) ]
public _MESSAGEHEADER MESSAGEHEADER { get; set; }
[DataMember(Name = "PATIENT", Order = 1)]
public _PATIENT PATIENT { get; set; }
}
[DataContract(Namespace = "my.report")]
public class _MESSAGEHEADER
{
[DataMember(Name = "MESSAGETYPE", Order = 0)]
public string MESSAGETYPE { get; set; }
[DataMember(Name = "MESSAGEDATE", Order = 1)]
public string MESSAGEDATE { get; set; }
}
You can use Message Contracts to create the shape of the message you need. For eaxample:
[MessageContract]
public class BankingTransaction
{
[MessageHeader] public Operation operation;
[MessageHeader(Namespace="http://schemas.contoso.com/auditing/2005")] public bool IsAudited;
[MessageBodyMember(Name="transactionData")] public BankingTransactionData theData;
})
WCF uses Message based on SOAP but WCF internals can hide this by converting inbound messages to SOAP and outbound messages to what ever transport protocol you are using.
You can ultimately create your own message formatter.
"Message formatters are the component which do the translation between CLR operations and the WCF Message object – their role is to convert all the operation parameters and return values (possibly via serialization) into a Message on output, and deconstruct the message into parameter and return values on input."
I am new in WCF and started learning.I want to host a WCF service for android app but I don't know how to invoke a method and what is the uritemplate.
the IService is:
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "UserReg", ResponseFormat = WebMessageFormat.Json)]
public string UserReg(string user_id, string first_name, string last_name, string email, string password);
}
and the Service is:
public class Service1 : IService1
{
P_M_SEntities objEntities = new P_M_SEntities();
public string UserReg(string user_id, string first_name, string last_name, string email, string password)
{
User_Registration tblObj = new User_Registration();
tblObj.user_id = Convert.ToInt32(user_id);
tblObj.first_name = first_name;
tblObj.last_name = last_name;
tblObj.email = email;
tblObj.password = EncryptPwd(password);
objEntities.User_Registration.Add(tblObj);
objEntities.SaveChanges();
string objstring = tblObj.user_id.ToString();
return string.Format(objstring);
}
}
I'm not familiar with WCF so I would really appreciate your help.
I developed a WCF Service with the following post method:
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "/InsertBearingData")]
bool InsertBearingData(String JSONString);
I am using Fiddler to formulate an HTTP POST Request for this method but, it is returning Status Code - 400 Bad Request. This is the request formulated:
Request Header:
Host: localhost:21468
Content-Length: 96
Content-Type: application/json
Request Body:
[{"start time":"29-03-2013 11:20:11.340","direction":"SW","end time":"29-03-2013 11:20:14.770"}]
Can you please tell me how to formulate a good request in order to get a succesful response?
There are a few issues in your code:
The data type of the parameter is string, but you're passing a JSON array to it; a string parameter requires a JSON string to be passed.
The body style of the operation is set to Wrapped, which means that the parameter should be wrapped in an object whose key is the parameter name, something like {"JSONString":<the actual parameter value>}
To receive a request like the one you're sending, you need to have an operation like the following:
[ServiceContract]
public interface ITest
{
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "/InsertBearingData")]
bool InsertBearingData(MyType[] param);
}
[DataContract]
public class MyType
{
[DataMember(Name = "start time")]
public string StartTime { get; set; }
[DataMember(Name = "end time")]
public string EndTime { get; set; }
[DataMember(Name = "direction")]
public string Direction { get; set; }
}
I am trying to pass a List in WCF Post call as parameter. Below is my code.
TrackingNumbers.cs
[KnownType(typeof(List<string>))]
[DataContract]
public class TrackingNumbers
{
[DataMember]
public List<object> TrackingNumberList { get; set; }
}
IService.cs
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "v1/xml/GetMultipleShipmentDetails/")]
Shipments[] XMLMultipleData(TrackingNumbers trackingNumbers);
Now When I am passing the following XML from fiddler
<TrackingNumbers xmlns="http://schemas.datacontract.org/2004/07/Chhotu.Web.Partner.API">
<TrackingNumberList>10000008871</TrackingNumberList>
<TrackingNumberList>10000008864</TrackingNumberList>
<TrackingNumberList>10000008858</TrackingNumberList>
</TrackingNumbers>
the XMLMultipleData method is not getting called from debugger. Please suggest what i am doing wrong.
I see some issues with our code:
No need for [KnownType(typeof(List))], the DataContractSerializer knows this type already.
List - is not a good approach. If you use numbers why not make it an int?
Are you sure you are attached? You can try to enforce the attaching of a debugger with Debugger.Break(); at a good position in your code.
I will suggest you try change this line
Shipments[] XMLMultipleData(TrackingNumbers trackingNumbers);
with
Shipments[] XMLMultipleData(TrackingNumbers[] trackingNumbers);
And your [DataContract] as
[DataContract]
public class TrackingNumbers
{
[DataMember]
public int TrackingNumber{ get; set; }
}
Also! Try removing KnownType(typeof(List<string>))]
Thanks!
I have a WCF REST service that needs to communicate with another WCF REST service.
There are three websites:
Default Web Site
Website1
Website2
If I set up both services in Default Web Site and connect to the other (using HttpClient) using the URI http://localhost/service then everything is okay.
The desired set-up is to move these two services to separate websites and rather than using the URI http://localhost/service, accessing the service via http://website1.domain.com/service still using HttpClient.
I received the exception:
System.ArgumentOutOfRangeException: Unauthorized (401) is not one of
the following: OK (200), Created (201), Accepted (202),
NonAuthoritativeInformation (203), NoContent (204), ResetContent
(205), PartialContent (206)
I can see this is a 401, but what is going on here?
Thanks
I think this is related to your setup for webservice. It is best if you just create GET,POST,Put,DELETE heartbeat calls for new services and then check those from fiddler. If you get 401, it may mean your app pool identity could not access something.
Steps to fix that:
Give user read/write/modify/execute/..similar rights at your WCF publish folder
Create app pool for this site in .net 4 integrated
Set this user to application pool identity, enable anonymous mode
Enable PUt,Delete verbs as well
Part of a heartbeat class in your service to test calls:
[DataContract]
public class StatusInfo
{
[DataMember]
public string MachineName { get; set; }
[DataMember]
public string IpAddress{ get; set; }
[DataMember]
public string Methodname { get; set; }
public override string ToString()
{
return "Machinename:" + MachineName + " ;IP:" + IpAddress + "; Method:" + Methodname;
}
}
private void ResolveStatus(StatusInfo statusInfo,string methodname)
{
try
{
var context = System.ServiceModel.OperationContext.Current;
RemoteEndpointMessageProperty property =
(RemoteEndpointMessageProperty)
context.IncomingMessageProperties[RemoteEndpointMessageProperty.Name];
statusInfo.IpAddress = property.Address;
statusInfo.MachineName = Environment.MachineName;
statusInfo.Methodname = methodname;
}catch(Exception ex)
{
}
}
/// <summary>
/// create task
/// </summary>
/// <param name="taskwrapped"></param>
[WebInvoke(Method = "POST", UriTemplate = "", RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public StatusInfo postcall()
{
StatusInfo statusInfo = new StatusInfo();
logger.Trace(Tagname + "postcall");
ResolveStatus(statusInfo, "POST");
return statusInfo;
}
/// <summary>
/// edit task
/// </summary>
[WebInvoke(Method = "PUT", UriTemplate = "", RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public StatusInfo Edit()
{
StatusInfo statusInfo = new StatusInfo();
logger.Trace(Tagname + "Edit");
ResolveStatus(statusInfo, "PUT");
return statusInfo;
}
//delete request with taskid
[WebInvoke(Method = "DELETE", UriTemplate = "", RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public StatusInfo DeleteCall()
{
StatusInfo statusInfo = new StatusInfo();
logger.Trace(Tagname + "Edit");
ResolveStatus(statusInfo, "DELETE");
return statusInfo;
}
//delete request with taskid
[WebInvoke(Method = "DELETE", UriTemplate = "/{recordid}", RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public StatusInfo DeleteCallWithParam(string recordid)
{
StatusInfo statusInfo = new StatusInfo();
logger.Trace(Tagname + "Edit");
ResolveStatus(statusInfo, "DELETE/"+recordid);
return statusInfo;
}
enter code here
I received the exception:
Who is "I"? One of the web services or some other client?
If I'm understanding things correctly, it's the receiving end that seems to be expecting a range of responses, 401 not being one of them. It maybe some error checking code that expects "this range" of responses and does X (and 401 isn't one of these, or there is no "default" method to account for x response?).
That said, 401, is an authorization error so check on possible ServiceAuthorizationManager and/or similar settings in place that isn't being met by "I" causing the 401 response in the first place....
Hth...
My guess is you are missing authorizaton headers or credentials.
Check this out :
Consume RESt API from .NET
How to authenticate with Rest-client based on HttpClient and .net4