i need to call an old asmx web service (I have not control over)from a .net core web api
is it possible?
thanks
The way I was able to do it was fully update Visual Studio 2017, then get the latest WCF Connected Services extension from here:
https://marketplace.visualstudio.com/items?itemName=WCFCORETEAM.VisualStudioWCFConnectedService
After I did that, I was able to add and call the SOAP service like so.
Right click on Connected Services folder (should appear just below your project) and select Add Connected Service. Then select "Add a WCF web service". Put your asmx url into the URI field, set the name space and click Finish. You will now have the reference set.
An example of what my code does...
If you don't have an authorization header, you can ignore that part:
MySoapClient.EndpointConfiguration endpoint = new MySoapClient.EndpointConfiguration();
MySoapClient myService = new MySoapClient(endpoint, myURL);
AuthorizationSoapHeader MyAuthHeader = new AuthorizationSoapHeader();
MyAuthHeader.AppName = FDSServiceAppName;
MyAuthHeader.AppID = Guid.Parse(MyAppID);
Entry[] entries = MyService.GetUsers().Result;
The accepted answer is 100% correct, but there was one gotcha when trying to add an ASMX Web Service with VS WCF Connected Services that I encountered, but wasn't initially obvious to me.
In my case the web service that I was trying to connect to had disabled the WSDL in the Web.config. I had to remove or comment out the following in the Web.config to allow the metadata to be imported and code scaffolded successfully.
<webServices>
<protocols>
<!-- <remove name="Documentation" /> -->
</protocols>
</webServices>
Once <remove name="Documentation" /> is removed or commented out like the example above, the ASMX service will be able to be added to your project.
Related
I created a new web application in VS2013 and chose "Single Page Application" to see how the OWIN OAuth authentication was setup. Everything works great, however when trying to migrate the behavior to an existing application, I am not seeing where to change the database context to point it to our existing database?
In "Startup.Auth.cs" I see the following line ->
UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>());
Which can take a DbContext as a parameter. Do I have to create a new instance of the context here and pass it in? Will this keep the context open indefinitely or per request?
I was able to resolve this using the following article as a reference-
http://blogs.msdn.com/b/webdev/archive/2013/12/20/announcing-preview-of-microsoft-aspnet-identity-2-0-0-alpha1.aspx?PageIndex=2
With VS 2010 SP1 I created an ASP.NET MVC4 project from the "internet" template. I then created a connection string for SQL Server CE 4.0:
<add name="DefaultConnection"
connectionString="Data Source=|DataDirectory|MyDatabase.sdf;Password=123456"
providerName="System.Data.SqlServerCe" />
With the web application successfully debug-launched in cassini, I choose the "Register" user option. Immediately this causes the InitializeSimpleMembershipAttribute filter to execute. The filter crashes the site when it reaches this code:
Database.SetInitializer<UsersContext>(null);
using (var context = new UsersContext())
{
if (!context.Database.Exists())
{
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
//This line never executes. It is meant to configure my custom user table.
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "Users", "ID", "UserName", true);
The Exists() check throws an ArgumentException stating:
Unable to find the requested .Net Framework Data Provider. It may not be installed.
Now I wanted to be sure that (1) there was nothing wrong with my connection string and (2) there was nothing wrong with my provider. To do that, I inserted a snippet of code before the Exists() check. The snippet used a new SqlCeEngine to create the database, and Dapper calls to setup user tables. That code worked just fine, just before exploding on the Exists() check again.
I then considered that EF might need some additional setup help. I tried replacing the EF defaultConnectionFactory in my web.config:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
<parameters>
<parameter value="System.Data.SqlServerCe.4.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
Still the exception I received did not change.
I'm now wondering if EF needs a "special" connection string to work with SQL Server CE. I will be checking here and here. But at first glance I'm not sure that is the issue.
Thoughts?
EF requires the providers to be installed.
Use one the connect to DB options to check. eg ADD Entity DAta Model to Project. Just to the providers available to it. Do you see your preferred connection Client ?
Seems Compact edition should work with some restrictions...
http://technet.microsoft.com/en-us/library/cc835494.aspx
So then I think its The "DEFAULT CONNECTION" issue
See the Context constructor. EF looks for a connection by that name unless you pass an alternative in.
try...
<connectionStrings>
<add name="MyContextName" connectionString="bla";App=EntityFramework"
providerName="System.Data.SqlServerCe.4.0" />
You need to install Sql Server Compact edition. You can download it from here.
In CRM 4.0 we could place dynamic content (aspx) in the ISV-folder in CRM, creating separate applications but with security and relative URLs to CRM, so for example a custom 360 view of account could be linked in an iframe using a relative URL along the lines of
/ISV/CrmMvcApp/Account.aspx/Overview?id=....
In CRM 2011 usage of the ISV folder is deprecated and Microsoft has some guidelines on how to transition into doing this in supported manner (MSDN gg309571: Upgrade Code in the ISV folder to Microsoft Dynamics CRM 2011). They say:
For scenarios that will not be satisfied by the Web resources feature, create your Web application in its own application pool with its own web.config.
The way I am reading this (coupled with the guidelines on supported/unsupported) is that we need a separate web site in IIS with its own binding as you are not allowed to add virtual directories etc. under the standard CRM app. This is unfortunate and does not allow relative paths/URLs in customizations and sitemap. This is troublesome especially when exporting and importing solutions from DEV, TEST and/or PROD.
Are my assumptions wrong?
Can we somehow have relative paths?
Have anyone else found a pragmatic and easy approach to having external content without doing the sitemap and customization changes for each environment?
EDIT: Confirmed with other sources that my understanding of the guidelines are correct, as this is also listed in the list of unsupported changes. Virtual folders and web apps are to be kept totally separated from the default CRM web site.
Creating an Internet Information Services (IIS) application inside the Microsoft Dynamics CRM website for any VDir and specifically within the ISV folder is not supported.
MSDN gg328350: Unsupported Customizations
If you primarily need to access CRM data/records, take a look at using a jScript web resources. You can do "most" CRUD operations using the REST OData services. If you use JQuery to parse the JSON it's very productive.
I have found a solution much like the javascript redirect, without the need for client execution and only configuring the environment details (servername, port) once. Additional logic can easily be added.
The solution creates a dependency into the customizations, but not an environment one like and can be used for unmanaged and managed solutions.
The solution was to place a file Redirect.aspx in the ISV folder. The code does not in any way interact with CRM and falls within the supported guidelines, however the solution is not future proof as the ISV folder is deprecated by Microsoft.
Redirect.aspxwill automatically pass along any parameter passed, so will work with or without the entity identifiers and so on.
Usage:
Place the file in the ISV folder on the CRM app server
Change the server name and port to match the current environment (must be done for each environment)
In customizations, for example for an iframe, use the following as a source:
/ISV/Redirect.aspx?redirect=http://SERVERREPLACE/CustomMvcApp/SomeControllerAction
Here is the content of Redirect.aspx
<%# Page Language="C#" %>
<html>
<script runat="server">
protected override void OnLoad(EventArgs e)
{
// must be customized for each environment
const string ServerBaseName = "appserver1:60001";
const string UrlParameterName = "redirect";
const string ReplacePattern = "SERVERREPLACE";
var parameterUrl = Request.Params[UrlParameterName].Replace(ReplacePattern, ServerBaseName);
var queryStringBuilder = new StringBuilder();
foreach (var key in Request.QueryString.AllKeys)
{
if (key == UrlParameterName)
{
continue;
}
queryStringBuilder.Append(!(queryStringBuilder.Length > 0) ? "?" : "&");
queryStringBuilder.Append(key + "=" + Request.QueryString[key]);
}
var completeRedirectString = parameterUrl + queryStringBuilder;
Response.Redirect(completeRedirectString);
}
</script>
<head>
<title>Redirecting</title>
</head>
</html>
Not quite "relative urls" as per your question, but a solution I use is to store "stub" or "root" urls in a config entity and read those records in JScript at runtime to determine the fully qualified destination for your custom links.
Can someone please post a confirmed example using linq to retrieve and update a record in CRM Dynamics 2011.
Microsoft claims this is "unsupported" but I have a suspicion it is possible.
I use the "early bound" approach where you generate C# entity classes using the CrmSvcUtil.exe tool, but make sure you use the /codecustomization switch that you'll find in various examples. You'll need the latest version of the CRM 2011 SDK, and must run CrmSvcUtil.exe from the \bin folder of that (don't use the version that installs with CRM).
Your project will need to reference Microsoft.Xrm.Client, Microsoft.Xrm.Sdk and Microsoft.Crm.Sdk.Proxy plus a few others from the .Net framework (look at the build errors to see what you're missing, then add them until it builds).
Here is a basic code snippet that retrieves a Contact entity, updates one of its fields, then saves it back to CRM:
CrmDataContext dc = new CrmDataContext("Xrm");
Contact contact = (from c in dc.ContactSet
where ...whatever...
select c).FirstOrDefault();
contact.FirstName = "Jo";
dc.SaveChanges();
(Note that CrmDataContext is the name of my data context. You can set this name using one of the CrmSvcUtil command line switches).
You'll also need to add a few things to your web.config:
<configSections>
<section name="microsoft.xrm.client" type="Microsoft.Xrm.Client.Configuration.CrmSection, Microsoft.Xrm.Client" />
</configSections>
<connectionStrings>
<add name="Xrm" connectionString="Server=http://<your crm url>; Domain=<your domain>; Username=<a crm user id>; Password=<their password>" />
</connectionStrings>
<microsoft.xrm.client>
<contexts>
<add name="Xrm" type="" />
</contexts>
</microsoft.xrm.client>
This is assuming you are running CRM on your corporate network, so the account and domain specified in the connection string would be an AD account, who is set up as a CRM user with relevant permissions to retrieve and update entities.
This is a rough example of using the ODATA provider connected to the online provider
var serverConfig = GetServerConfig(sessionKey);
// Connect to the Organization service.
// The using statement ensures that the service proxy will be properly disposed.
using (var serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri, serverConfig.Credentials, serverConfig.DeviceCredentials))
{
// This statement is required to enable early-bound type support.
serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
using (var orgContext = new CrmServiceContext(serviceProxy))
{
return orgContext.AccountSet.Where(item => item.Id == id).Select().Single();
}
}
there's also a good example in the SDK:
CRM2011Sdk\sdk\samplecode\cs\wsdlbasedproxies\online
I was encouraged to learn that the Sharepoint 2010 Client Object Model essentially wraps remote calls to the server. So, I copied the Microsoft.Sharepoint.Client.Silverlight.dll and Microsoft.Sharepoint.Client.Silverlight.Runtime.dll from my Sharepoint 2010 server to my development machine (without Sharepoint). I assumed the Silverlight code I tested on the Sharepoint 2010 server would also work on my development machine. Naturally, I don't use the "ApplicationContext.Current.Url" because I am not executing in Sharepoint, so I manually add sharepoint server name as follows (kept anonymous for the post):
//ClientContext context = new ClientContext(ApplicationContext.Current.Url);
ClientContext context = new ClientContext("https://[servername]");
_web = context.Web;
context.Load(_web);
context.Load(_web.Lists);
context.ExecuteQueryAsync(new ClientRequestSucceededEventHandler (OnRequestSucceeded), new ClientRequestFailedEventHandler(OnRequestFailed));
When I execute the code, I am prompted by a Windows Authentication window (Sharepoint is configured to use Windows Authentication), I add my domain/user and password. However, I am getting the following error:
Note: I was able to get Sharepoint 2010 web services working given a similar error by changing the binding security mode="Transport" and including a clientAccessPolicy.xml file on the Sharepoint root website. Do I need to configure another Sharepoint directory for thje Client Object Model endpoint?
Exception {System.Security.SecurityException ---> System.Security.SecurityException: Security error.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.b__0(Object sendState)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryGetResponseAsyncCallback(IAsyncResult asyncResult)} System.Exception {System.Security.SecurityException}
Please look in to the below blog post, you need to add clientaccesspolicy.xml file in your sharepoint website root folder.
http://vangalvenkat.blogspot.com/2011/08/sharepoint-2010-getting-list-item.html
Aha, I found it. You can set the security on the client context to use the default windows authentication like so:
using (Microsoft.Sharepoint.Client.ClientContext ctx = new Microsoft.Sharepoint.Client.ClientContext("http://sharepointserver")){
ctx.AuthenticationMode = Microsoft.Sharepoint.Client.ClientAuthenticationMode.Default
}
This should also prevent any windows authentication pop-ups