how to consume webservices from asp.net mvc application - asp.net-mvc

There is a external web services.
I can invoke it from my winform application, but I cannot invoke it from my asp.net mvc web application.
Error message is like this :
System.ServiceModel.EndpointNotFoundException: There was no endpoint listening at http://ihexds.nist.gov:9080/tf6/services/xdsrepositoryb that could accept the message. This is often caused by an incorrect address or SOAP action.
Is there anything to configure for my mvc web application to consume it?
Edit :
following is my code to invoke web services
WCF.Message msgInput, msgOutput;
msgInput = WCF.Message.CreateMessage(MESSAGE_VERSION, PROVIDEANDREGISTERDOCUMENTSETB_WSAACTION, request);
msgOutput = WCF.Message.CreateMessage(WCF.MessageVersion.Soap12WSAddressing10, "");
string endpointName = GetRepositoryEndPointName();
XDSRepository.XDSRepositoryClient client = new XDSRepository.XDSRepositoryClient(endpointName);
msgOutput = client.ProvideAndRegisterDocumentSet(msgInput);

Judging from your comments, I think your problem is proxy server related. I think you're using a proxy server internal to your company. You have to specify in you web.config file that you want the dotnet code to use the credentials you're logged on with. Add this to your web.config and try again:
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true" >
</defaultProxy>
</system.net>
It's also possible that you're working with a .pac script. In that case you have to explicitly specify the proxy server like so:
<system.net>
<defaultProxy useDefaultCredentials="true">
<proxy proxyaddress="http://proxyserver:proxyport"/>
</defaultProxy>
</system.net>

Related

How to solve MVC 5 Update and Delete Error

I have built MVC 5 Web application in .net 4.7.2. It runs fine in my local machine. Update and Delete commands were failing, which I have now sorted out thanks to this post: DELETE/PUT verbs result in 404 Not Found in WebAPI, only when running locally, I added this line to the web.config and all the CRUD now works:
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0
However, when I publish the application to my hosting server it breaks at this line in the web.config.
When I remove the line only Create and Retrieve data works, but Update and Delete fails with the error:
Object reference not set to an instance of an object.
at this line in the Index view: Line 40: #For Each item In Model
I understand this is because the model is null/nothing at this point.
This is my delete function showing where the error starts...
Public Function Delete(ByVal id As Integer) As ActionResult
Dim Client As HttpClient = New HttpClient()
Client.BaseAddress = New Uri(myWeb & "AppMenuCRUD")
Dim APIConsumer = Client.DeleteAsync("AppMenuCRUD/" & id.ToString())
APIConsumer.Wait()
Dim Result = APIConsumer.Result << failure here: Error 404
If Result.IsSuccessStatusCode Then
Return RedirectToAction("Index")
End If
Return View("Index")
End Function
The hosted server is running Windows Server 2016, .Net 4.7.2. I have enabled read/write to the website folder.
This is my IIS Settings in the hosting server:
UPDATES:
Having looked further into this, my hosting server is now updated to .net 4.8 and everything now just fails. I am now not able to even load the index view page. It breaks at the same line 40 as above.
In IIS, my application pool is set to integrated, .net 4.0. I cannot see anything higher from the dropdown list.
In IIS, I have nothing filtered in the list of HTTP Verbs, which I believe means it should accept anything.
UPDATE 2
After the updates to .net 4.8, I am now getting a new error
Lock Violation
I have enabled everything in the IIS, including changing all the ASP Configurations from Read Only to Read/Write.
I'm fearing I may introduce vulnerabilities to the VPS...
Is there anything else I need to do to get this to work?
Sometimes you need to update manually the Web.config when you change the target framework, please double check those lines:
<system.web>
<compilation debug="true" targetFramework="4.8">
<httpRuntime targetFramework="4.8" />
...
So, this is how I finally got it to work:
I am hosted with Plesk as 'control cpanel'. Apparently, Plesk has some lock which I had to unlock here:
Plesk > Tools & Settings > Security > Prohibit the ability to override handlers
Thanks to https://support.plesk.com/hc/en-us/articles/115000287305-Site-shows-500-19-Internal-Server-Error-Config-Error-Lock-violation. I was quite surprised my host could not help with this!
In the gymnastics of enabling everything else in my VPS, I ended up enabling/installing WebDAV. This also apparently does not 'allow' Edit/Delete actions. Instead of uninstalling it, I sorted it out from the web.config like this:
<system.webserver>
...
Thanks to Web API Put Request generates an Http 405 Method Not Allowed error

Email functionality in .net web app cannot be implemented due to SMTP server credential problem

