According to the following guide at MSDN, any operations that use streamed transfers can only have one input/output parameter.
Link: http://msdn.microsoft.com/en-us/library/ms731913.aspx (see heading "Restrictions on Streamed Transfers")
I'm using streamed transfers for a WCF service that lets clients/consumers upload files to it. The upload itself works fine, but I need a way of passing two more input parameters along with the Stream object: 'string filename' and 'int userid'.
How would I go about doing this?
ThereĀ“s something called headers that you can use in your datacontract:
Example of the interface:
[ServiceContract]
public interface IFile
{
[OperationContract]
Stream DownloadFile(int fileid);
[OperationContract]
bool UploadFile(FileUploadMessage request);
}
Put this in a separate file:
[MessageContract]
public class FileUploadMessage
{
[MessageHeader(MustUnderstand = true)]
public int MyInt {get;set;
[MessageHeader(MustUnderstand = true)]
public string MyString {get;set;
[MessageBodyMember(Order = 1)]
public System.IO.Stream FileByteStream {get;set;}
}
I have a somewhat similar problem. I created a test project and used a post I found to successfully create a wcf service call it from another project. I have a solution and the two web projects. One project call the service in the other project using a service reference.
I had the ServiceContract and the message contract in the interface file generated by creating a wcf service (the file that start with "I"). All of this worked fine. Then I went to our company's main project. It has a main web project that hosts two silverlight project. However the web project is not really a project but started out life as a website with no project at all. I have assumed that adding the two silverlight projects to the website probably created a solution for all three projects. However I'm not certain how vs2010 sees the main website which I will assume has no pointers to any files as a "real" project would.
What happened was when I created the wcf service in the main website and put the ServiceContract and MessageContract into the interface file I got the "interfaces cannot declare types" messge regarding the MessageContract and its child classes. I'm trying to follow your advice onthis post by taking the MessageContract and putting it into another file but I'm not sure what type of file. I tried putting the Message contract into a class (cs file). However the ServiceContract refers to classes in the MessageContract and the ServiceContract is no longer seeing the classes in the MessageContract even though they are public.
What type of file should I use to separate the Message contract from the ServiceContract?
Thanks,
Fig
Related
I am having a weird problem where I have a wcf service that has some Operation Contracts but when I add the service reference to another project they are there.
When I go to add -> add service reference. I put in the wfc url and the service shows up.
When I look at the operations list I see those endpoints but when I hit "ok" and then I try to find those endpoints in my project they are not found.
How can I go about debugging this?
Make sure you are using the correct Data Anotations on your interface, for example:
[ServiceContract]
public interface IService1
{
[OperationContract]
[FaultContract(typeof(ExceptionMessage))]
List<student> GetStudents();
[OperationContract]
[FaultContract(typeof(ExceptionMessage))]
void AddStudents(Student student);
[OperationContract]
[FaultContract(typeof(ExceptionMessage))]
void DeleteStudent(long StudentId);
}
You must have a [Service Contract] interface. And it should contain your methods
When you successfully add the service reference, the proxy class will be automatically generated in the project:
And it will automatically generate web.config, web.config contains endpoint information:
My project is a consumer for a 3rd party web service (old school web service vs. WCF service), and it has two versions, the "sandbox" (staging), and prod services. The APIs on these services are almost identical, and I am looking for a way to cleanly switch between the two versions, preferably without using conditional compilation.
I instinctively rushed off and extracted an interface from the client generated by Visual Studio's "Add web reference", i.e. AgentImport but that class is not partial, so I can't make it derive from the interface, or from any other superclass. I already have the creation of AgentImport instances nicely encapsulated in an abstract base for all my clients of AgentImport, but without using more risky compiler directives, how can I switch between v1 and v2 of AgentImport?
Some code:
using Clients.PrivateProperty.AgencyServicesApiService;
namespace Client.PrivateProperty
{
public abstract class PrivPropFacilityBase
{
protected static AgentImport Client;
protected PrivPropFacilityBase()
{
Client = new AgentImport();
Client.Timeout = 10000;
}
protected virtual AgentImport GetClient()
{
return new AgentImport();
}
}
}
I have tried adding service references instead of web references, as advised in comments below, to at least get access to partial classes, but when I add the first service reference, for the production service, and extract an interface from the auto-generated SOAP client, i.e. IAsapiClient, that interface references objects declared in other auto-generated classes, in the same namespace as the client, e.g. SecurityToken:
void UpdateUniqueAgentID(string PrivatePropertyAgentId, string AgentId, AgencyServicesApiService.SecurityToken Token);
If I add the second service reference, for the staging service, that second auto-generated SOAP client references objects in its own namespace, e.g. now it uses AgencyServicesApiSandbox.SecurityToken, so my compiler tells me that it doesn't implement the interface I extracted the first time. I am then left with the messy business of having to extract an new interface for each object that the main interface, IAsapiClient, references, so that this main interface only uses the extracted contracts, not actual class names.
In pursuing the above< I have reached the conclusion that my only feasible, and lowest risk, way forward is to use two client projects, one specifically for the production service, and one for the staging service. Then, at execution time, I only need to worry about dynamically choosing between two well known, i.e. not auto-generated, client objects.
At client side, I have this class without [DataContract]:
public class UserEntity
{
public string login;
public string password;
}
when I put [DataContract] and refresh the reference of this class at WCF side, then I can't initiate the web service. It says an error:
cannot create metadata...
What's wrong?
Are you sure that you actually know, why you can't refresh the reference? I mean you add [DataMember] - and it fails, you remove it - it works? Or it works several days ago and now you add [DataMember] (and many other stuff) and it not works now?
But anyway, the easiest way to solve "refresh reference" issues - to refresh reference manually with SvcUtil.exe. In this case error message would be much more descriptive the simple "oops! error!".
What is client and server side in your case? What is refreshing reference on the WCF side? Your description is very uncommon. Here is description how to create service with complex data type and WCF Class library:
Create WCF class library
Add data contract to the class library
Add service to class library
Implement service contract and service in the class library
Add host project
Reference WCF class library from host project
Host service from class library in host project
Add Metadata endpoint to your hosted service
Create client project
Run the host project outside the visual studio
Use Add service reference to create proxy on WCF service hosted in your host project
Implment code to call your service through created proxy
As you see there is no modification of data contract on the client side and no refreshing WCF service.
I have a webservice - called MyCompany.WebService1
I reference this using a web reference in my ASP.net web application.
Theres a method called "GetDeal" in this web service, that returns a "Deal" Object.
The deal object currently looks (for example) like this:
public class Deal
{
Public string Name {get;set;}
Public string Description {get;set;}
}
This class is in a different assembly: MyCompany.Model
The web service references this assembly.
In my web app, I can call the GetDeal method.
This returns Service1.Deal (service1 is just the name of the web reference)
I can access both properties above.
I have now changed the Deal class, and added a couple more properties.
However, I can't see these new properties in my web application.
I've updated the web service in the web application.
I rebuilt the web service several times, tried removing the MyCompany.Model reference and re-addding it etc...
I can't figure out what has changed... This was working - I have changed the model before, and it's updated the reference correctly...
Anything I've missed?
As long as the following points are fulfilled, this should work:
the new property is marked as Public and must be read/write (must have a getter and a setter)
you have compiled the host web application (the web app which exposes the web service).
(You can try calling the web service in a web browser to check whether the new property is visible).
you have updated the web reference the client application (and rebuilt the app)
In addition to what Martin suggests, you have to actually run the updated service.
I recommend you look at the WSDL to see if the changes took effect. Add "?wsdl" to the web service URL in the browser, and look to see if your new properties appear in the XML Schema at the top.
We are using C#, ASP.NET & WCF. I am trying to send form data to a web service which in turn inserts/updates a database with the data from my form. How should I send over my data?
We have the forms populated fine but are having some issues with sending updates back to the web service. We have determined that it is not great practice to use datasets in this situation, it is slow and we have to do too many SELECT *'s for our liking.
I have about 15 fields that need to go across. One team member wants to pass everything as a parameter which I dont think is optimal. We tried sending everything across in an Object[] array but are receiving a weird error "Type 'System.DBNull' with data contract name 'DBNull:http...' is not expected. Add any types not known statically to the list of known types",
Any suggestions are most welcome.
We use WCF to define our Data Contracts and Data Methods using attributes.
Basically we create an assembly to define all our classes and another assembly to provide the WCF connective bits
OPur class assembly contains a service class and several message classes.
We define an interface for our service and mark it up with relevant WCF markup. This is our Service Contract.
[ServiceContract]
public interface IExampleWebService
{
[OperationContract]
CreateAccountResponse CreateAccount(int parameter, CreateAccountArguments another parameter);
[OperationContract]
DeleteAccountResponse DeleteAccount(int parameter);
}
We implement this interface in a class and we create various data contracts (our response and argument classes).
[DataContract]
public class CreateAccountResponse
{
[DataMember]
public bool CreatedOk { get; set; }
[DataMember]
public int AccountId { get; set; }
}
These classes are exposed to our form using the Web Service (We create another assembly as a web service and have a class that inherits from our Service Class (not shown in this example) so we let Visual Studio do all the work setting up the WCF service as we reap the benefits with an easy to use and maintain Web Service.