I have been trying to create a webservice that needs to allow the client to send thru 3 parameters being Username, Password and XML_In all 3 of type string. This then sends the variables to a Stored procedure which processes the data and returns an XML string which is then returned to the client.
The Stored procedure works 100% but I'm getting an error with the XML being sent thru as a string. From reading up most gave the suggestion of adding <httpRuntime requestValidationMode="2.0"/> and <pages validateRequest="false"> to my web.config which works but that would then apply to my entire site which I dont want at all.
The other suggestion was to place it in the #Page part but that does not apply to a web service as it has no user defined layout. Please see my code below and help. I'm still quite a newbie to .Net thus the reason I'm doing 90% of it in SQL.
The error That gets returned is :
System.Web.HttpRequestValidationException: A potentially dangerous Request.Form value was detected from the client (XML_In="<senddata><settings ...").
at System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection)
at System.Web.HttpRequest.ValidateHttpValueCollection(HttpValueCollection collection, RequestValidationSource requestCollection)
at System.Web.HttpRequest.get_Form()
at System.Web.Services.Protocols.HtmlFormParameterReader.Read(HttpRequest request)
at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
here's the code:
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
Imports System.Xml
Imports JumpStart.Framework.Database
' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://mydomainname.co.za/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class LeadProcessor
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function Lead_Processing(ByVal UserName As String, ByVal PassWord As String, ByVal XML_In As String) As XmlDocument
Dim poDSL As New DSL
Dim Result As String
Dim XML_Out = New XmlDocument()
Result = poDSL.ExecuteProcedure_ExecuteScalar("DECLARE #Result XML " & _
"EXEC [dbo].[APP_InsertLeadFromXML] " & _
"#Username = N'" & UserName & "', " & _
"#Password = N'" & PassWord & "', " & _
"#ParmListXML = '" & XML_In.ToString & "', " & _
"#XMLResult = #Result OUTPUT " & _
"SELECT #Result")
XML_Out.LoadXml(Result)
Return XML_Out
End Function
I agree with CodeCaster comment (new projects - WCF or WebApi).
But if you can't change it now, consider use a XMLDocument as parameter, or an XElemento, or directly, do a Base64 transform of the text, in order to avoid that errors.
Code for your service' client:
your_proxy.Lead_Processing(sUserName, sPassWord, Convert.ToBase64String(Encoding.UTF8.GetBytes(sXML))
Then, in your service, do this
<WebMethod()> _
Public Function Lead_Processing(ByVal UserName As String, ByVal PassWord As String, ByVal XML_In As String) As XmlDocument
Dim oData As Byte() = Convert.FromBase64String(XML_In)
Dim sDecodedXML As String = System.Text.Encoding.UTF8.GetString(oData)
Dim poDSL As New DSL
Dim Result As String
Dim XML_Out = New XmlDocument()
Result = poDSL.ExecuteProcedure_ExecuteScalar("DECLARE #Result XML " & _
"EXEC [dbo].[APP_InsertLeadFromXML] " & _
"#Username = N'" & UserName & "', " & _
"#Password = N'" & PassWord & "', " & _
"#ParmListXML = '" & sDecodedXML & "', " & _
"#XMLResult = #Result OUTPUT " & _
"SELECT #Result")
XML_Out.LoadXml(Result)
Return XML_Out
End Function
Hope it helps
Edit:
Your service with base64.
We're telling that Asmx it's almost a legacy tech. New projects may use WCF tech (I can't teach you WCF in a few lines).
You can put that code into your asmx service. You can use that code in the way I edited my answer.
Related
It sends to one ok. But not to 2 or more. I've tried separating addresses by , and ; and space in the to_addr string, but failed.
What format does class EmailAddress expect for multiple addresses?
public async sub send_message( msg_subject, msg_body, from_addr_text, to_addr_text, optional commands = "")
dim apiKey = Environment.GetEnvironmentVariable("SENDGRID_API_KEY")
dim client as new SendGridClient( apiKey, , , "v3", )
dim from = new EmailAddress( from_addr_text, "INSTRUMENT")
dim subject = msg_subject
if subject = ""
subject = " " ' won't send if empty
End If
dim to_addr = new EmailAddress( to_addr_text, "INSTRUMENT")
dim plainTextContent = msg_body
dim htmlContent = "<strong>" & msg_body & "</strong>"
dim msg = MailHelper.CreateSingleEmail(from, to_addr, subject, plainTextContent, htmlContent)
dim response = await client.SendEmailAsync(msg)
if instr( commands, "SKIP POPUPS") ' TEST TEXT MSG !!!
exit sub
End If
popup_information( "MESSAGE SENDING", "Sent..." & vbcrlf & vbcrlf & "SUBJECT: " & vbcrlf & subject & vbcrlf & vbcrlf & "BODY: " & vbcrlf & msg_body )
end sub
Not sure which SDK version are you using , but if you follow the Sendgrid V3 api SDK for C# , you should find a method like below in the MailHelper class
public static SendGridMessage CreateSingleEmailToMultipleRecipients(EmailAddress from, List<EmailAddress> tos, string subject,string plainTextContent,string htmlContent)
which accepts a List<EmailAddress> to send email to multiple recipients. So instead of using the below line in your code
dim msg = MailHelper.CreateSingleEmail(from, to_addr, subject, plainTextContent, htmlContent)
you should use the below code
var to_addr = new List<EmailAddress>();
to_addr.Add(new EmailAddress( to_addr_text, "INSTRUMENT"));
to_addr.Add(new EmailAddress( "secondperson#test.com", "secondperson")); // you can add multiple email in this list
and then you can use to_addr in the code below
dim msg = MailHelper.CreateSingleEmailToMultipleRecipients(from, to_addr, subject, plainTextContent, htmlContent)
Pardon me for the example in C# but the same should be applicable for your VB.NET code
The stack overflow answer here shows how to implement SendGrid using dependency injection into a Net 6 Web API application using controllers.
The scenario of sending an email to multiple recipients is covered in the referenced example code here: https://github.com/Davidmendoza1987/dotnet-sendgrid-examples
I have just migrated a website from Server 2003 to Server 2012, and MS Indexing service is not available.
In doing some research, I found that MS Search Service is the 'replacement,' and, as such, I installed it on Server 2012. Beyond this, I haven't found what ASP-Classic (VB) code would be necessary to enable the new Search Service to catalog my documents, as Indexing Service did.
Does MS Search Service have the capability and flexibility to catalog and search documents, and return results in the same way that MS Indexing Service did?
Below is an example of the code that currently calls the MS Indexing Service (on the Windows 2003 server):
<%
Dim strQuery ' The text of our query
Dim objQuery ' The index server query object
Dim rstResults ' A recordset of results returned from I.S.
Dim objField ' Field object for loop
Dim objUtility
' Retreive the query from the querystring
strQuery = Request.QueryString("CiRestriction")
if strQuery <> "" then
if Request.QueryString("ExactPhrase") = "Yes" then
strQuery = """" & strQuery & """"
end if
end if
' If the query isn't blank them proceed
If strQuery <> "" Then
' Create our index server object
Set objQuery = Server.CreateObject("IXSSO.Query")
' Set its properties
objQuery.Catalog = "Test_Docs" ' Catalog to query
objQuery.MaxRecords = 75 ' Max # of records to return
objQuery.SortBy = "Rank[d], size"
objQuery.Columns = "Characterization, DocTitle, Directory, Filename, Path, Rank, Size, Vpath, Write"
' Build our Query: Hide admin page and FPSE pages
'strQuery = "(" & strQuery & ")" _
' & " AND NOT #filename = *admin*" _
' & " AND NOT #path *\_vti_*"
' Uncomment to only look for files modified last 5 days
'strQuery = strQuery & " AND #write > -5d"
' To set more complex scopes we use the utility object.
' You can call AddScopeToQuery as many times as you need to.
' Shallow includes just files in that folder. Deep includes
' subfolders as well.
'
Set objUtility = Server.CreateObject("IXSSO.Util")
objUtility.AddScopeToQuery objQuery, "d:\test_shares\test_docs", "deep"
objQuery.Query = strQuery ' Query text
Set rstResults = objQuery.CreateRecordset("nonsequential") ' Get a recordset of our results back from Index Server
' Check for no records
If rstResults.EOF Then
Response.Write "Sorry. No results found."
Else
' Print out # of results
Response.Write "<p><strong>"
Response.Write rstResults.RecordCount
Response.Write "</strong> results found:</p>"
' Loop through results
Do While Not rstResults.EOF
' Loop through Fields
' Pretty is as pretty does... good enough:
%>
<%KSize=formatnumber(rstResults.Fields("size"))
KSize= round(KSize/1024,0)%>
<p>
<%'test below using PoorMansIsNull function%>
<% If PoorMansIsNull(rstResults.Fields("DocTitle")) Or rstResults.Fields("DocTitle")="" Then %>
<%= PathToVpath(rstResults.Fields("filename")) %>
<% Else %>
<font size="3"><%= rstResults.Fields("DocTitle") %></font>
<% End If %>
<br><%= rstResults.Fields("Characterization") %><br>
<font color="#009900"><%= PathToVpath(rstResults.Fields("path")) %> - <%= KSize %>k<br /></font>
</p>
<%
' Move to next result
rstResults.MoveNext
Loop
rstResults.MoveFirst
Response.Write "<pre>"
'Response.Write rstResults.GetString()
Response.Write "</pre>"
End If
' Kill our recordset object
Set rstResults = Nothing
Set objUtility = Nothing
Set objQuery = Nothing
End If
%>
</body>
</html>
<%
Function PathToVpath(strPath)
Const strWebRoot = "d:\test_shares\test_docs\"
Dim strTemp
strTemp = strPath
strTemp = Replace(strTemp, strWebRoot, "\")
strTemp = Replace(strTemp, "\", "/")
PathToVpath = strTemp
End Function
%>
And, the results would be listed, per document (the name of the document, with excerpt from document text, along with title, size), as illustrated below:
Thanks for any leads and/or alternatives.
This example is in fact incorrect. It does not work. The following code:
objRecordSet.Open "SELECT Top 20 " & _
"System.ItemPathDisplay " & _
",System.ItemName " & _
",System.Size " & _
"FROM SYSTEMINDEX", objConnection & _
"WHERE SCOPE='file:E:\MANIF\DAAP\AC'"
Should really use the connection object at the end of the query. Spent a few hours wondering why the WHERE clause was not working.
objRecordSet.Open "SELECT Top 20 " & _
"System.ItemPathDisplay " & _
",System.ItemName " & _
",System.Size " & _
"FROM SYSTEMINDEX " & _
"WHERE SCOPE='file:E:\MANIF\DAAP\AC'", objConnection
This should help all who are having the same difficulty.
I'm facing the same problem. I've found a MS guide about this issue: Querying the Index with Windows Search SQL Syntax.
I've tested this ASP (Classic) code and ran ok:
<html>
<body>
Results<br>
<ol>
<%
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")
objConnection.Open "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
'change directory on scope clause
objRecordSet.Open "SELECT Top 20 " & _
"System.ItemPathDisplay " & _
",System.ItemName " & _
",System.Size " & _
"FROM SYSTEMINDEX" & _
" WHERE SCOPE='file:E:\MANIF\DAAP\AC'", objConnection
objRecordSet.MoveFirst
Do Until (objRecordSet.EOF)
%>
<li>
<strong>Path Display:</strong><%=objRecordSet("System.ItemPathDisplay")%><br>
<strong>Name:</strong><%=objRecordSet("System.ItemName")%><br>
<strong>Size:</strong><%=objRecordSet("System.Size")%><br>
<hr>
</li>
<%
objRecordSet.MoveNext
Loop
objRecordSet.Close
Set objRecordSet = Nothing
objConnection.Close
Set objConnection = Nothing
%>
</ol>
</body>
</html>
Other alternatives:
Try to register asp dll in windows server. For I could see, nobody related success on this approch. See this post;
Create a VM a previous windows version to support your asp. See this MS article.
Hope it could help you.
When calling a Sub to populate a System.Collections.Generic.Dictionary with keys and values from a DictionaryEntry(), upon examining the Dictionary in Debug mode every property has a red circle with an X and contains the text "Unable to evaluate expression." It appears to be working, it will even complain if I try to add two entries with the same Key/Value pair. No keys or values are present either, even though my test string (valuesString) is populated.
I am calling the Sub from the ItemInserted event of a FormView (.Net Framework 4, Visual Studio 2013 Webforms Application)
Protected Sub PopulateDictionary(myValues As DictionaryEntry())
Dim de As DictionaryEntry
Dim valuesString As String = String.Empty
Dim myDictionary As New Dictionary(Of String, String)
For Each de In myValues
'This works - the string is populated with key/value pairs
valuesString &= "Key=" & de.Key.ToString() & ", " & _
"Value=" & de.Value.ToString() & "<br/>"
'This doesn't - just get the red circle with an X
myDictionary.Add(de.Key.ToString(), de.Value.ToString())
Next
End Sub
What is going on here? I have restarted Visual Studio with no luck.
odd that this works with the "<br/>". it looks like it's missing the closing quote. (and maybe ToString() is not needed?)
valuesString &= "Key=" & de.Key.ToString() & ", " & _
"Value=" & de.Value.ToString() & "<br/>"
it looks like this:
myDictionary.Add(de.Key.ToString(), de.Value.ToString())
just needs to be:
myDictionary.Add(valuesString)
or (not sure...):
myDictionary.Add(DictionaryEntry())
I have set up a web service with an .asmx file and its web methods are being called via Ajax (all using asp.net scriptmanager etc) on the clientside.
When I call the webservice and look at the value of the return value in the callback, it is never in the 'SOAP' format, ie in xml. instead the value is returned in its raw form.
So for instance if I return a string from the webservice, the result passed to my successful callback is the string, not encoded or surrounded by XML tags.
How can I change this so I can see it in the SOAP format?
Are you calling from jquery? possible return in Json format. My guess without seeing your code.
It sounds like you are being returned the result of the web service function and letting .NET handle all of the underlying SOAP details. What you need to do if you want to see the HTTP SOAP response in your code, is instead of referencing the Web Service and invoking the function, issue an HTTP SOAP request. In VB.NET:
Dim _soapRequest As String = "<?xml version=""1.0"" encoding=""utf-8""?>" & _
"<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">" & _
"<soap:Body>" & _
"<CelsiusToFahrenheit xmlns=""http://tempuri.org/"">" & _
"<Celsius>" & 100 & "</Celsius>" & _
"</CelsiusToFahrenheit>" & _
"</soap:Body>" & _
"</soap:Envelope>"
Dim response As String = DoRequestResponse(_soapRequest, "http://localhost:88/Service1.asmx")
and the DoRequestResponse Function looks like this
Public Function DoRequestResponse(ByVal _p_RequestString As String, ByVal _p_RequestURL As String) As String
Dim _httpWebRequest As HttpWebRequest
Dim _httpWebResponse As HttpWebResponse
Dim _streamReq As Stream
Dim _streamResp As Stream
Dim _streamReader As StreamReader
Dim _responseString As String
Dim _bytesToWrite() As Byte
Try
_httpWebRequest = CType(WebRequest.Create(_p_RequestURL), HttpWebRequest)
_httpWebRequest.Method = "POST"
_httpWebRequest.ContentType = "text/xml"
_httpWebRequest.Timeout = 30000
Dim EncodingType As System.Text.Encoding = System.Text.Encoding.UTF8
_bytesToWrite = EncodingType.GetBytes(_p_RequestString)
_streamReq = _httpWebRequest.GetRequestStream()
_streamReq.Write(_bytesToWrite, 0, _bytesToWrite.Length)
_streamReq.Close()
_httpWebResponse = DirectCast(_httpWebRequest.GetResponse(), HttpWebResponse)
_streamResp = _httpWebResponse.GetResponseStream()
_streamReader = New StreamReader(_streamResp)
_responseString = _streamReader.ReadToEnd()
_streamReader.Close()
_httpWebResponse.Close()
Catch ex As Exception
Dim _ex As WebException = ex
Console.Write(_ex.Status)
Console.Write(DirectCast(_ex.Response, HttpWebResponse).StatusCode)
Throw New Exception("DoRequestResponse Error :" & vbCrLf & ex.Message)
End Try
Return _responseString
End Function
You can do something like this in your code-behind of the asp.net page, and call it from AJAX, via postback, etc., which will then post to your .asmx web service and return the SOAP response.
I want to add javascript to asp.net page dynamically.
can anybody point me towards working example?
i know it can be done by using Page.ClientScript.RegisterClientScriptBlock
but i have no idea to use it.
MSDN
This is the MSDN link
if (!this.Page.ClientScript.IsClientScriptBlockRegistered(typeof(Page), "Utils"))
{
string UtilsScript = ResourceHelper.GetEmbeddedAssemblyResource("Utils.js");
this.Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Utils", UtilsScript, true);
}
I added the above example to help,
Here we test if the script is already registered (using the type an dkey we register against) get the script as a string from an embedded resource, then register (the last parameter of true tells the code to render Script tags).
hope this helps
P
An example to move the value of a Drop Down List to text field. The ID parameters are the Object.ClientID properties for the drop down list and text box.
Private Sub RegisterClientDropDownToTextBox(ByVal functionName As String, ByVal dropDownId As String, ByVal textBoxId As String)
Dim javascriptFunction As String = "function " & functionName & "() {" & _
"document.getElementById('" & textBoxId & "').value = document.getElementById('" & dropDownId & "').value;" & _
"}"
Dim javascriptWireEvent As String = "document.getElementById('" & dropDownId & "').onclick = " & functionName & ";"
Me.ClientScript.RegisterClientScriptBlock(Me.GetType(), functionName & "_ScriptBlock", javascriptFunction, True)
Me.ClientScript.RegisterStartupScript(Me.GetType(), functionName & "_Startup", javascriptWireEvent, True)
End Sub