passing Dictionary in WCF service [duplicate] - wcf

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to serialize Dictionary<string, string> through WCF?
How to pass a dictionary in a method in WCf ...
I'm doing this
public void SendData(Dictionary<string, string > data)
{
foreach (KeyValuePair<string, string> item in data)
{
Console.WriteLine("{0} : {1}", item.Key, item.Value);
}
}
When I access it as 192.X.X.X//Akhil/service.svc/SendData?data={}
here What/How should I pass arguments in data...some example please.

Generate your proxy (Say, "TestProxy") then do:
TestProxy.YourServiceClient client = new TestProxy.YourServiceClient();
Dictionary<string, string> testDict = new Dictionary<string, string>();
testDict.Add("test", "test1");
client.SendData(testDict);
WCF will serialize your Dictionary with no problem. The problem here is that you are trying to access your WCF service as if you exposed it as a REST Service through an HTTP Get request. I'm pretty sure based on your question, you aren't exposing this as a REST service. If you want to be able to do Get Requests, then google .Net WCF REST.
*Note: you might also want to look into the Request/Response SOA pattern, it's going to save a bunch of trouble down the road.
Update:
Here are some links that might point you in the right direction, you'll probably want to expose your WCF service as a JSON endpoint.
JSON / REST Link
Search Dictionary in this LINK to get some details on alternatives and gotchas in WCF JSON.
Hope these help. I have never done an Iphone app so I don't have any source code to give you.

Related

WCF and Data Transfer Object

I am stuck on this simple question. In my console application, I want to consume a wcf service. So I add the web reference to the project and call it. That is it.
But why I saw some examples especially using RESTSHARP, they never add web reference. They just use so called "DTO" to return object by the service and consume it.
I hope somebody can clarify the concepts for me. Is DTO used inside WCF?
sample:
private static List<ApplicationDTO> features;
RestClient client = new RestClient("http://" + baseUrl + "/FacilityData.svc");
var request = new RestRequest(Method.GET);
request.Resource = "/GetFeatures";
request.Parameters.Clear();
request.AddParameter("Id", 888);
var response = client.Execute(request);
features = JsonConvert.DeserializeObject<List<ApplicationDTO>>(response.Content);
from this post:
For REST service, it provides a generic way for WCF service consuming
which doesn't rely on the SOAP. That's why we no longer need "Add
ServiceReference..." for consuming it. REST service operations can be
accessed through standard HTTP GET/POST request, so any webrequest
enabled client can consume it. For example, you can use HttpWebRequest
to invoke a REST operation and use LINQ to XML to load and extract
values from the response XML data. It's very flexible.
DTO, usually used for Data Transfer Object - is nothing more then entity you want to pass as parameter / receive as a result.
In your example, ApplicationDTO - is probably some entity to hold Data about Application Feature object (Name, Type, ...)

How to Consume MVC 4 WebApi Service

