What's does IMetadataExchange endpoint actually do? - asp.net

I'm working on a web service that uses ASP.NET security model (i.e. with AspNetCompatibilityRequirements set to allowed). Like many others, I got an error saying the Anonymous access is required because the mexHttpBinding requires it and the only way to get around it is to remove the mex endpoint from each service as described here:
WCF - Windows authentication - Security settings require Anonymous
I thought by removing mex endpoint I will no longer able to generate WSDL or add a reference to the service from Visual Studio but to my surprise everything still works. I quickly googled the "mex binding" but most web sites just say it's for "Metadata Exchange" without going into too much detail on what it actually does.
Can anyone tell me what's the side effect of removing the mex binding?

If your WCF service does not expose service metadata, you cannot add a service reference to it, neither from within Visual Studio (Add Service Reference), nor will another client be able to interrogate your service for its methods and the data it needs.
Removing Metadata Exchange (mex) basically renders the service "invisible", almost - a potential caller must find out some other way (e.g. by being supplied with a WSDL file, or by getting a class library assembly with a client he can use) about what the service can do, and how.
This might be okay for high risk environment, but most of the time, being able to interrogate the service and have it describe itself via metadata is something you want to have enabled. That's really one of the main advantages of a SOAP based service - by virtue of metadata, it can describe itself, its operations, all the data structures needed. That feature is used to make it really easy to call that service - you just point to the mex endpoint, and you can find out all you need to know about that service.

Without the metadata exchange, you won't be able to use svcutil.exe to automatically generate the proxy classes.

Related

How to use BizTalk Server to forward an existing SOAP WebService?

I am new to BizTalk development. I have an existing SOAP web service, which has around 50 different operations. I want to connect this service to another application, but use the BizTalk server as an intermediary in this communication. So service and application should not know each other directly, BizTalk should be able to log all messages going through etc etc.
What is the best approach to make this work in BizTalk Server 2013?
So far I tried to create a new BizTalk Application and import the SOAP web service there. Then however it seems that I need to create around 50 different orchestrations, each one just mapping the incoming message in BizTalk to the external service for each service operation. This seems very cumbersome. Also publishing all those orchestrations becomes painful, as BizTalk cannot merge those into a single endpoint again. Ideally I would like to publish a single endpoint for BizTalk server on IIS that is using the exact same WSDL as the target SOAP service, ideally without having to create any orchestrations at all. Is this possible?
Thanks!
So, yes, but...what you want is absolutely doable but there would be lots of answers for that. Once you learn how things in BizTalk are actually working, it's obvious how to do this.
For example, a single Receive Location (IIS endpoint) can receive any number of request types provided they are the same protocol/format, SOAP, REST/JSON for example. The only difference in the IIS site is any metadata, so just don't publish that. The Message differentiation is done in the Pipelines just like any other BizTalk Message.
You don't really need Orchestrations for Maps, you can apply those at the Port Level provided it's a 1-1 relationship between the SOAP call and Map.
Please try a few things. I'll become clear. You can always come back for any specific issues.

WCF service architecture query

I have an application that consists of a web application, and mutliple windows services, only one windows service is installed depending on what version of the backend sofware is used.
Currently, Data is saved by the web app in a database, then the relevant service is installed and this picks up the data and posts it in to the backend system that is installed.
I want to change this to use WCF services so the resulting data is returned directly to the web app.
I have not used WCF services before but Im assuming I can do something like this.
WebApp.Objects.Dll - contains Database objects, eg PurchaseOrder object
WebApp.Service.Contracts.dll - here I can describe the service methods, this will reference the WebApp.Objects.dll so I can take a PurchaseOrder object as a parameter
WebApp.Service.2011.dll - This will be the actual service for the 2011 version of the backend system, this will reference the WebApp.Service.Contracts dll
WebApp.Service.2012.dll - This will be the actual service for the 2012 version of the backend system, this will reference the WebApp.Service.Contracts dll
So, my question is, does the web app need to know the specifics about what backend WCF service is used? I just want to call a service with the specified Interface and not care about how its implemented or what it does internally, but just to return the purchase order that was created in the backend system (whether it return an interface or a concrete class)
Will i be able to create a service client without needing to know whether its the 2011, or 2012 WCF service being used?
As long as you are able to use the exact same contract for all the versions the web application does not need to know which version of the WCF service it is accessing.
In the configuration of the web application, you specify the URL and the contract. However, besides the contract there might be other differences between the services. In an extreme example this might mean that v2011 uses a different binding as v2012 of the backend - which is not very likely from your description. But also subtle differences in the configuration or the behavior of the services should be addressed in the configuration files. E.g. if v2012 needs longer for an action as v2011 does, the timeouts need to be configured so that the longer time of v2012 does not lead to an expiration.

WCF Data Services: Why is URI needed in every datacontext, and where does this fit in a typical Layered Architecture?

