I want to invoke an ASP.NET web service via an http POST request using C# (i.e. I don't want to use the SoapHttpClientProtocol object generated by running wsdl.exe).
As far as I can tell, the process involves:
creating an HttpWebRequest object which points to the url/method of the web service, with the method;
Creating a SOAP xml envelope;
Serialising any parameters I want to pass to the web method using an XmlSerializer;
Making the request, and parsing the response.
I would like to do this without having to copy and use generated code.
(1) seems pretty straightforward;
(2) I don't know if the envelope here is standard, or how it should change depending on the webservice method I am calling. I guess I might need to add custom soap headers if required by the service?
(3) What is the process of doing this? I assume that I need to do something like this:
MyClass myObj;
XmlSerializer ser = new XmlSerializer(myObj.GetType());
TextWriter writer = new StringWriter();
ser.Serialize(writer, myObj);
string soapXml = writer.ToString();
writer.Close();
Also, I guess I should add the soapXml to the soap:Body element
(4) I believe I should extract and deserialize the contents of the soap:Body element as well. Is it OK to use the reverse of the process in (3)?
Thanks,
K.
I don't know why I am doing this but here's an example of invoking a web service manually. Please promise to never use this in a production code.
Suppose you had the following SOAP service:
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld(Foo foo)
{
return "Hello World";
}
}
You can invoke it manually like this:
class Program
{
static void Main(string[] args)
{
using (WebClient client = new WebClient())
{
client.Headers.Add("SOAPAction", "\"http://tempuri.org/HelloWorld\"");
client.Headers.Add("Content-Type", "text/xml; charset=utf-8");
var payload = #"<?xml version=""1.0"" encoding=""utf-8""?><soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""><soap:Body><HelloWorld xmlns=""http://tempuri.org/""><foo><Id>1</Id><Name>Bar</Name></foo></HelloWorld></soap:Body></soap:Envelope>";
var data = Encoding.UTF8.GetBytes(payload);
var result = client.UploadData("http://localhost:1475/Service1.asmx", data);
Console.WriteLine(Encoding.Default.GetString(result));
}
}
}
Related
I'm trying to understand how to create/backwards engineer a Multipart WCF Soap endpoint that takes attachments as input parameters seperated by "MIME-delimiter".
I got an example of who requests to this kind of endpoint would look like but i don't understand how to create the service to receive the request.
So the example i got was something like this (FYI I've removed information for security reasons):
--MIME11111.11111
<SOAP-ENV:Envelope xmlns:SOAP-ENV="" xmlns:eb="" xmlns:xsi="" xsi:schemaLocation="">
<SOAP-ENV:Header>
<eb:MessageHeader SOAP-ENV:mustUnderstand="1" eb:version="2.0">
<eb:From>
<eb:PartyId eb:type="TYPE1">NUMBER</eb:PartyId>
</eb:From>
<eb:To>
<eb:PartyId eb:type="TYPE2">NUMBER</eb:PartyId>
</eb:To>
<eb:CPAId>ID</eb:CPAId>
<eb:Service eb:type="TYPE3">TEXT</eb:Service>
<eb:Action>TEXT</eb:Action>
<eb:MessageData>
<eb:MessageId>ID</eb:MessageId>
<eb:Timestamp>DATE</eb:Timestamp>
</eb:MessageData>
</eb:MessageHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<eb:Manifest eb:version="2.0">
<eb:Reference xlink:href="cid:payload-1" xlink:role="aop:ROOT"/>
</eb:Manifest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
--MIME11111.11111
Content-ID: payload-1
<?xml version="1.0" encoding="UTF-8"?>
<aop:ROOT xsi:schemaLocation="" xmlns:aop="" xmlns:xsi="">
<aop:ELEMENT>
<aop:SUBELEMENT11>TEXT</aop:SUBELEMENT11>
<aop:SUBELEMENT12>
<aop:SUBELEMENT21>NUMBER</aop:SUBELEMENT21>
<aop:SUBELEMENT22>NUMBER</aop:SUBELEMENT22>
</aop:SUBELEMENT12>
</aop:ELEMENT>
</aop:ROOT>
--MIME11111.11111--
What i have done so far is:
Created a WCF Project in Visual Studio.
Created my Interface like this:
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "Post", BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/PostBusinessData")]
PostBusinessDataResponseContract PostBusinessData(Manifest data);
}
[MessageContract]
public class Manifest
{
[MessageHeader]
public Headers MessageHeader { get; set; }
[MessageBodyMember]
public Stream Reference { get; set; }
}
[MessageContract]
public class PostBusinessDataResponseContract
{
[MessageBodyMember]
public string PostBusinessDataResponse { get; set; }
}
Created my controller / service like this:
public class Service1 : IService1
{
public PostBusinessDataResponseContract PostBusinessData(Manifest data)
{
return new PostBusinessDataResponseContract() { PostBusinessDataResponse = "It Works"};
}
}
My Header class was created by "special pasting" the XML structure between "header" elements from the example above.
I have the class Model for the soap-envelope header pretty much set up except some of the attributes on the elements instead show up as sub elements in the generated request structure.
But the main thing is that i don't quite understand how to built the code for the in parameter in regards to the attachment. It looks to me that the Attachment in the multipart example comes in as a stream, but as a stream of what? A file, a xml string/text? the only thing the reference in the SOAP envelope contains is a so called "Content-ID". No file name, nothing else.
How do i set up my endpoint in my backed to be able to consume the type of request shown in the example above is really my question.
According to your description, I made a demo. After creating a WCF service, we can generate a proxy class to call the service by adding a service reference.
Right click References and select Add Service Reference.
Enter the address of the service in the address field, and click OK to generate the proxy class and configuration file for you to call the service.
ServiceReference1.Service1Client service1Client = new Service1Client();
string str = "Testing";
byte[] array = Encoding.ASCII.GetBytes(str);
MemoryStream stream = new MemoryStream(array);
Console.WriteLine(service1Client.PostBusinessData(stream));
Console.ReadLine();
The client-side can support the request type of the server through the generated proxy class.
This is the result.
UPDATE
WCF supports MTOM, which is the W3C standard superseded SwA.This is a link to MTOM related information:
https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/mtom-encoding
For more information about MTOM and SWA, please refer to the following link:
https://learn.microsoft.com/en-us/previous-versions/dotnet/articles/ms996462(v=msdn.10)?redirectedfrom=MSDN
In WCF, if you want to receive the XML message you give, I think you can use message inspectors to intercept the XML message and parse it.
public class ServerMessageLogger : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
string xml = ""+request;
// Parse the received XML here
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
string xml = ""+reply;
//Encapsulate the XML to send
}
}
For more information about message inspectors, please refer to the following link:
https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/message-inspectors?redirectedfrom=MSDN
I'm making an asmx web service in C# and trying to test it with a simple client app. I write the web service's inner code but I have to conform to a given xml for post and response. It's supposed to receive a header with authentication information and return a token and comments. The headers in both directions contain the same types but half the fields are used only for input and half are used only for output.
The header class is defined roughly like this:
public class CustomHeader : SoapHeader
{
public string InParam;
public string OutParam;
}
The web service method code looks something like this:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class WebService_UD : System.Web.Services.WebService
{
public CustomHeader customHeader;
[WebMethod]
[SoapHeader("customHeader", Direction = SoapHeaderDirection.InOut)]
public string CustomWebMethod (int param1, string param2)
{
// code reading inner fields of customHeader
// code updating other inner fields of customHeader
// code dealing with other parameters and creating normal return value
}
}
And the test client application like this:
WebService_UDClient caller = new WebService_UDSoapClient();
CustomHeader header = new CustomHeader();
header.InParam = "blip";
string response = caller.CustomWebMethod(header, 1, "1");
string outParam = header.OutParam; // returns null here
The web service doesn't seem to change the header. Changing the header's InParam also doesn't change it in client. The problem is probably that I'm not passing header in by reference, but I don't know how to change the web service code (since the rest is auto-generated) to pass by reference.
So how do I do that, or how do I retrieve the response header in some other way?
A client has a service that sends out xml soap formatted requests that we need to receive via our .Net MVC4 project. A request would be in the format:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ReceiveStatusUpdate xmlns="http://test.com">
<StatusUpdate>
<Reference>214563</Reference>
<ThirdPartyReference>YOUR-REFERENCE</ThirdPartyReference>
<Status>Pending</Status>
</StatusUpdate>
</ReceiveStatusUpdate>
</soap:Body>
</soap:Envelope>
I'm wondering what would be the best way to receive and parse this request?
Slightly hacky way of doing this but it worked for me and it's a one off request type that I need to handle. I basically pulled the request body out and parsed it with XDocument
public ActionResult Update()
{
var inputStream = Request.InputStream;
inputStream.Seek(0, SeekOrigin.Begin);
var request = new StreamReader(inputStream).ReadToEnd();
var soapRequest = XDocument.Parse(request);
...
}
The easiest way to achieve this is to use an old-fashioned asmx web service.
Exposing via Web API would require considerable work as it does not support SOAP binding out of the box.
You could use a WCF service, but they can be fiddly and time consuming to configure, which is the price to pay for their flexibility.
In short, if you only need to support SOAP bindings, use the tool that was made for that job - asmx web services.
Just add a new item to your MVC project of type Web Service (ASMX), example shown below (you'd obviously have your StatusUpdate class defined in a separate file).
/// <summary>
/// Summary description for StatusWebService
/// </summary>
[WebService(Namespace = "http://test.com")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class StatusWebService : System.Web.Services.WebService
{
[WebMethod]
public void ReceiveStatusUpdate(StatusUpdate StatusUpdate)
{
//Do whatever needs to be done with the status update
}
}
public class StatusUpdate
{
public string Reference { get; set; }
public string ThirdPartyReference { get; set; }
public string Status { get; set; }
}
In my opinion - maybe someone can say more about it, would be to choose WebAPI. It's simple to use, just some code so it's light. You have lot's of tools for processing XML documents in .NET so this wont be any problem for you.
There is one more thing. In your XML there is error, the closing tag "ReceiveStatusUpdate" is misspelled.
This will be helpful in the beginning: http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
Then you can use Fiddler to post those XML's to your WebAPI.
Might not be the best answer BUT here is what I'm doing now.
[HttpPost]
public IHttpActionResult HotelAvailRQ(HttpRequestMessage request)
{
// Parse the SOAP request to get the data payload
var xmlPayload = MyHelper.GetSoapXmlBody(request);
// Deserialize the data payload
var serializer = new XmlSerializer(typeof(OpenTravel.Data.CustomAttributes.OTA_HotelAvailRQ));
var hotelAvailRQ = (OpenTravel.Data.CustomAttributes.OTA_HotelAvailRQ)serializer.Deserialize(new StringReader(xmlPayload));
return Ok();
}
Helper class
public static class MyHelper
{
public static string GetSoapXmlBody(HttpRequestMessage request)
{
var xmlDocument = new XmlDocument();
xmlDocument.Load(request.Content.ReadAsStreamAsync().Result);
var xmlData = xmlDocument.DocumentElement;
var xmlBodyElement = xmlData.GetElementsByTagName("SOAP-ENV:Body");
var xmlBodyNode = xmlBodyElement.Item(0);
if (xmlBodyNode == null) throw new Exception("Function GetSoapXmlBody: Can't find SOAP-ENV:Body node");
var xmlPayload = xmlBodyNode.FirstChild;
if (xmlPayload == null) throw new Exception("Function GetSoapXmlBody: Can't find XML payload");
return xmlPayload.OuterXml;
}
}
WCF Json deserialization.
I'm building a middleware webservice in WCF using Dotnet 4.5, This server returns a polymorphic type.
[DataContract]
[KnownType(typeof(SomethingA))]
[KnownType(typeof(SomethingB))]
public class Something
{
[DataMember]
public int Item1 { get; set; }
[DataMember]
public string Item2 { get; set; }
}
[DataContract]
public class SomethingA : Something
{ }
[DataContract]
public class SomethingB : Something
{ }
/// <summary>
/// Contract for a service for testing various web operations.
/// </summary>
[ServiceContract]
[ServiceKnownType(typeof(SomethingA))]
[ServiceKnownType(typeof(SomethingB))]
public interface ITesting
{
/// <summary>
/// Test passing in and returning an object using POST and json.
/// </summary>
[OperationContract]
[WebInvoke(
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "use-polymorphic-somethings",
Method = "POST")]
List<Something> UsePolymorphicSomethings();
}
/// <summary>
/// Implementation of the ITesting service contract.
/// </summary>
public class Testing : ITesting
{
public List<Something> UsePolymorphicSomethings()
{
List<Something> retVal = new List<Something>();
retVal.Add(new SomethingA { Item1 = 1, Item2 = "1" });
retVal.Add(new SomethingB { Item1 = 1, Item2 = "1" });
return retVal;
}
}
On the client side I'm attempting to deserialize this in such a way as to preserve the different types in the collection. The MSDN documentation for this seems really weak to me. The first issue I encountered was that adding a reference to System.Web.Http created an undocumented dynamic dependency on on a third party open source component called Newtonsoft.Json which I had to download off the web.
The first two deserialization approaches fail, but I have found a third approach that works.
What I'd like to know is why do the first two approaches fail? Ideally I'd like to get the first approach to work as that is the most streamlined.
[TestMethod]
public void UsePolymorphicSomethings_Test1()
{
using (HttpClient http = new HttpClient())
{
http.BaseAddress = new Uri("http://localhost:8733/");
HttpResponseMessage response = http.PostAsJsonAsync(
"Design_Time_Addresses/InSite8WebServiceLib2/Testing/use-polymorphic-somethings",
new StringContent(string.Empty)).Result;
List<Something> ret = response.Content.ReadAsAsync<List<Something>>().Result;
// FAILS.
Assert.AreEqual(typeof(SomethingA), somethings[0].GetType());
Assert.AreEqual(typeof(SomethingB), somethings[1].GetType());
}
}
[TestMethod]
public void UsePolymorphicSomethings_Test2()
{
using (HttpClient http = new HttpClient())
{
http.BaseAddress = new Uri("http://localhost:8733/");
HttpResponseMessage response = http.PostAsJsonAsync(
"Design_Time_Addresses/InSite8WebServiceLib2/Testing/use-polymorphic-somethings",
new StringContent(string.Empty)).Result;
string ret1 = response.Content.ReadAsStringAsync().Result;
Newtonsoft.Json.JsonSerializerSettings s = new Newtonsoft.Json.JsonSerializerSettings();
s.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All;
List<Something> r = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Something>>(ret1, s);
// FAILS.
Assert.AreEqual(typeof(SomethingA), somethings[0].GetType());
Assert.AreEqual(typeof(SomethingB), somethings[1].GetType());
}
}
[TestMethod]
public void UsePolymorphicSomethings_Test3()
{
using (HttpClient http = new HttpClient())
{
http.BaseAddress = new Uri("http://localhost:8733/");
HttpResponseMessage response = http.PostAsJsonAsync(
"Design_Time_Addresses/InSite8WebServiceLib2/Testing/use-polymorphic-somethings",
new StringContent(string.Empty)).Result;
Stream stream = response.Content.ReadAsStreamAsync().Result;
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<Something>));
List<Something> somethings = (List<Something>)serializer.ReadObject(stream);
// SUCCEEDS.
Assert.AreEqual(typeof(SomethingA), somethings[0].GetType());
Assert.AreEqual(typeof(SomethingB), somethings[1].GetType());
}
}
From my understanding, you are "worried" about the stream lining of the code that you have written. Seeing that you have the code working in your last method, and I hope my reasons for it working and the others not explain it to your satisfaction. We can still stream line you method a bit using a simple helper.
public T Deserialize<T>(Stream stream) where T : class
{
var serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
}
you can then simply call this method like so
List<Something> somethings = Deserialize<List<Something>>(stream);
To make things maybe even easier in a sense, you could write the helper method as a extension method,
something like this
public static class Helpers
{
public static T Deserialize<T>(this Stream stream) where T : class
{
var serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
}
}
You could then call this method like this
var result = stream.Deserialize<List<Something>>();
To go all the way up, you could create the extension method against the HttpResponseMessage
public static class Helpers
{
public static T Deserialize<T>(this HttpResponseMessage response) where T : class
{
var stream = response.Content.ReadAsStreamAsync().Result;
var serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
}
}
You could call this method like this
var result = response.Deserialize<List<Something>>();
At least your code will now again be a one liner and if you in the future change your serializer, you will only have to change your client code in a single place. you might want to check the code out, as I don't have visual studio open currently to test it out for you. But it looks good to me.
I am adding a new helper example here, so there are more options / fixes to choose from.
public static class Helpers
{
public static Task<T> ReadAsAsyncCustom<T>(this HttpContent content)
{
var formatters = new MediaTypeFormatterCollection();
formatters.Clear();
formatters.Add(new JsonMediaTypeFormatter { UseDataContractJsonSerializer = true });
return content.ReadAsAsync<T>(formatters);
}
}
and this one could be used as follows
List<Something> ret = response.Content.ReadAsAsyncCustom<List<Something>>().Result;
The reason I call clear on the formatter variable in the helper method, is because the constructor of the MediaTypeFormatterCollection creates default formatters, we are not interested in those, so I clear them and add in just 1 formatter that we know works with your solution.
I generally try stick to the DRY rule, which is the reason I try keep "customisation" isolated in just a single place, so that when things change, I don't need to go through all the source and try remember or search for all the instances where it may have been used.
to put things in another way as well, while the framework does support your scenario, it of course requires a settings change if you will. If you were not using what you call polymorphic types, the standard out of the box methods would work great. I wrote up a solution mimicking yours this morning, and I could not see a quick way that could help you get away without making changes on your client side.
In my opinion, methods 1 and 2 instantiate an object of type T and then set its properties by reading the stream. In other words, these methods only known the type "Something" so they can only instantiate "Something". Third method also uses attributes DataContract and KnownType, so it is able to instantiate the known types "Something", "SomethingA" and "SomethingB".
I want to create an IIS-hosted webservice which I will consume using a universal windows store aoo (windows phone/windows 8.1/windows RT).
As I understand universal applications do not support proxy class generation and SOAP calls using "Add service reference" so I need to create a RESTful webservice and manually consume it in the universal application.
I've tried dozens of tutorials and approaches throughout the net but I never managed to actually POST data to the webservice.
I need to send objects of a custom class which is defined in a shared library to the webservice. I understand that I will need to serialize the Object and include it in the POST request, however no matter what I try I end up with different issues - e.g HTTP 400 Bad Request: The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'.
I've seen several approaches to manually set the content type header, however the methods I found are not available in a universal application.
Can someone provide information or an example which is fitting my scenario (POST-ing via universal app)?
update 1: For further clarification: I am aware how WCF works and I was already able to complete a basic GET request like described in this post. However I was unable to extend that to also work with POST requests.
Some code I've tried:
public async static void SendStartup(CustomClass customObject)
{
var httpClient = new HttpClient();
var serialized = JsonConvert.SerializeObject(customObject);
var response = await httpClient.PostAsync("http://localhost:49452/Metrics.svc/LogStartup", new StringContent(serialized));
string content = await response.Content.ReadAsStringAsync();
}
Web Service Interface:
[OperationContract]
[WebInvoke(UriTemplate = "LogStartup", Method="POST", BodyStyle=WebMessageBodyStyle.Wrapped)]
string LogStartup(CustomClass obj);
Implementation:
public void LogStartup(CustomClass obj)
{
// nothing
}
This for example failes at runtime with the error mentioned above
There are two problem with your code.
1) You have to send the Content-Type header while your are making a request
var content = new StringContent(serialized,Encoding.UTF8,"application/json");
2) You have to use BodyStyle = WebMessageBodyStyle.Bare
WebMessageBodyStyle.Bare can work with one parameter as in your example, but if you want to post more parameters then you have to use WebMessageBodyStyle.Wrapped but then, your object you post should be modified as
var serialized = JsonConvert.SerializeObject(new { obj = customObject });
Here is a working code you can test with self-hosted WCF service
async void TestRestService()
{
var ready = new TaskCompletionSource<object>();
Task.Factory.StartNew(() =>
{
var uri = new Uri("http://0.0.0.0:49452/Metrics.svc/");
var type = typeof(Metrics);
WebServiceHost host = new WebServiceHost(type, uri);
host.Open();
ready.SetResult(null);
},TaskCreationOptions.LongRunning);
await ready.Task;
var customObject = new CustomClass() { Name = "John", Id = 333 };
var serialized = JsonConvert.SerializeObject(new { obj = customObject });
var httpClient = new HttpClient();
var request = new StringContent(serialized,Encoding.UTF8,"application/json");
var response = await httpClient.PostAsync("http://localhost:49452/Metrics.svc/LogStartup", request);
string content = await response.Content.ReadAsStringAsync();
}
[ServiceContract]
public class Metrics
{
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped)]
public string LogStartup(CustomClass obj)
{
return obj.Name + "=>" + obj.Id;
}
}
public class CustomClass
{
public string Name { set; get; }
public int Id { set; get; }
}
PS: If you want to return a json response then you can use ResponseFormat=WebMessageFormat.Json. You should then change the WebInvoke attribute as
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped,ResponseFormat=WebMessageFormat.Json)]
BTW: You can still dynamically choose the returned content type(xml or json) by setting AutomaticFormatSelectionEnabled.
Have you seen this article?
How to use HttpClient to post JSON data
Basically it seems like you need to add more parameters to your StringContent() constructor like this:
new StringContent(serialized, System.Text.Encoding.UTF8, "application/json");
One thing you need to know about Windows Communication Foundation is the ABC's.
A : Address
B : Binding
C : Contract
So the theory is incredibly simple, though while your coding it, it is quite odd. A simple tutorial can be found here or here. Several other tutorials can be found at Code Project for this exact approach.
Understanding Polymorphism may be helpful for understanding Windows Communication Foundation as it relies heavily on it.
[ServiceContract]
public interface IContent
{
[OperationContract]
void DoSomething(SomeModel model);
}
So what you're doing here is defining your service, defining your method. As I mentioned above we've explicitly declared our contract but we haven't implemented our method. Also we intend to pass SomeModel which would be our Data Contract.
We will build our model:
[DataContract]
public class SomeModel
{
[DataMember]
public string Name { get; set; }
}
The model can be incredibly simple like above, or incredibly complex. It will depend on usage.
Now we would like to implement our method:
public class Content : IContent
{
public void DoSomething(SomeModel model)
{
// Implementation
}
}
Now on the client, you simply consume your service. Once you understand the basics and how it serializes and deserializes you can use it for REST. Which tutorials also exist for that.