I am new to Web Api world and I see a lot of potential for in the new MVC 4 Web Api. I have generated a WCF Web Service but was planning to get to know Web-APIs and their web service capabilities. Now, is MVC 4 Web-Api Service more as front end? I wrote a sample Service by following some examples online in MVC 4 Web Api but how do I consume the Service in just a basic console app? I have figured out the only way to consume it is by using HttpClient are there other ways? I am used to ASP.NET Web Service and WCF Web Service as where you reference it as a service in your references and then you are able to see all of its objects, properties to make appropriate calls.
What happens if web-api is requesting a object "Task" for post method as an example how am I able to fill an object "Task" and post it back to the web-api? As in WCF I am able to see that "Task" object and its properties because of WSDL so I am able to fill them and send it back to the service how is that done in web-api service?
The webservice would be used internally is it worth it to have an web-api service?
Thank you so much for helping clearing some question of what I have about web-api services.
---Edit as per Comment---
This screenshot shows a possible structure which you can approach. Of course, you can take a design that best suit your application.
So ControllerLib is a separate Class Library project which is brought into the main project as a Service Reference (which is not shown in the screenshot but should be inside the References folder of the SecondMVCApplication project). The two controller file (HomeController.cs and LocationController.cs is a controller file that implemented the Controller class, which is the same thing as a Controller file when you create a new MVC4 application using the template)
So for your question regarding if there is a SVC file. NO. In MVC 4, there is no such thing as a SVC file whether the application is one project or a combination of multiple project (unless I am mistaken). Inside the SecondMVCApplication, there is a file called RouteConfig.cs which holds the routing URL and as long as you add the Service Reference and there controller function exists. The code will run. Also the sample screenshot I showed also includes a WebApiConfig.cs file. You can use that file to do API stuff for mobile if you need. So, the regular RouteConfig.cs handles website request and the WebApiConfig.cs handles API request.
Good to Note: If you are using a Model project as a separate project (which I know you will as it is a M-V-C project...DUH!!). Make sure you put your connection string inside the web.config main project (in this case, the SecondMVCApplication). I remember I was stuck in this problem for 3 days (8 hours each) trying to fix this problem. Hope you don't run into it.
---End Edit---
The following answer to your question is mostly based on my knowledge and may or may not be true to all users.
Is MVC 4 Web-Api Service more as front end?
This depends on how you look at it. Typically, a Web-API service is more suited for creating back-end service to provide a data payload to different platforms, like mobile, desktop apps and so on. However, a MVC4 Internet Application will have front-end aspects in them, namely the Views, which end-users sees.
How do I consume the Service in just a basic console app?
AFAIK, there is two way to do this. One if to consume the APIs as a Service Reference. Another is to use HTTP operation (which I will mention in your question regarding the HTTP client and reserve this answer using the Service Reference method).
This depends on how your application is done. Like I said, if it is a website, your MVC pattern will not need to do anything, but the Models, Views and Controllers all are designed to work together without using any service.
Although, as I mentioned in the comments to the questions, if it is a big application then you will need to break them into different projects that will make the app modular and nimble. So you will end up creating different Service Library. If you go down the Service Library road, then you just make use of the Add Reference option to bring in your API/Projects/Whatever-you-call-it into the project. (For this, I normally put all project inside a single solution and let Visual Studio manage the build order as I am lazy to write up a build script).
Similarly, the same logic could be applied when consuming your web service in a console app.
I have figured out the only way to consume it is by using HttpClient are there other ways?
One way to consume web APIs is using HTTP. Are you aware of how to write http request headers and handle http response. If so, this is the second way I mentioned. You call the web service through it's URL and then get the data and do whatever work. If your answer to use http in console app is NO, then look at this post: Create HTTP post request and receive response using C# console application
What happens if web-api is requesting a object "Task" for post method as an example how am I able to fill an object "Task" and post it back to the web-api?
I think I indirectly answered this in your previous answer (assuming you are going to take the HTTP road). If not, then comment and I'll see if I can find some resource for you.
The webservice would be used internally is it worth it to have an web-api service?
I sort of answered this in the comment to the question. Ask if you need clarification.
Hope all this helps.
you can create your own Client Service class that will serve for every request.
public class ClientService
{
#region async helper methods
private static string m_mediaTypeHeaderValue= "application/json";
static HttpClient client = new HttpClient();
static HttpClient createHttpClientInstance()
{
return client ?? new HttpClient();
}
// SELECT
internal static async Task<T> Get<T>(string endpoint)
{
client= createHttpClientInstance();
var response = await client.GetAsync(endpoint);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
// INSERT
static async Task<T> Post<T>(string endpoint, object data)
{
client = createHttpClientInstance();
var httpContent = new StringContent(JsonConvert.SerializeObject(data));
httpContent.Headers.ContentType = new MediaTypeHeaderValue(m_mediaTypeHeaderValue);
var response = await client.PostAsync(endpoint, httpContent);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
// UPDATE
static async Task<T> Put<T>(string endpoint, object data)
{
client = createHttpClientInstance();
var httpContent = new StringContent(JsonConvert.SerializeObject(data));
httpContent.Headers.ContentType = new MediaTypeHeaderValue(m_mediaTypeHeaderValue);
var response = await client.PutAsync(endpoint, httpContent);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
// DELETE
static async Task<T> Delete<T>(string endpoint)
{
client = createHttpClientInstance();
var response = await client.DeleteAsync(endpoint);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
#endregion
}

Consuming a WCF Rest Service with WP7

I have a WCF Restful Service that returns JSON objects that my iPhone and Android apps consume nicely. This is my first attempt at building something like this and I left WP7 till last as my background lies with C# and VS2010. But it seems it’s not going to be a simple as I had guessed.
So I guess I have three questions:
1, Can I consume JSON objects in WP7? If so does anyone know of a tutorial?
2, if not, can I use the existing service and build some new contracts for consumption in WP7? Or,
3, do I need to build a whole new service?
Option one is most desirable but either way, I need to develop for all three operating systems so does anyone know the best type of model to bring this all together???
Cheers,
Mike.
Yes, but not with the channel factory / proxy programming model which you may be used to with WCF. REST services are usually consumed by using some simpler classes such as WebClient. You can use the JSON libraries (DataContractJsonSerializer is in the WP7 profile) then to deserialize the data you receive. Even the untyped JSON (the System.Json classes from the System.Json.dll on Silverlight), while not officially in the profile, they kind of work on WP7 as well (I've seen a few people simply referencing the SL library on a WP7 project).
If you want proxy support, you can add a new endpoint to the service using BasicHttpBinding, which is supported in WP7; if you don't need it, see 1).
No. See 1) and 2).
Try this to deserialize a JSON object:
public static T Deserialize<T>(string strData) where T : class
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
byte[] byteArray = Encoding.UTF8.GetBytes(strData);
MemoryStream memoryStream = new MemoryStream(byteArray);
T tRet = serializer.ReadObject(memoryStream) as T;
memoryStream.Dispose();
return tRet;
}
I find a totally wcf-based approach more interesting.
This is a good post that addresses this issue
http://blogs.msdn.com/b/carlosfigueira/archive/2010/04/29/consuming-rest-json-services-in-silverlight-4.aspx

Type 'System.Web.HttpRequest' cannot be serialized

I am trying to design an Picture Upload feature into a web site.
I am using ASP.NET 3.5, C#, and WCF.
I have been asked to accomplish the following:
1) Make the Uploader a Web Service
2) Return progress updates to the user as files are uploaded.
3) Log other relevant user-selected options in the database.
So, I have started off by creating a WCF web client with the
below service contract:
IService.UploadPictures(HttpRequest request);
private UploadServiceClient upload;
protected void Page_Load(object sender, EventArgs e)
{
upload = new UploadServiceClient();
upload.UploadPictures(Request.Files);
}
When I compile, I get the below error:
Type 'System.Web.HttpRequest' cannot
be serialized. Consider marking it
with the DataContractAttribute, and
marking all of its members you want
serialized with the
DataMemberAttribute attribute.
So, I went back into my service contract and
changed [OperationContract] to [DataContract]
but the change produced the same error.
Can somebody kindly tell me what I am doing wrong
and provide examples as to how to best move forward?
Thanks for your time.
You cannot use something like a HttpRequest as a WCF parameter. The error messages says it all - the HttpRequest is not serializable, and in order to work with WCF, types have to be serializable.
Also, you need to remember: you're not just passing an object instance to a method here - what you're really doing is having the WCF runtime serialize your request (the method name to call plus all the parameters passed in) into a message (think: e-mail or xml file), sending it to the server, deserialising there and building up a new copy of the given datatype (as defined in your DataContract), and doing something with it.
Your WCF service could well be self-hosted, e.g. running in a NT Service or console app - no HttpRequest available in those circumstances!
You need to definitely rearchitect your solution - you need to either check into WCF streaming to upload files to WCF (google for it - you'll find plenty of hits) or you'll need to find another way to pass the relevant info (e.g. list of filenames) to the WCF service without use of a HttpRequest object.
Marc
You are submitting a request as a parameter to a request. This is not what you want to do. I'm assuming that "Request.Files" is an array of files. This is what you want to upload. So something like:
IService.UploadPictures(List<SomeFileType> request);

Accepting form fields via HTTP Post in WCF

I need to accept form data to a WCF-based service. Here's the interface:
[OperationContract]
[WebInvoke(UriTemplate = "lead/inff",
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
int Inff(Stream input);
Here's the implementation (sample - no error handling and other safeguards):
public int Inff(Stream input)
{
StreamReader sr = new StreamReader(input);
string s = sr.ReadToEnd();
sr.Dispose();
NameValueCollection qs = HttpUtility.ParseQueryString(s);
Debug.WriteLine(qs["field1"]);
Debug.WriteLine(qs["field2"]);
return 0;
}
Assuming WCF, is there a better way to accomplish this besides parsing the incoming stream?
I remember speaking to you about this at DevLink.
Since you have to support form fields the mechanics of getting those (what you are currently doing) don't change.
Something that might be helpful, especially if you want to reuse your service for new applications that don't require the form fields is to create a channel that deconstructs your stream and repackages it to XML/JSON/SOAP/Whatever and have your form clients communicate with the service through that while clients that don't use forms can use another channel stack. Just an idea...
Hope that helps. If you need help with the channel feel free to let me know.
You can serialize your form fields with jquery and package it as json request to wcf service.