I am developing a web app in .NET using MVC and need to implement a functionality to allow the user to send a mail from his mail_id to another. Both the mail ids are in the same domain. I am using the System.Net.Mail class. But I am facing problems since the SMTP server need the sender credentials. The solutions I came across says to use the Net.NetworkCredentials class to give the username and password. But doesn't that require the user to give his credentials to the server? Isn't it not preferable? Is that the correct way? I think I am missing some fundamentals here. The app uses windows authentication to validate users.
try
{
string fromAddr = sender + "#microsoft.com";
string toAddr = receiver + "#microsoft.com";
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient(smtp_server_dns);
//SmtpServer.UseDefaultCredentials = true;
mail.From = new MailAddress(fromAddr);
mail.To.Add(toAddr);
mail.Subject = sub;
mail.Body = body;
SmtpServer.Send(mail);
}
catch
{
throw;
}
}
You may need to use CredentialCache, and will need to pass the Exchange server name in its parameter.
Try similar to below:
SmtpClient client = new SmtpClient("smtp.your-mailserver.com");
client.Credentials = CredentialCache.DefaultNetworkCredentials;
Ignore from here - It was due to misinterpretation in the question
Ideally, you should have the credentials for SMTP within the web.config file. Though there are no any drawbacks to specifying them straight-away in code. However, for better maintainability purpose, web.config is the ideal place where it is also easy to switch the network delivery mode (like, file system for testing environments).
Just similar to below -
<?xml version="1.0"?>
<configuration>
<system.net>
<mailSettings>
<smtp from="youremail#yourdomain.com">
<network host="smtp.yourdomain.com" port="25" userName="yourUserName" password="yourPassword"/>
</smtp>
</mailSettings>
</system.net>
</configuration>
You also need to set "EnableSsl" property of the smtpClient object to true. Once hosted with Https protocol, your web server will connect with the smtp server in a secured way and the encryption will be handled by .NET.

Service Worker in Asp.Net MVC, scope

Does the scope of a service worker have to be root for an asp.net mvc application? It needs to see the controller, it will need scripts, etc. My concern is what happens on a very large application.
If using an Area, you can include scripts in the area so that's one way of narrowing it down, are there any best practices?
You can place the service worker file anywhere you want. Here's how I did it.
Let's assume you setup an area called "Customer". So your file structure would be "/Areas/Customer", "/Areas/Customer/Controllers", "/Areas/Customer/Models", "/Areas/Customer/Views", etc. Assuming you didn't change the routing, the url would be "https://www.somewebsite.com/customer". If you want to make the scope of your service worker "/customer", but not have the service worker javascript file in the root, you would do the following.
I'm going to make another assumption that you created a "scripts" folder in this location "/Areas/Customer/Scripts" to hold your server worker js file.
In the javascript file that registers your service worker, you would do something like this.
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/areas/customer/scripts/serviceworker.js", { scope: "/customer" })
.then(registration => {
console.log("Service Worker registered properly.");
})
.catch(error => {
console.log("Service Worker NOT registered properly.");
});
}
If you run the site now, you will receive an error similar to this "The path of the provided scope ('/customer') is not under the max scope allowed ('/areas/customer/scripts/'). Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope."
What you need to do is update your web.config file with the below text in order to send the Service-Worker-Allowed HTTP header. This goes in the "configuration" section of web.config.
<location path="areas/customer/scripts/serviceworker.js">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Service-Worker-Allowed" value="/customer" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
This should now allow you to have your serviceworker.js file in a folder other than the root, but still keep the scope of the service worker to the correct area.

How can I add “X-Content-Type-Options: nosniff” to all the response headers

I am running an ASP.NET MVC 3 website on IIS. Is there a flag in web.config or something similar that can do this?
As long as you're using IIS 7 or above, it's as simple as adding it to your web.config.
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
Or you can add them using the IIS Management GUI, or even command line. Take a look at http://www.iis.net/configreference/system.webserver/httpprotocol/customheaders
This question originates from MVC 3, but as this problem is still relevant in ASP.NET Core, I'll let myself propose a solution for the recent versions:
public static IApplicationBuilder UseNoSniffHeaders(this IApplicationBuilder builder)
{
return builder.Use(async (context, next) =>
{
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
await next();
});
}
Then simply add this in Startup.cs:
app.UseNoSniffHeaders();
The beauty of this approach is that it makes it independent from your web server and deployment process. At the same time you may need to extend this solution if you want it to apply to static files as well.
In case whenever you deploy new application and its replacing the web.config file. its better to add the configuration IIS site level as below.
Click on site and select the 'HTTP response headers".
Click on 'add' on left side corner and add the name and value as below.
name: X-Content-Type-Options
value: nosniff
The nosniff response header is a way to keep a website more secure. Security researcher Scott Helme describes it like this: “It prevents Google Chrome and Internet Explorer from trying to mime-sniff the content-type of a response away from the one being declared by the server.

IIS Express defaulting to port 44300 for HTTPS when enabling SSL

