Posting form to a web service

Mondeo

Centurion
Joined
Nov 10, 2006
Messages
128
Location
Sunny Lancashire
I have a basic HTML page (the host doesn't support ASP or .NET)

I have a simple mail form

<form name="form1" method="post" action=http://remotesite/sendmail.asmx>
<input type="text" name="name" width="180">
<input type="text" name="phone" width="180">
<input type="text" name="email" width="180">
<textarea name="comments" rows="3"></textarea>
<input type="submit" name="Submit" value="Submit">
</form>

I want to use the sendmail service to send mail on behalf of this page, can it be done?

How does sendmail.asmx access the form values of this page? It also needs either the URL of the first page or its IP address to restrict usage.

Thanks
 
Append method name to action URL

Since you are using POST, you need to append the method name to the URL of the webservice in the action attribute. For example, if your method was called SendMail then your form element would be:

Code:
<form name="form1" method="post" action="http://remotesite/sendmail.asmx/SendMail">

The webservice would receive a request like:

Code:
POST /sendmail.asmx/SendMail HTTP/1.1
Host: [url]remotesite[/url]
Content-Type: application/x-www-form-urlencoded
Content-Length: length

name=somevalue&phone=somevalue&email=somevalue&comments=somevalue

However, you do not need to worry about this as ASP.Net will handle the request and automatically invoke the SendMail method on the webservice class.

Good luck :cool:
 
Okay cheers, so in my method if I have this for example

Code:
<WebMethod()> _
Public Sub SendMail(byval suject as string, byval message as string)

Will subject and message be populated with the form values of the same name? Is that how it works?

Thanks
 
Looking good

Yes, that's how it works. However, the number of parameters passed in the form must match the number of parameters the method takes, so for the example form you would need SendMail to take 4 parameters - name, phone, email and comments.

As for capturing the IP address etc, the Request object is still available in a webservice and should allow you to perform any filtering you require. You can also access session variables if you place EnableSession:=True in the WebMethod attribute constructor.

:)
 
Try the test form

Check the action attribute of the HTML form corresponds exactly to the name of your webservice followed by / and the name of the method. The method name must exactly match the name of the method in the webservice code - the request should only end with /smtpsend if the method is named smtpsend (or you have assigned it a different message name).

You can test that your webservice is working by navigating your browser to it. If the webservice is running from the local machine you will also be able to test the webservice via a HTML form. By looking at the HTML source of the page you can see how the form should be constructed.

If you're unable to fix it, you will have to post the relevant HTML code along with the name of the webservice and and method signature.

Good luck :cool:
 
The form i'm developing has loads of fields, however i've reproduced the error with a simple form.

This is the HTML

Code:
<form name="form1" method="post" action="http://www.underagrandcars.com/testingarea/smtpservice.asmx/test">
<input type="text" name="subject" width="180">
<input type="submit" name="Submit" value="Submit">
</form>

This is the web method

Code:
<WebMethod()> _
    Public Function test(ByVal subject As String) As String
        Return subject
    End Function

If I put http://www.underagrandcars.com/testingarea/smtpservice.asmx/test directly into a browser I get the same error, however http://www.underagrandcars.com/testingarea/smtpservice.asmx opens up the correct page and shows "test" as a method.
 
POST is disabled!

It would appear that by default, using POST only works from the local machine, and that only SOAP is enabled for remote requests. However, I found a Microsoft Help and Support page on the issue which explains how to enable POST for remote requests.



Microsoft Help and Support said:
HTTP GET and HTTP POST may be enabled by editing the Web.config file for the vroot where the Web service resides. The following configuration enables both HTTP GET and HTTP POST:

Code:
<configuration>
    <system.web>
    <webServices>
        <protocols>
            <add name="HttpGet"/>
            <add name="HttpPost"/>
        </protocols>
    </webServices>
    </system.web>
</configuration>


Alternatively, you can enable these protocols for all Web services on the computer by editing the <protocols> section in Machine.config. The following example enables HTTP GET, HTTP POST, and also SOAP and HTTP POST from localhost:

Code:
<protocols>
	<add name="HttpSoap"/>
	<add name="HttpPost"/>
	<add name="HttpGet"/> 
	<add name="HttpPostLocalhost"/>
      <!-- Documentation enables the documentation/test pages -->
	<add name="Documentation"/>
</protocols>



Since I had only ever used POST from the test form, and SOAP in my actual application, I assumed POST would still work. Good catch.

Good luck :cool:
 
Thanks for that. Its fixed it.

Apart from....I now get the wonderful HTTP 500 Internal Server Error. Is there any way to see the actual exception? I have the <customErrors mode="Off"/>

I have a couple of ideas, in my method constructor all the incoming values are As String. However on the form some are Checkboxes, do these need to be declared boolean?
 
Maybe you should use aspx

Ah checkboxes... If they are checked, the value "on" is typically posted to the server. However, if they are unchecked, no value is posted to the server at all. This would cause an exception with a webservice since, in its eyes, a parameter is missing.

Perhaps a webservice is the wrong way to go here. Maybe you're better off using an aspx page. In the page's Load event you can then deal with any form variables however you want, and you are more able to display a success/failure page.
 
Thanks for all your help.

Its working fine now, i've set those parameters to boolean.

Believe me I would love to use ASPX. I do a lot of work for a designer, he designs the sites then I code them.

But, a lot of them like this one are just plain static HTML, the hosts he uses dont support .NET and he doesn't want to move them just for the sake of it.

I get a lot of requests like this just to make the contact form work, I usually end up messing about on the hosts site seeing what preinstalled mail scripts they offer etc.

So today I though if I create a web service like this, I can use it in the future for all these similar jobs.

Thanks again.

Ben
 
Checkboxes

As I said in my previous post, the exception is caused by the fact that if a checkbox is unchecked, NO variable is sent to the server. This means the webserver sees fewer parameters, and is unable to find a webservice method with a matching signature.

My best suggestion right now would be to try declaring each of the (boolean) checkbox parameters as Optional, with a default value False. Theoretically this should work, but I don't know if webservice methods can take optional parameters. If not, then you could look at using Javascript to populate a form of hidden fields and then submit that to the webservice.

However, I am still a little confused as to why you are able to use a webservice, but not an aspx page. You are obviously hosting the webservice on an ASP.Net server, so you should be able to use an aspx page. It would still be possible to make it 'generic' for all the possible jobs you might need it for.

Anyway, good luck :)
 
It says optional parameters are not allowed.

I'm curious about your sussestion of using an aspx page instead of a service. Would this just be a case of posting to the page from within the form.

Then in the page get the values off the querystring with request.querystring.

If this could be done it would solve my problem, I could just go back to the original page with response.write and the referrer.

What do you think? Is this what you were meaning?
 
aspx approach

Yes, that's the sort of thing I meant. Basically, you create a blank page - it doesn't need to contain any HTML as you'll be redirecting the request anyway. Then use the Page_Load event, or override the OnLoad method. For example, lets say you have a page SendMail.aspx:


Visual Basic:
Partial Class SendMail
    Inherits System.Web.UI.Page

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        Dim subject As String
        Dim redirecturl As String

        subject = Request.Form("subject")
        redirecturl = Request.Form("redirecturl")

        'etc.
        'Continue to get variables from Request.Form then use to process request

        'Redirect the request
        Response.Redirect(redirecturl)

    End Sub

End Class

In this example, I've provided a form variable redirecturl which tells the page where it should redirect the user to (as referer can be unreliable or undesirable).

Good luck :cool:
 
Back
Top