I am considering implementing WCF Data services in one of my projects. After extensive research, I have some questions that have yet to be answered. If someone can please help me out?
When we are passing concrete data specific operations (albeit over HTTP using URI's), why is a WCF data service next to the UI layer in most of the documentations? Shouldn't it be a higher level of abstraction than interfacing between UI and the EDM?
Why is the passing of a URI needed to establish context? Wasn't the URI passed into the ADD SERVICE REFERENCE (or DATASVCUTIL) to generate client proxy classes? Why this redundancy whenever a context needs to be established?
What if my service URL changes? How to determine this service URL dynamically? For example, let's assume I have a WCF DATA SERVICE at http://localhost:8443/project1/WCFSERVICE1. How can i get this URL dynamically at runtime (because of the changing port under VS)????
I have seen some examples where DataServiceRequest and DataServiceResponse are used; sometimes they are not and the query is directly executed via CREATEQUERY or EXECUTE. What is the difference in one line??
How to access a remote service over corporate network proxy? I know we can pass defaultcredentials to the webrequest but how is that to be done with wcf data service client proxy classes?
P.S. For now, I have configured a static port in visual studio. However, how to get this port dynamically?
Appreciate your help.
Just saw this, I'm sure by now you've got answers to most of these questions, but here goes.
Your question 3 is the answer to your title question. Passing the URI in the constructor means you have greater runtime flexibility for the location of the data service. So in my case I've got the port and server name as application settings that can be modified at runtime without the need to modify the application.
Hope this helps.

Avoiding having to map WCF's generated complex types

I have an ASP.NET MVC web app whose controllers use WCF to call into the domain model on a different server. The domain code needs to talk to a database and access to the database server isn't always possible from web servers (depends on the customer site) hence the use of WCF to get to a place where my code is allowed to connect to the database server.
This is configurable so if the controllers are able to access the database server directly then I use local instances of the domain objects rather than use WCF.
Lets say I have a page asking for person details like age, name etc. This is a complex type that is a parameter on my WCF operation like this :
[OperationContract]
string SayHello( Person oPerson);
When I generate the client code (eg; by adding a service reference in my client) I get a separate Person class that fulfills the wcf contract. The client, an MVC web app, can use this client Person class as the view model and all is well. I pass that straight into the WCF client methods and it all works brilliantly.
If my mvc client app is configured to NOT use WCF I have a problem. If I am calling my domain objects directly from the controller (assume I have a domain access factory/provider setup) then I need the original Person class and not the wcf generated Person class. This results in my problem which is that I will have to perform mapping from one object to another if I don't use WCF
The main problem with this is that there are many domain objects that will need to be mapped and errors may be introduced such as new properties forgotten about in future changes
I'm learning and experimenting with WCF and MVC can you help me know what my options are in this scenario? I'm sure there will be an easy way out of this given the extensibility of WCF and MVC
Thanks
It appears that you are not actually trying to use a service-oriented architecture. In this case, you can place the domain objects into a single assembly, and share it between the WCF service and the clients. When creating the clients, use "Add Service Reference", and on the "Advanced" tab, choose "Share Types". Either choose to share all types, or choose the list of assemblies whose types you want to share.
Sound service-oriented-architecture dictates that you use message based communication regardless of whether your service is on another machine, in another process, in another appdomain, or in your appdomain. You can use different endpoints with different bindings to take advantage of the speed of the link (http, tcp, named pipes) based on the location of your service, but the code using that service would remain the same.
This may not be the easiest or least time-consuming answer, but one thing you can do is avoid using the "add service reference" option, and then copy your contract interfaces to your MVC application and initiate the connection to WCF manually without automatically creating a service proxy. This will allow you to use one set of classes for your model objects and you can control explicitly when to use WCF or not.
There's a good series of webcasts on WCF by Michele Leroux Bustamante, and I think in episode 2, she explains how to do exactly this. Check it out here: http://www.dasblonde.net/WCFWebcastSeries.aspx
Hope this helps!
One sound option is that you always use WCF, even if client and server are in the same process, as Aviad points out.
Another option is to define the service contracts on interfaces, and to put these, together with the data contracts into an assembly that is shared between client and server. In the client, don't use svcutil or a service reference; instead, use ClientFactory<T>.
This way, your client code will use the same interfaces and classes as the server.

Can I check if a SOAP web service supports a certain WebMethod?

Our web services are distributed across different servers for various reasons (such as decreasing latency to the client), and they're not always all up-to-date. Rather than throwing an exception when a method doesn't exist because the particular web service is too old, it would be nicer if we could have the client check if the service responds to a given method before calling it, and otherwise disable the feature (or work around it).
Is there a way to do that?
Get the WSDL (append ?wsdl to the URL) - you can parse that any way you like.
Unit test the web service to ensure its signatures don't break. When you write code that breaks the method signature, you'll know and can adjust the other applications accordingly.
Or just don't break the web services and publish them in a way that enable syou to version them. As in http://services.domain.com/MyService/V1.1/Service.asmx (for .NET) so that way your applications that use v1.1 won't break when you publish v1.2 and make breaking changes.
I would also check out using an internal UDDI server if it's really that big of a hasle to manage your web services. Using the Green Pages of UDDI will tell you what you want to know about the service.
When you are making a SOAP request you are just sending an HTTP request to a server. If the server understands it, it will respond with an HTTP 200 and some XML back, if it doesn't it will send you some error HTTP code (404, 500, ...)
There is no general way to ask for the existance of a "method" exposed by a web service. Try to use the WSDL exposed if it is automatic, or just try to use the "method" and check for an error in the response (you don't have to send an exception to the user...)
Also, I don't know if I understood you well, but you are thinking of quering the server twice, once to check if the method exists, and second to make the actual call it if it does? I would just check for the error if it doesn't, and proceed normally if it does.

Resources