When you initially set up IIS Express to enable SSL, it defaults the port to 44300. Unfortunately, when I try to access my site in on https://localhost/ it doesn't work unless I use the port number 44300 - https://localhost:44300/.
The links are generated using the following:
<%= Html.ActionLink("Index", "Index", "Home", new { #action = "https://" + Request.Hostname + Url.Action("Index", "Home") }) %>
Although an ugly solution, the #action keyword can override the generated route, but it means that the application would seemingly need to be aware of any non-standard ports (eg 44300).
The problem with that is that I'd be writing something to solve a problem that would only occur in a development environment.
So my question is... How do I change the port to 443 and have IIS Express like it?
Config for my site is below:
<site name="MySite" id="2" serverAutoStart="true">
<application path="/">
<virtualDirectory path="/" physicalPath="C:\Inetpub\MySite" />
</application>
<bindings>
<binding protocol="http" bindingInformation=":80:" />
<binding protocol="https" bindingInformation=":44300:" />
</bindings>
</site>
Many thanks in advance.
Update:
This question has been answered by Divya over on the IIS forums.
This question has been answered by Divya over on the IIS forums.
Once you enable SSL for a website in WebMatrix, it defaults to port 44300 and does all the bindings in the background. I am hoping that you tried to change this port to 443 in the config file. Once that is done and saved, you also need to modify the binding in http.sys. You would need to delete the existing entry for port 44300 and add the entry for port 443.
To do this, you could use httpcfg (WinXp/Win2003) or 'netsh http' (WinVista/Win2K8/Win7).
Here are the commands for netsh:
1) Get the appid and certhash for the existing entry of 44300 (I
assume, you are going to use the same certificate which WebMatrix
installs by default. If you want to change the certificate as well,
get the certificate hash of the certificate from the certificate
store): netsh http show sslcert. In the output search for entry for
port 44300 and copy certhash and appID.
2) Delete the entry for 44300: netsh http delete sslcert ipport=0.0.0.0:44300
3) Add a new entry for port 443 with certhash and appID copied in step
1. netsh http add sslcert ipport=0.0.0.0:443 certhash=<certhash> appid=<appid>
After configuring the entry in http.sys, you need to restart http
service for the changes to take effect.
net stop http
net start http
As noted by others, there are several nice ways of getting your SSL certs.
netsh http show sslcert > output.txt
or (my preferred method):
netsh http show sslcert | clip
Since I have spent much time on this topic , I would like to share my finding. I am reposting segment from my other post minus the code. Some background and explanation:
==========================================
After researching aroud, I was able to solve this issue with IIS Express and an override of the Controller class's OnAuthorization method (Ref#1). I have also gone with the route recommended by Hanselman (Ref#2). However, I was not complete satisfied with these two solutions due to two reasons:
Ref#1's OnAuthorization only works at the action level, not at the controller class level
Ref#2 requires a lot of setup (Win7 SDK for makecert), netsh commands, and, in order to use port 80 and port 443, I need to launch VS2010 as administrator, which I frown upon.
So, I came up with this solution that is quite simplistic with the following conditions:
I want to be able to use the RequireHttps attribute at Controller class or action level
I want MVC to use HTTPS when the RequireHttps attribute is present, and use HTTP if it is absent
I do not want to have to run Visual Studio as administrator
I want to be able to use any HTTP and HTTPS ports that are assigned by IIS Express
I can reuse the self-signed SSL cert of IIS Express, and I do not care if I see the invalid SSL Prompt
=========================================
You can find my solution/code here ==> ASP.NET MVC RequireHttps in Production Only
The port 44300 is sequential: 00 mean that its the first application you have configured as SSL enabled; 01 will be the second one and so on.
Since I also require my website to only work in HTTPS by adding the [RequireHttps] global attribute, I had some trouble debugging. When launched, it was automatically redirecting to https://localhost/
To fix this problem when debugging a web site, I simply create a new RequireHttpsAttribute that specify the port
#if DEBUG
public class RequireHttpsAttribute : System.Web.Mvc.RequireHttpsAttribute
{
protected override void HandleNonHttpsRequest(System.Web.Mvc.AuthorizationContext filterContext)
{
base.HandleNonHttpsRequest(filterContext);
var result = (RedirectResult)filterContext.Result;
var uri = new UriBuilder(result.Url);
uri.Port = 44301;
filterContext.Result = new RedirectResult(uri.ToString());
}
}
#endif
Use this class when debugging only. When deployed to IIS7, you should use Url rewriting to redirect to HTTPS.
Dan answer is right but if you still have problems with configuring IIS Express to serve your website with http and https on standard ports here is nice tutorial that that guide you step by step:
http://www.lansweeper.com/kb/54/How-to-configure-SSL-in-IIS-Express.html
In my case I accidentally deleted IIS Express certificate. I think it is generated the first time you use SSL in Visual Studio (F4 on selected project to get properties window and checking 'SSS Enabled' checkbox). This tutorial guided me how to create certificate and fix it.
Create class
public class RequireSSLAttribute: RequireHttpsAttribute
{
protected override void HandleNonHttpsRequest(AuthorizationContext filterContext)
{
base.HandleNonHttpsRequest(filterContext);
if (filterContext.HttpContext.Request.Url.Host.ToLower().Equals("localhost"))
{
// redirect to HTTPS version of page
string localhostSSLPort = System.Configuration.ConfigurationManager.AppSettings["localhostSSLPort"];
string url = "https://" + filterContext.HttpContext.Request.Url.Host + ":" + localhostSSLPort + filterContext.HttpContext.Request.RawUrl;
filterContext.Result = new RedirectResult(url);
}
}
}
And inside your web config add something like this
<appSettings>
<add key="localhostSSLPort" value="44300"/>
</appSettings>
And then you use it like
[RequireSSL]
public class AdminController : Controller
{
...
}

Resources