I'm trying to create an application in Visual Studio 2015 that calls a web service set up on one of our servers (It's a third party web service so I don't really know anything about its implementation).
I can browse to the web service definition, and view the wsdl and singleWsdl definitions.
In Visual Studio, I right-click on the Service References folder and choose 'Add Service Reference...', type in the URL to the web service (I've also tried the wsdl and singleWsdl URLs which produce the same result) and click 'Go'. The operations are shown, so I enter a namespace and click 'OK'.
At this point lots of code is generated, but, and I think this is the cause of my problem, there are no changes made to the config file.
When I try and run my code I get an error:
"An exception of type 'System.InvalidOperationException' occurred in
System.ServiceModel.dll but was not handled in user code
Additional information: Could not find default endpoint element that
references contract 'CRMContactEventService.ContactEventService' in
the ServiceModel client configuration section. This might be because
no configuration file was found for your application, or because no
endpoint element matching this contract could be found in the client
element."
I've tried using SvcUtil.exe to generate the proxy but it also does not generate any config file. I've tried using wsdl.exe to generate another wsdl file but that just generates an empty file. I've tried saving the singleWsdl file to my local drive and using that instead of the URL but the results are the same.
Now after lots of searching, I have tried to manually add what I think is missing to the web.config file:
<system.serviceModel>
<client>
<endpoint address="http://...<url to service>.../ContactEventService.svc"
binding ="netHttpBinding"
contract = "CRMContactEventService.ContactEventService" />
</client>
</system.serviceModel>
This changes the error message:
"An exception of type 'System.ServiceModel.EndpointNotFoundException'
occurred in mscorlib.dll but was not handled in user code
Additional information: There was no endpoint listening at
http://....../ContactEventService.svc that could
accept the message. This is often caused by an incorrect address or
SOAP action. See InnerException, if present, for more details."
InnerException contains:
"The remote server returned an error: (404) Not Found."
I have tried several different values for the binding parameter in the web.config file as I don't know which one to use, but most return the above error or some other error which makes it clear that I made a bad choice.
I've been looking at this problem for far too long and I cannot see how to get this working, or even whether it's a problem with what I am doing or a problem with the web service.
Can you first manually make the SOAP call to the actual service endpoint and check if you're getting the expected result? The free SoapUI client is very useful for this type of troubleshooting. (Having said that, if the remote endpoint is responding correctly, I think you're on the right path to figuring this out.)
Related
I have an MVC website (v5, though I don't think it's related) where I have intentionally introduced an error upon when attempting to establish a database connection (wrong server IP in the connection string). When the user hits the HomeController one dependencies for the constructor is a UserRepository (to get the current user profile data) which depends on a database connection/session to be available. When it's not, the Dependency Resolver can't inject the UserRepository and when that happens it causes an error (as it does with any dependency of any controller), and I get a generic "No parameterless constructor defined for this object". Which is pretty useless.
So I'm trying to use a custom error page to retrieve the inner exception and display it in a friendly manner. (Because this error is happening when trying to acquire the HomeController, it never actually reaches the HandleErrorAttribute, hence the relying on CustomErrors).
So I have an ErrorsController with a series of actions...
Snippet from ErrorsComtroller.cs
public ActionResult Error()
{
return View("Error_500");
}
public ActionResult NotFound()
{
return View("Error_404");
}
Snippet from web.config
<customErrors mode="On">
<error statusCode="404" redirect="~/errors/notfound" />
<error statusCode="500" redirect="~/errors/error" />
</customErrors>
The Error_500 page is pretty basic, it has a model type of HandleErrorInfo, but if it's not present it checks for Exception details using Server.GetLastError(). Problem is, GetLastError() is always null, and I get my custom error page but no additional details beyond my generic feedback of "An unexpected error has occured". After doing some digging I found that the method doesn't work after a redirect, which is the default way the CustomErrors functions. So I changed the web.config to use this line instead...
Snippet from web.config
This way it won't cause a redirect and the GetLastError() should have my exception details about the database connection problem. Thing is, now I get the default ASP.NET error page with this message.
An exception occurred while processing your request. Additionally,
another exception occurred while executing the custom error page for
the first exception. The request has been terminated.
So I did some more digging using intellitrace, and I see the exception about the database connection. A little farther down I see the error about not having a parameterless constructor on HomeController and then one about encountering an error trying to create the controller of type 'HomeController'. But then I see one that says
Error executing child request for /errors/error
So I navigated directly to that path and the page works fine. But when it's used in customerrors WITH the ResponseRewrite for the redirectmode, it errors out. I put a break line on the first (and only) line of the ErrorsController.Error() action, but it never gets hit. If I substitute the redirect path in the custom errors to a static file it works, but if I change it back to the ~/errors/error it fails again.
Is there a issue when using MVC actions as url's for the CustomErrors when ResponseRewrite is specified?
"This happens because "ResponseRewrite" mode uses Server.Transfer under the covers, which looks for a file on the file system. As a result you need to change the redirect path to a static file, for example to an .aspx or .html file:"
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx"/>
See: https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging
"Apparently, Server.Transfer is not compatible with MVC routes, therefore, if your error page is served by a controller action, Server.Transfer is going to look for /Error/Whatever, not find it on the file system, and return a generic 404 error page!"
See: CustomErrors does not work when setting redirectMode="ResponseRewrite"
In other words, you cannot use ResponseRewrite with views.
This is a well known issue that has been problematic for developers because it does not afford itself to either an easy or elegant solution. Bottom line, MVC does not play nice when using custom views for exception handling and customer user-friendly pages for HTTP errors. The stock error.cshtml file (i.e., a View) in the Views\Shared folder is a great thing to have because it maintains the layout of the web page and provides exception errors. But, when you get HTTP errors then you need to create a view to handle the status code errors (e.g., 404, 500, etc.). Note: if you go the route of sending HTTP errors to a view then the URL line will contain non-ideal info (see weblinks below for further explanation).
You could route HTTP errors to the Error view, but I don't recommend it because the Error view should be for application errors (i..e, exceptions) whereas a separate custom user-friendly page should be created for generic HTTP errors. The difference is that the former is an application problem that the site developer needs to look at whereas the latter is a user error (or at least should be) that does not require the developer to look at it (just my 2 cents).
An alternative is to bypass the views and use custom user-friendly pages for both application exceptions and HTTP errors. But, beware of two problems:
1.) The wrong status code is returned (usually 200), which can be a problem because it will be picked up and indexed by search engines (you do not want this!)
2.) The URL specifies a non-sensical URL in the web browser
These can be handled easy enough. See the following link (go down to the section customErrors in web.config): https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging
Below are other weblinks that I also found useful:
http://benfoster.io/blog/aspnet-mvc-custom-error-pages
https://msdn.microsoft.com/en-us/library/bb397417.aspx
https://www.youtube.com/watch?v=nNEjXCSnw6w
How do I display custom error pages in Asp.Net Mvc 3?
The last one appears to be yet another alternative: a custom hack to get around the problem of not being able to couple views with ResponseRewrite. This works by completely bypassing CustomErrors (i.e., CustomErrors mode="Off"). I have not yet tried this yet, but I am looking into it.
Final thought, keep an eye on all site status codes when either error or exception codes are thrown - make sure there are no 200 (i.e., OK) codes.
I have a problem when calling web Services in ASP.net MVC , I do the following
add the web service by add service reference to solution, and I include the service.cs file to the solution also, but when I try to create object in home controller , I have the following error
Could not find default endpoint element that references contract 'Service' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
can any one help me please
thanks
There's a couple things going on here. First, you're using SVCUTIL to generate a proxy and configuration settings for a non-WCF service - .asmx is legacy. I was able to generate a proxy and config settings, but to overcome the error you got you need to call one of the overloaded versions of WeatherHttpClient.
I'm not 100% sure, but this is what I think based on what I observed.
The reason is because there are two endpoints defined in the configuration file (one for SOAP 1.1 and one for SOAP 1.2), and since both endpoints are named there is no default endpoint to choose from.
When I used var x = new WeatherHttpClient(new BasicHttpBinding("WeatherSoap"), new EndpointAddress("http://wsf.cdyne.com/WeatherWS/Weather.asmx")); I was able to create the proxy just fine.
However, when I called GetCityForecastByZip I got the following error:
Server did not recognize the value of HTTP Header SOAPAction: http://ws.cdyne.com/WeatherWS/WeatherHttpGet/GetCityForecastByZIPRequest.
So then I used WSDL.exe to generate the proxy a la .ASMX style. I included that in my project, and the following code returned a result (after including a reference to System.Web.Services - I was using a console app):
var x = new Weather();
ForecastReturn result = x.GetCityForecastByZip("91504");`
I would suggest for simplicity using WSDL.exe to generate the proxy for your service, as it seems to be simpler.
I will also add that I've done very little MVC, but I don't think this is an MVC issue. I hope this helps you.
I am reasonably experienced in BizTalk but new to the ESB Tool kit. We don't really have the need for an ESB solution as such but I would like to use the ESB Portal to display errors, modify messages and resubmit.
I have successfully, as far as I can tell, installed and configured the ESB tool kit correctly on my dev machine.
I have managed to send errors to the portal by enabling routing for failed messages and from within an Orchestration by creating a message thus: FaultMessage = Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.CreateFaultMessage();
The messages display correctly in the portal and on selecting 'Edit' I am given the option to resubmit via WCF OnRamp, SOAP OnRamp and HTTPReceive. This is where my problem starts. I have been using the WCF OnRamp to resubmit and on doing so I get a message:
This message has been successfully resubmitted
However on returning to the home screen of the portal I now have a new error for the Microsoft.Practices.ESB application:
There was a failure executing the receive pipeline: "Microsoft.Practices.ESB.Itinerary.Pipelines.ItinerarySelectReceiveXml, Microsoft.Practices.ESB.Itinerary.Pipelines, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Source: "ESB Itinerary Selector" Receive Port: "OnRamp.Itinerary" URI: "/ESB.ItineraryServices.WCF/ProcessItinerary.svc" Reason: Error 135008: The itinerary was not found in the repository.
I presume I need to configure something here, a resolver perhaps for my message but I, so far, have not been able to find a guide that will help me through this issue. Is there a walk through out there some where that shows the full end to end exception handling with ESB Portal? I have managed to find plenty of help with getting messages into it but not for configuring for resubmit. Thanks.
Coincidentally I was trying to make this work today as well...
If you set the Itinerary resolver connection string on the WCF OnRamp's receive pipeline component configuration to use ITINERARY-STATIC:\headerRequired=true; (instead of ITINERARY-STATIC:\headerRequired=false;), then you'll get the following message in the event viewer:
The itinerary name is required and was not provided
Meaning the Itinerary isn't present in the custom SOAP header.
I also traced the message going from the ESB.Portal using Fiddler (after turning off the Message security in both the ESB.Portal and the BizTalk receive location). No Itinerary custom SOAP header.
After going through the ESB.Portal code, I found the cause in MessageResubmitter.cs:
[Serializable]
public static class MessageResubmitter
{
/// <summary>
/// Submits an XML message to the WCF OnRamp. The URL of the WCF OnRamp is defined in the
/// portal web.config. Context properties are not resubmitted, they are expected to be
/// applied by the receiving pipeline.
/// </summary>
/// <param name="doc">The XML document to submit.</param>
/// <returns>True if the submission was successful, false if the submission failed.</returns>
public static bool ResubmitWCF(XmlDocument doc)
{
try
{
ProcessRequestClient onRamp = new ProcessRequestClient();
onRamp.SubmitRequest(**null**, doc.OuterXml);
return true;
}
catch (Exception)
{
return false;
}
}
The first argument of SubmitRequest is the Itinerary, which is set to null. This means the ESB.Portal does not resend the Itinerary as a custom SOAP header to BizTalk when you resubmit the message.
At the moment, I can think of the following options to make this work:
1) Create a (or modify the existing) generic WCF OnRamp to use the BRE to determine the Itinerary to be associated with the resubmitted message. This could however become complex, because you'll need to create your rules to be able to deal with any messages resubmitted from any step within your itineraries.
2) Modify the code of the ESB.Portal to be able to resend the Itinerary + current step as a Custom SOAP header.
I'm probably going for option 2.
The WCF OnRamp uses the ItinerarySelectReceiveXml pipeline this can be configured to point to an Itinerary or Business Rule and thus the message can be easily routed depending on its message type and content.
My issue now is that a third party got there before me on our installation so I am now looking into creating a new OnRamp and configuring the ESB portal to pick that up in its resubmit list.
We had a similar issue recently. While we were exporting our itineraries to a local database, and deploying them, the ESB would not be able to find the itineraries.
It turned out a consultant we had on site had modified the esb.config file in ESB Toolkit to look for itineraries on a server instead of the local machine.
So, if, like me, you are sure the itineraries are being exported to the right place and that they are deployed, modify the esb.config connection string.
<connectionStrings>
<add name="ItineraryDb" connectionString="Data Source=.;Initial Catalog=EsbItineraryDb;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionString>
Using Visual Studio I have a Class Library (C#) where I added a reference to a Service (more preciselly a Web Service).
The Web Service classes and interfaces where generated correctly, and I am trying to consume them using the following code (the web service receives an returns a string):
CallWS request = new CallWS();
request.input = "input string";
WSClient client = new WSClient();
CallWSResponse response = client.CallWS(request);
The last line originates the following exception:
Could not find default endpoint element that references contract 'WS_INTER' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
How do I solve this?
You have to add an application configuration file and set up system.serviceModel section defining the address of a service.
You can certainly do that in code. Check this or MSDN for description
I created a WCF service (.NET 3.5) that grabs data from a db and returns a list of objects. It works just fine. I tested it using the WCFTestClient application and got the desired results.
Now, I tried to create an ASP.NET web application and consume the service. After enabling <serviceDebug includeExceptionDetailInFaults="true"/> in the config file, the error message is "Object reference not set to an instance of an object."
How do I modify the service to work with ASP.NET?
Thanks!
Update 1 - I created a reference to the service. When I ran my very basic testing app, based on the sample code displayed on the service's default web page, I got the "Object reference not set to an instance of an object" message.
The service is returning the correct results when I use the WCF Test Client utility provided with Visual Studio. When I try to use the following code, all in the page_load event, I get the object reference message.
PhoneNumberServiceClient client = new PhoneNumberServiceClient();
// Use the 'client' variable to call operations on the service
List<PhoneNumber> phones = client.GetPhoneNumbers();
// Always close the client.
client.Close();
I will try to get some additional debug info.
Have you tried openning the service after you initialize it by using:
client.Open();
If the problem still persists maybe the it lies on the WCF method itself. Try to add breakpoints on your method and debug it to trace the cause of the error. You could also use profilers.
You also have to configure the Service to allow exception details in results. Follow the info in here to make that happen.
I presume your ASP.NET app is expecting to catch certain information from the service that you have not set it up to provide, hence the null object error.
I would have written this as comment, but couldn't figure out how to, so I guess I'll attempt an answer.
You mentionned you used the built in test client, but when You created your client application(the website that you want to be calling your new service with) have you configured it's end point(web.config) to match the end of your wcf service? For example, a client app calling a wcf service with wsHttpBinding endpoint:
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost:8080/ContractorService" binding="wsHttpBinding" contract="ContractorService.IContractorService"
name="ContractorService_WsHttp">
</endpoint>
</client>
</system.serviceModel>
Also, your service is returning a list, the default service reference that you added to your client very likely stops at array. Right click the service reference your client now has and select configure service reference, in the drop down box for collection type, instead of System.array, select System.Collections.Generic.List.
If you need details on configuration, check here http://msdn.microsoft.com/en-us/library/dd936243.aspx
Place a break point in the Page_Load method of your client, you should be able to step through your client code and it will jump in automatically in your wcf service once you call it's method, then you can see exactly where it fails.
Hope this helps