sirbounty
asked on
VB.net - uploading a file to a web site
Based on the process outlined here, http://www.codeproject.com/Articles/28917/Setting-a-file-to-upload-inside-the-WebBrowser-com, I'm looking for help incorporating this into my vb.net project.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
FormToMultipartPostData.cs :
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace FormToMultipartPostData
{
/**
*
* This is a helper class to build postData header an body with the values from
* the given HTML form. The purpose of this class is to attach files to
* the <INPUT TYPE="FILE"> fields.
*
* License: Code Project Open License (CPOL)
* (c) Kirill Hryapin, 2008
* (c) Steven Cheng (Microsoft), 2005 (?)
*
* See usage example in Form1.cs included with this distribution.
*
*/
public class FormToMultipartPostData
{
private struct ValuePair // KeyValuePair<string, string> sounds too verbose for me
{
public string name;
public string value;
public ValuePair(string name, string value)
{
this.name = name;
this.value = value;
}
}
public struct RequestParameters
{
public byte[] data;
public string headers;
}
private List<ValuePair> values = new List<ValuePair>();
private List<ValuePair> files = new List<ValuePair>();
private Dictionary<string, string> overloadedFiles = new Dictionary<string,string>();
private HtmlElement form;
private WebBrowser webbrowser;
/**
* In most circumstances, this constructor is better (allows to use Submit() method)
*/
public FormToMultipartPostData(WebBrowser b, HtmlElement f)
{
form = f; webbrowser = b;
GetValuesFromForm(f);
}
/**
* Use this constructor if you don't want to use Submit() method
*/
public FormToMultipartPostData(HtmlElement f)
{
GetValuesFromForm(f);
}
/**
* Submit the form
*/
public void Submit()
{
Uri url = new Uri(webbrowser.Url, form.GetAttribute("action"));
RequestParameters req = GetEncodedPostData();
webbrowser.Navigate(url, form.GetAttribute("target"), req.data, req.headers);
}
/**
* Load values from form
*/
private void GetValuesFromForm(HtmlElement form)
{
// Get values from the form
foreach (HtmlElement child in form.All)
{
switch (child.TagName)
{
case "INPUT":
switch (child.GetAttribute("type").ToUpper())
{
case "FILE":
AddFile(child.Name, child.GetAttribute("value"));
break;
case "CHECKBOX":
case "RADIO":
if (child.GetAttribute("checked") == "True")
{
AddValue(child.Name, child.GetAttribute("value"));
}
break;
case "BUTTON":
case "IMAGE":
case "RESET":
break; // Ignore those?
default:
AddValue(child.Name, child.GetAttribute("value"));
break;
}
break;
case "TEXTAREA":
case "SELECT": // it's legal in IE to use .value with select (at least in IE versions 3 to 7)
AddValue(child.Name, child.GetAttribute("value"));
break;
} // of "switch tagName"
} // of "foreach form child"
}
private void AddValue(string name, string value)
{
if (name == "") return; // e.g. unnamed buttons
values.Add(new ValuePair(name, value));
}
private void AddFile(string name, string value)
{
if (name == "") return;
files.Add(new ValuePair(name, value));
}
/**
* Set file field value [the reason why this class exist]
*/
public void SetFile(string fieldName, string filePath)
{
this.overloadedFiles.Add(fieldName, filePath);
}
/**
* One may need it to know whether there's specific file input
* For example, to perform some actions (think format conversion) before uploading
*/
public bool HasFileField(string fieldName)
{
foreach (ValuePair v in files) {
if (v.name == fieldName) { return true; }
}
return false;
}
/**
* Encode parameters
* Based on the code by Steven Cheng, http://bytes.com/forum/thread268661.html
*/
public RequestParameters GetEncodedPostData()
{
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
Stream memStream = new System.IO.MemoryStream();
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
foreach (ValuePair v in values)
{
string formitem = string.Format(formdataTemplate, v.name, v.value);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n";
foreach (ValuePair v in files)
{
string filePath;
if (overloadedFiles.ContainsKey(v.name))
{
filePath = overloadedFiles[v.name];
}
else
{
if (v.value.Length == 0) { continue; } // no file
filePath = v.value;
}
try // file can be absent or not readable
{
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
string header = string.Format(headerTemplate, v.name, filePath);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
fileStream.Close();
}
catch (Exception x) // no file?..
{
MessageBox.Show(x.Message, "Cannot upload the file", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
RequestParameters result = new RequestParameters();
memStream.Position = 0;
result.data = new byte[memStream.Length];
memStream.Read(result.data, 0, result.data.Length);
memStream.Close();
result.headers = "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n" +
"Content-Length: " + result.data.Length + "\r\n" +
"\r\n";
return result;
}
}
}
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
It's the class where I got stuck - even after converting it... :(
ASKER
Ah, but your version looks much better...
ASKER
Code fix recommended:
Dim postData As New FormToMultipartPostData (WebBrowser1, form)
to
Dim postData As New FormToMultipartPostData.Fo rmToMultip artPostDat a(WebBrows er1, form)
Dim postData As New FormToMultipartPostData (WebBrowser1, form)
to
Dim postData As New FormToMultipartPostData.Fo
ASKER
Yep, I use the same converter (I think you showed me that one a few years ago ;^)
To simplify your code, you should remove the Namespace FormToMultipartPostData... End Namespace lines. C# code had namespace, but it is not needed in VB.NET.
ASKER
Ok, as-is, it doesn't seem to be applying the file path. Fortunately with the appliance it will always be the same file.
(removing the namespace corrected the problem from above).
Since I don't quite understand the code, I'm not sure what I should be looking for. Could it be that the SetFile method is looking for "file" and it's actually labeled something different on the page? Or am I looking in the wrong direction?
(removing the namespace corrected the problem from above).
Since I don't quite understand the code, I'm not sure what I should be looking for. Could it be that the SetFile method is looking for "file" and it's actually labeled something different on the page? Or am I looking in the wrong direction?
ASKER
Not sure if this is needed/relevant, but this is what I find in the page source for that browse section:
<input type="file"
id="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload"
name="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload"
size="40"
class="formField" />
<tbody><tr><td>
<a href="#" onclick="return oamSubmitForm('zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm','zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:downloadMsgLockConfig');" id="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:downloadMsgLockConfig">Download current configuration</a>
</td><td>
What does the <form> element look like?
ASKER
What do you need from it?
Shows a Document: {System.Windows.Forms.Html Document}
DomElement: {[object]}
Several "Event" options - all objects as well...
Have an ID, which appears to be the same as above, an inner-html & text, as well as outer of the same.
Shows a Document: {System.Windows.Forms.Html
DomElement: {[object]}
Several "Event" options - all objects as well...
Have an ID, which appears to be the same as above, an inner-html & text, as well as outer of the same.
ASKER
Wait - at this point, I haven't sent a click to the Browse button - I'm thinking I should do that first and then proceed with the above?
I'll try that now...
I'll try that now...
ASKER
Nope - that just 'leaves' it at the "Choose File to Upload" dialogue box...
ASKER
I'm wondering if the problem is that the box where the file name ends up, is greyed out - and you cannot type in it - you must choose the browse button to upload.
Still possible with this code?
Still possible with this code?
There is a problem with the VB.NET conversion here:
form.AttachEventHandler("o nsubmit", delegate(object o, EventArgs arg)
{
FormToMultipartPostData postData = new FormToMultipartPostData(we bBrowser1, form);
postData.SetFile("file", @"C:\windows\win.ini");
postData.Submit();
});
The delegate function is known as an anonymous function. It attaches new code to the onsubmit event handler.
form.AttachEventHandler("o
{
FormToMultipartPostData postData = new FormToMultipartPostData(we
postData.SetFile("file", @"C:\windows\win.ini");
postData.Submit();
});
The delegate function is known as an anonymous function. It attaches new code to the onsubmit event handler.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
"What does the <form> element look like?"
I need to see the <form> element in the HTML, not from your code.
Like this:
<form action="demo_form.asp" method="get">
I need to see the <form> element in the HTML, not from your code.
Like this:
<form action="demo_form.asp" method="get">
ASKER
I don't see a form action...
Should
form.AttachEventHandler("o amSubmitFo rm", AddressOf OnSubmit) ? ( see prior post)
<form id="zdmSummaryDetailsSubview:relContentViewpc1:zdmTabsForm2" name="zdmSummaryDetailsSubview:relContentViewpc1:zdmTabsForm2" method="post" action="/console/services/zdm/index.jsf" enctype="application/x-www-form-urlencoded"><table border="0" cellpadding="0" cellspacing="0" width="100%" class="wizardButtonBox"><tbody><tr><td></td></tr></tbody></table><input type="hidden" name="zdmSummaryDetailsSubview:relContentViewpc1:zdmTabsForm2_SUBMIT" value="1" /><input type="hidden" name="javax.faces.ViewState" value="rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAN0AAFhcHQAFy9zZXJ2aWNlcy96ZG0vaW5kZXguanNw" /></form>
Should
form.AttachEventHandler("obensubmit", AddressOf OnSubmit)
form.AttachEventHandler("o
ASKER
Do I need to publicly declare 'form' for OnSubmit to use? Or pass it as an argument somehow?
ASKER
As-is, it's not hitting the onsubmit sub...
Here's my current documentcompleted sub:
Here's my current documentcompleted sub:
Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
If e.Url.AbsolutePath.ToLower.Contains("login") Then Exit Sub
If ServiceTabClicked Then
If ZDMConfigTabClicked Then
' Dim browseButton As mshtml.HTMLInputElement = helper.GetHtmlElementById(Of mshtml.HTMLInputElement)("zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload")
' browseButton.click()
Dim doc As HtmlDocument = WebBrowser1.Document
For i As Integer = 0 To doc.Forms.Count - 1
Form = doc.Forms(i)
If form.GetAttribute("enctype").ToLower() <> "multipart/form-data" Then Continue For
form.AttachEventHandler("onsubmit", AddressOf OnSubmit)
form.SetAttribute("hasBrowserHandler", "1")
Next
Else
Dim zdmCfgTab As mshtml.HTMLInputElement = helper.GetHtmlElementById(Of mshtml.HTMLInputElement)("zdmSummaryDetailsSubview:relContentViewpc1:configZDMTabbedPane.2") '"zdmSummaryDetailsSubview:relContentViewpc1:zdmTabsForm:bcServiceZDM")
'"zdmSummaryDetailsSubview:relContentViewpc1:configZDMTabbedPane.2"
zdmCfgTab.click()
ZDMConfigTabClicked = True
End If
Else
VSite.Path = "console/services/zdm/index.jsf"
WebBrowser1.Navigate(VSite.Uri.ToString)
ServiceTabClicked = True
End If
End Sub
ASKER
Don't know if this helps, but before the upload this is what I see for the 'file':
<input type="file" id="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload" name="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload" size="40" class="formField" />
After:<INPUT id=zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload
class=formField
value="\\SERVER\PATH\FILE.CSV"
size=40
type=file
name=zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload>
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ok, that makes it a little bit clearer for me, thanks.
But (a) does that eliminate the need for me to locate the browse button and 'click' it? and (b) I've tried it both ways and neither route seems to be doing anything.
But (a) does that eliminate the need for me to locate the browse button and 'click' it? and (b) I've tried it both ways and neither route seems to be doing anything.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Yes, there is a link to download the current config (it has never really worked when I tried it), but we just append to an existing external config file sitting on a share.
The way I'm interpretting this is that we've setup an event hanlder for when the page attempts to submit the file, but there doesn't seem to be a way to actually submit the file, or is that what clicking the browse button should trigger? Because that seems to move away from the scope of the page and generate a popup dialogue that's no longer associated with the web page. Should this event handler be able to manipulate that dialogue?
Could it be that the event handler is named incorrectly?
Is the "hasBrowserHandler" attribute still applicable (I'm not sure what the benefit is for that)?
I did try putting a breakpoint at OnSubmit, but it doesn't hit it. I also adjusted the code to set the handler before clicking the browse button:
I can attach the full page code if that would help. I'm afriad I just don't know enough to know what else to look for (but I'm still trying - and learning! :^)
The way I'm interpretting this is that we've setup an event hanlder for when the page attempts to submit the file, but there doesn't seem to be a way to actually submit the file, or is that what clicking the browse button should trigger? Because that seems to move away from the scope of the page and generate a popup dialogue that's no longer associated with the web page. Should this event handler be able to manipulate that dialogue?
Could it be that the event handler is named incorrectly?
Is the "hasBrowserHandler" attribute still applicable (I'm not sure what the benefit is for that)?
I did try putting a breakpoint at OnSubmit, but it doesn't hit it. I also adjusted the code to set the handler before clicking the browse button:
Dim browseButton As mshtml.HTMLInputElement = helper.GetHtmlElementById(Of mshtml.HTMLInputElement)("zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload")
Dim doc As HtmlDocument = WebBrowser1.Document
For i As Integer = 0 To doc.Forms.Count - 1
form = doc.Forms(i)
If form.GetAttribute("enctype").ToLower() <> "multipart/form-data" Then Continue For
form.AttachEventHandler("onsubmit", AddressOf OnSubmit)
form.SetAttribute("hasBrowserHandler", "1")
Next
browseButton.click()
End If
I can attach the full page code if that would help. I'm afriad I just don't know enough to know what else to look for (but I'm still trying - and learning! :^)
I just noticed something in the code that you posted:
This means if the enctype attribute is not "multipart/form-data", then skip.
The form enctype is here:
enctype="application/x-www -form-urle ncoded"
If form.GetAttribute("enctype").ToLower() <> "multipart/form-data" Then Continue For
This means if the enctype attribute is not "multipart/form-data", then skip.
The form enctype is here:
enctype="application/x-www
ASKER
I had hopes, but no, still nothing.
Looking at the source, the only enctype before the browse button is showing multipart/form-data. Is that not the relevant one?
<table width="920"><tbody><tr><td ><form id="zdmSummaryDetailsSubvi ew:relCont entViewpc1 :tabZDMSer vice:tabZD MServiceSe ttings:zdm DetailsFor m" name="zdmSummaryDetailsSub view:relCo ntentViewp c1:tabZDMS ervice:tab ZDMService Settings:z dmDetailsF orm" method="post" action="/console/services/ zdm/index. jsf"
enctype="multipart/form-da ta"><div class="leftPaddedSection"> <div class="form"><table border="0" cellspacing="2" width="100%"><tbody><tr><t d class="formLabelNoWrap">De fault Domain *</td><td class=""><input id="defaultDomain" name="defaultDomain" type="text" value="COMPANY.com" size="30" class="formField" /></td></tr><tr><td class="formLabelNoWrap">Me ssage Format</td><td class=""><select id="msgFormat" name="msgFormat" size="1" class="formField"> <option value="V2">Version 2</option> <option value="V3" selected="selected">Versio n 3</option></select></td></ tr><tr><td class="formLabelNoWrap"><n obr>Sessio n Timeout Period (minutes) *</nobr></td><td class="">
<input id="sessionTimeout" name="sessionTimeout" type="text" value="20" size="12" class="formField" /></td></tr><tr><td class="formLabelNoWrap">Id entity Timeout Policy</td><td class=""><select id="identityTimeoutPolicy" name="identityTimeoutPolic y" size="1" class="formField" onchange="submit()"> <option value="OFF">Disabled</opti on> <option value="NEVER">Enabled - Never Times Out</option> <option value="TIMEOUT" selected="selected">Enable d - With Timeout Period</option></select></ td></tr><t r><td class="formLabelNoWrap">Id entity Timeout Period</td><td class=""><input id="identityTimeout" name="identityTimeout" type="text" value="12" size="12" class="formField" /> <select id="identityTimeoutUnit" name="identityTimeoutUnit" size="1" class="formField"> <option value="HOUR" selected="selected">Hour(s )</option> <option value="DAY">Day(s)</option > <option value="WEEK">Week(s)</opti on></selec t></td></t r><tr><td class="formLabelNoWrap"><s pan class="formLabelTop">Messa ge Locking Configuration</span></td>
Looking at the source, the only enctype before the browse button is showing multipart/form-data. Is that not the relevant one?
<table width="920"><tbody><tr><td
enctype="multipart/form-da
<input id="sessionTimeout" name="sessionTimeout" type="text" value="20" size="12" class="formField" /></td></tr><tr><td class="formLabelNoWrap">Id
ASKER
Thinking I may be misunderstanding (again)...should I be focusing on the Save button and making sure that submit gets overridden with the file details? (I have a new question open for that one, since it's an anchor element and I've been unable to get the click event working for that)
So many details, so little time...
Please show me the HTML elements for the <input type="file> for the upload, and the associated <form> element.
Please show me the HTML elements for the <input type="file> for the upload, and the associated <form> element.
ASKER
I pulled this block which includes the options before (setting I don't change), the browse button and the save button/link:
<form id="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm" name="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm"
method="post"
action="/console/services/zdm/index.jsf"
enctype="multipart/form-data">
<div class="leftPaddedSection"><div class="form">
<table border="0" cellspacing="2" width="100%">
<tbody><tr><td class="formLabelNoWrap">Default Domain *</td><td class="">
<input id="defaultDomain" name="defaultDomain" type="text" value="companyname.com" size="30" class="formField" />
</td></tr><tr>
<td class="formLabelNoWrap">Message Format</td>
<td class="">
<select
id="msgFormat"
name="msgFormat"
size="1"
class="formField">
<option value="V2">Version 2</option>
<option value="V3" selected="selected">Version 3</option>
</select>
</td>
</tr>
<tr>
<td class="formLabelNoWrap"><nobr>Session Timeout Period (minutes) *</nobr></td>
<td class="">
<input
id="sessionTimeout"
name="sessionTimeout"
type="text"
value="20"
size="12"
class="formField" />
</td>
</tr>
<tr><td class="formLabelNoWrap">Identity Timeout Policy</td>
<td class="">
<select
id="identityTimeoutPolicy"
name="identityTimeoutPolicy"
size="1"
class="formField"
onchange="submit()">
<option value="OFF">Disabled</option>
<option value="NEVER">Enabled - Never Times Out</option>
<option value="TIMEOUT" selected="selected">Enabled - With Timeout Period</option>
</select>
</td></tr>
<tr><td class="formLabelNoWrap">Identity Timeout Period</td>
<td class="">
<input id="identityTimeout" name="identityTimeout" type="text" value="12" size="12" class="formField" />
<select id="identityTimeoutUnit" name="identityTimeoutUnit" size="1" class="formField">
<option value="HOUR" selected="selected">Hour(s)</option>
<option value="DAY">Day(s)</option>
<option value="WEEK">Week(s)</option></select></td></tr>
<tr>
<td class="formLabelNoWrap">
<span class="formLabelTop">Message Locking Configuration</span>
</td>
<td class="">
<br/>
<span class="formTip">Browse to select a CSV file, then click the Save button to upload it.</span>
<table border="0" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td>
<input type="file"
id="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload" name="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload"
size="40"
class="formField" />
</td>
<td></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr><td>
<a href="#" onclick="return oamSubmitForm('zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm','zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:downloadMsgLockConfig');" id="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:downloadMsgLockConfig">Download current configuration</a></td><td> </td><td><a href="#" onclick="var cf = function(){if (!confirm('Are you sure you want to delete all message locking filters?')) return false};var oamSF = function(){return oamSubmitForm('zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm','zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:clearMsgLockConfig');};return (cf()==false)? false : oamSF();" id="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:clearMsgLockConfig">Clear current configuration</a></td></tr></tbody></table></td></tr></tbody></table></div></div><br/><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td>
<div class="ButtonRowR">
<table class='ButtonWrapper'>
<tr>
<td>
<a href="#"
onclick="return oamSubmitForm ('zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm','zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:saveZDMSessionConfig');" id="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:saveZDMSessionConfig" class="ButtonLeft">
<div class='ButtonRight'>
<div class='ButtonMiddle'>Save</div>
</div>
</a>
</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
We need to focus here:
<div class="ButtonRowR">
<table class='ButtonWrapper'>
<tr>
<td>
<a href="#"
onclick="return oamSubmitForm ('zdmSummaryDetailsSubview :relConten tViewpc1:t abZDMServi ce:tabZDMS erviceSett ings:zdmDe tailsForm' ,'zdmSumma ryDetailsS ubview:rel ContentVie wpc1:tabZD MService:t abZDMServi ceSettings :zdmDetail sForm:save ZDMSession Config');" id="zdmSummaryDetailsSubvi ew:relCont entViewpc1 :tabZDMSer vice:tabZD MServiceSe ttings:zdm DetailsFor m:saveZDMS essionConf ig" class="ButtonLeft">
<div class='ButtonRight'>
<div class='ButtonMiddle'>Save< /div>
</div>
</a>
</td>
</tr>
</table>
</div>
Is that the relevant anchor that you can't get click() to work?
<div class="ButtonRowR">
<table class='ButtonWrapper'>
<tr>
<td>
<a href="#"
onclick="return oamSubmitForm ('zdmSummaryDetailsSubview
<div class='ButtonRight'>
<div class='ButtonMiddle'>Save<
</div>
</a>
</td>
</tr>
</table>
</div>
Is that the relevant anchor that you can't get click() to work?
ASKER
Yes, but I think it's because of the function that it's trying to execute.
Four parameters required: (formName, linkId, target, params)
Four parameters required: (formName, linkId, target, params)
ASKER
Changed this line (to onclick)
form.AttachEventHandler("o nclick", AddressOf OnSubmit)
and it hit the handler...although it still popped up a script error (yes/no prompt)
form.AttachEventHandler("o
and it hit the handler...although it still popped up a script error (yes/no prompt)
ASKER
Stepping through the code shows:
? child.Name
"zdmSummaryDetailsSubview: footerView pc1:footer Formpc1_SU BMIT"
? child.GetAttribute("value" )
"1"
? child.Name
"javax.faces.ViewState"
? child.GetAttribute("value" )
"rO0ABXVyABNbTGphdmEubGFuZ y5PYmplY3Q 7kN5YnxBzK WwCAAB4cAA AAAN0AAE1c HQAFx9zZXJ 2aWNlcy43Z G0vaW5kZXg uanNw"
(this from the Case Else - I don't really need to catch these)
It never hit the input, file case element.
Once it went through I fired off the remainder and it did add the attribute, but then bombed at
result.headers = (Convert.ToString("Content -Type: multipart/form-data; boundary=") & boundary) + vbCr & vbLf + "Content-Length: " + result.data.Length + vbCr & vbLf + vbCr & vbLf
with a conversion error.
I think we're getting closer?
? child.Name
"zdmSummaryDetailsSubview:
? child.GetAttribute("value"
"1"
? child.Name
"javax.faces.ViewState"
? child.GetAttribute("value"
"rO0ABXVyABNbTGphdmEubGFuZ
(this from the Case Else - I don't really need to catch these)
It never hit the input, file case element.
Once it went through I fired off the remainder and it did add the attribute, but then bombed at
result.headers = (Convert.ToString("Content
with a conversion error.
I think we're getting closer?
Try this:
result.headers = "Content-Type: multipart/form-data; boundary=" & boundary & vbCr & vbLf & "Content-Length: " & result.data.Length & vbCr & vbLf & vbCr & vbLf
ASKER
Well, it prevented the coversion error, but with the script error still there it doesn't seem to be submitting the file.
I did try changing the reference to the input file to set that attribute for "file" to the location of the file. Didn't seem to change anything there either.
I'll try turning the script error suppresion back on (left it off so I could get past the security alert, but now I've installed the cert)...
I did try changing the reference to the input file to set that attribute for "file" to the location of the file. Didn't seem to change anything there either.
I'll try turning the script error suppresion back on (left it off so I could get past the security alert, but now I've installed the cert)...
ASKER
It seems to loop through the doccompleted sub multiple times after I click the save button.
No script errors this time, but about the 3rd time it hits the completed sub, it doesn't find the browse button, so errors on the missing object. And the page now looks like it didn't completely load.
I let the sub finish out and tried a refresh, but it's still not uploading the file.
I know when it has new config data, because there's a section on the header that states an update to all nodes is needed...
No script errors this time, but about the 3rd time it hits the completed sub, it doesn't find the browse button, so errors on the missing object. And the page now looks like it didn't completely load.
I let the sub finish out and tried a refresh, but it's still not uploading the file.
I know when it has new config data, because there's a section on the header that states an update to all nodes is needed...
At this point I can't assume that this line was reached:
webbrowser.Navigate(url, form.GetAttribute("target"), req.data, req.headers)
And, we shouldn't assume that this line is reached:
postData.Submit()
Do you reach this line?
Private Sub AddFile(name As String, value As String)
If name = "" Then
Return
End If
files.Add(New ValuePair(name, value))
End Sub
Private Sub AddFile(name As String, value As String)
If name = "" Then
Return
End If
files.Add(New ValuePair(name, value))
End Sub
What is "result.data.Length" here?
result.headers = "Content-Type: multipart/form-data; boundary=" & boundary & vbCr & vbLf & "Content-Length: " & result.data.Length & vbCr & vbLf & vbCr & vbLf
result.headers = "Content-Type: multipart/form-data; boundary=" & boundary & vbCr & vbLf & "Content-Length: " & result.data.Length & vbCr & vbLf & vbCr & vbLf
ASKER
First two comments - yes, I hit breakpoints at both (though after the script error).
No to the AddFile sub - it never hits that case element.
result.data.length is 416 at the line you posted last, but for the webbrowser.navigate, the url appears correct, but the form attribute "target" is empty...
No to the AddFile sub - it never hits that case element.
result.data.length is 416 at the line you posted last, but for the webbrowser.navigate, the url appears correct, but the form attribute "target" is empty...
1) The "target" attribute is not specified, and that's OK, since you don't need it (target frame).
2) It should call AddFile here:
Select Case child.TagName
Case "INPUT"
Select Case child.GetAttribute("type") .ToUpper()
Case "FILE"
AddFile(child.Name, child.GetAttribute("value" ))
Exit Select
Case "CHECKBOX", "RADIO"
...
2) It should call AddFile here:
Select Case child.TagName
Case "INPUT"
Select Case child.GetAttribute("type")
Case "FILE"
AddFile(child.Name, child.GetAttribute("value"
Exit Select
Case "CHECKBOX", "RADIO"
...
ASKER
I'll step through it again and see what the tagname is - pretty sure it kept hitting the case else...
ASKER
First pass to GetValuesFromForm,
child.TagName = "A" so it skips, next it's "INPUT" but "type" attribute is 'hidden',
so it hits the case else and adds "hidden" with a value of '1'
Third time it's "INPUT" with 'hidden' and a value of a really long string of seemingly random characters.
It doesn't return after this.
child.TagName = "A" so it skips, next it's "INPUT" but "type" attribute is 'hidden',
so it hits the case else and adds "hidden" with a value of '1'
Third time it's "INPUT" with 'hidden' and a value of a really long string of seemingly random characters.
It doesn't return after this.
It needs to find the <input type="file"> element.
<input type="file" id="zdmSummaryDetailsSubvi ew:relCont entViewpc1 :tabZDMSer vice:tabZD MServiceSe ttings:zdm DetailsFor m:msglockf ileupload" name="zdmSummaryDetailsSub view:relCo ntentViewp c1:tabZDMS ervice:tab ZDMService Settings:z dmDetailsF orm:msgloc kfileuploa d"
size="40"
class="formField" />
</td>
<input type="file" id="zdmSummaryDetailsSubvi
size="40"
class="formField" />
</td>
ASKER
And for the GetEncodedPostData, the values (2 of them) are:
? values(0)
{Voltage_Test.FormToMultip artPostDat a.ValuePai r}
name: "zdmSummaryDetailsSubview: footerView pc1:footer Formpc1_SU BMIT"
value: "1"
? values(1)
{Voltage_Test.FormToMultip artPostDat a.ValuePai r}
name: "javax.faces.ViewState"
value: "rO0ABXVyABNbTGphdmEubGFuZ y5PYmplY3Q 7kM5YnxBzK WwCAAB4cAA AAAN0AAE1c HQAFy9zZXJ 2aWNlcy96Z G0vaW5kZXg uanNw"
? values(0)
{Voltage_Test.FormToMultip
name: "zdmSummaryDetailsSubview:
value: "1"
? values(1)
{Voltage_Test.FormToMultip
name: "javax.faces.ViewState"
value: "rO0ABXVyABNbTGphdmEubGFuZ
ASKER
I presume I need to leave this?
Changed this line (to onclick)It wasn't hitting the handler otherwise... Or is there some other event I should be looking for?
form.AttachEventHandler("onclick", AddressOf OnSubmit)
According to the sample project, you need to attach an event handler to the "onsubmit" event:
form.AttachEventHandler("o nsubmit", ...
When the event doesn't get raised, it is because there is no submit. That should happen on the <input type="file"> element, which we are having a problem finding.
form.AttachEventHandler("o
When the event doesn't get raised, it is because there is no submit. That should happen on the <input type="file"> element, which we are having a problem finding.
ASKER
I think this is why it's not making sense to me...
The only 'event' that I see in the source is when the save button is clicked. There is no action shown for the browse button. Are we assuming we can technically skip that procedure and just ensure that the file value gets populated correctly and then submit via the save button? Or should I focus on actually clicking the browse button and that somehow is inserting the file into the popup dialogue?
The only 'event' that I see in the source is when the save button is clicked. There is no action shown for the browse button. Are we assuming we can technically skip that procedure and just ensure that the file value gets populated correctly and then submit via the save button? Or should I focus on actually clicking the browse button and that somehow is inserting the file into the popup dialogue?
This is pretty complex, so let's review:
1) Attach an event handler to the "onsubmit" event.
2) The <Save> anchor, when clicked, raises the "submit" event.
3) Find an <input type="file"> HTML element.
4) When the "onsubmit" event is raised, handle it.
5) Let JavaScript know that the client-side event was handled by external handler:
form.SetAttribute("hasBrow serHandler ", "1")
6) The FormToMultipartPostData.Su bmit method uses a POST to get the file bytes, and upload to the server.
All these steps need to work correctly, or the upload will not occur.
1) Attach an event handler to the "onsubmit" event.
2) The <Save> anchor, when clicked, raises the "submit" event.
3) Find an <input type="file"> HTML element.
4) When the "onsubmit" event is raised, handle it.
5) Let JavaScript know that the client-side event was handled by external handler:
form.SetAttribute("hasBrow
6) The FormToMultipartPostData.Su
All these steps need to work correctly, or the upload will not occur.
ASKER
Putting it back to onsubmit doesn't do anything.
I grab the id for the save button, click it, get the script error, then it just kind of sits there... :(
The only onsubmit that I see in the source is within the page function:
I grab the id for the save button, click it, get the script error, then it just kind of sits there... :(
The only onsubmit that I see in the source is within the page function:
function oamSubmitForm(formName, linkId, target, params) {
var clearFn = 'clearFormHiddenParams_'+formName.replace(/-/g, '\$:').replace(/:/g,'_')
if (typeof window[clearFn] =='function') {
window[clearFn](formName)
}
var form = document.forms[formName]
var agentString = navigator.userAgent.toLowerCase()
if (agentString.indexOf('msie') != -1) {
if (!(agentString.indexOf('ppc') != -1 && agentString.indexOf('windows ce') != -1 && version >= 4.0)) {
window.external.AutoCompleteSaveForm(form)
}
}
var oldTarget = form.target
if(target != null) {
form.target=target
}
if((typeof params!='undefined') && params != null) {
for(var i=0, param; (param = params[i]); i++) {
oamSetHiddenInput(formName,param[0], param[1])
}
}
oamSetHiddenInput(formName,formName +':'+'_idcl',linkId)
if(form.onsubmit) {
var result=form.onsubmit()
if((typeof result=='undefined')||result) {
try {
form.submit()
} catch(e) {
}
}
}else {
try{
form.submit()
}catch(e){
}
}
form.target=oldTarget
if((typeof params!='undefined') && params != null) {
for(var i=0, param; (param = params[i]); i++) {
oamClearHiddenInput(formName,param[0], param[1])
}
}
oamClearHiddenInput(formName,formName +':'+'_idcl',linkId)
return false
}
ASKER
Perhaps a silly, certainly ignorant, question - case doesn't matter with 'onsubmit' does it?
ASKER
So I shouldn't be focused on the onclick listed under the anchor tag?
<a href="#"
onclick="return
oamSubmitForm ('zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm','zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:saveZDMSessionConfig');"
id="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:saveZDMSessionConfig"
class="ButtonLeft">
<div class="ButtonRight"><div class="ButtonMiddle">Save</div></div>
</a>
"case doesn't matter with 'onsubmit' does it?"
That is never a silly question when working with C# and Javascript, but as a VB.NET programmer it makes sense that you think it is silly. Case does matter in most cases.
This line will submit the page:
form.submit()
If you have attached to the correct handler, then the event should be handled by the VB.NET code.
That is never a silly question when working with C# and Javascript, but as a VB.NET programmer it makes sense that you think it is silly. Case does matter in most cases.
This line will submit the page:
form.submit()
If you have attached to the correct handler, then the event should be handled by the VB.NET code.
ASKER
And this is the only instance I see window.external, within that function above (window.external.AutoCompl eteSaveFor m(form)) which is where the script error is thrown immediately after clicking save.
ASKER
This line will submit the page:So use that rather than Savebutton.click()?
form.submit()
"So I shouldn't be focused on the onclick listed under the anchor tag?"
Yes, you should be focused on that, since it calls the oamSubmitForm, which in turn calls the form.submit(), which raises the "onsubmit" event, which is handled by the code.
Knee bone connected to the thigh bone...
Thigh bone connected to the hip bone...
Yes, you should be focused on that, since it calls the oamSubmitForm, which in turn calls the form.submit(), which raises the "onsubmit" event, which is handled by the code.
Knee bone connected to the thigh bone...
Thigh bone connected to the hip bone...
ASKER
submit is not a member of system.windows.forms.htmle lement.
Trying form.raiseevent instead...
Trying form.raiseevent instead...
ASKER
Gah - raiseevent gives me "Value does not fall within the expected range." :(
While those were valiant attempts, they will not get you where you need to be. I believe that it should be possible if we follow the code example project from CodeProject, we just need to get all the steps to work as expected.
ASKER
Ok, so backing up to your outline above...only step #1 is definitely completed/working.
I'm unsure that the save anchor being clicked is raising the submit event. Based on what I'm seeing, it is not, or at least it's throwing a script error first that may or may not be interfering. Suppressing the script errors doesn't seem to do anything.
I'm going to step through the forms.count loop and see if I can determine any uniqueness there.
I also moved the form.raiseevent("submit") within this loop, after the hasBrowserHandler is set.
I'm unsure that the save anchor being clicked is raising the submit event. Based on what I'm seeing, it is not, or at least it's throwing a script error first that may or may not be interfering. Suppressing the script errors doesn't seem to do anything.
I'm going to step through the forms.count loop and see if I can determine any uniqueness there.
I also moved the form.raiseevent("submit") within this loop, after the hasBrowserHandler is set.
ASKER
? doc.forms(0).getattribute( "enctype") & vbTab & doc.forms(0).id
"application/x-www-form-ur lencoded zdmSummaryDetailsSubview:h eaderViewp c1:headerF ormpc1"
? doc.forms(1).getattribute( "enctype") & vbTab & doc.forms(1).id
"application/x-www-form-ur lencoded zdmSummaryDetailsSubview:h eaderViewp c1:globalA ctionsForm pc1"
? doc.forms(2).getattribute( "enctype") & vbTab & doc.forms(2).id
"application/x-www-form-ur lencoded zdmSummaryDetailsSubview:n av1Viewpc1 :navServic esFormpc1"
? doc.forms(3).getattribute( "enctype") & vbTab & doc.forms(3).id
"application/x-www-form-ur lencoded zdmSummaryDetailsSubview:n av2Viewpc1 :nav2Servi ceZDMFormp c1"
? doc.forms(4).getattribute( "enctype") & vbTab & doc.forms(4).id
"application/x-www-form-ur lencoded zdmSummaryDetailsSubview:r elContentV iewpc1:zdm TabsForm"
? doc.forms(5).getattribute( "enctype") & vbTab & doc.forms(5).id
"application/x-www-form-ur lencoded "
? doc.forms(6).getattribute( "enctype") & vbTab & doc.forms(6).id
"multipart/form-data zdmSummaryDetailsSubview:r elContentV iewpc1:tab ZDMService :tabZDMSer viceSettin gs:zdmDeta ilsForm"
? doc.forms(7).getattribute( "enctype") & vbTab & doc.forms(7).id
"application/x-www-form-ur lencoded zdmSummaryDetailsSubview:r elContentV iewpc1:zdm TabsForm2"
? doc.forms(8).getattribute( "enctype") & vbTab & doc.forms(8).id
"application/x-www-form-ur lencoded zdmSummaryDetailsSubview:f ooterViewp c1:footerF ormpc1"
So, it appears that element 6 is the one I want, and the only one with multipart/form-data.
The inner/outer html shows:
Within there, I see the INPUT file type:
<INPUT id=zdmSummaryDetailsSubvie w:relConte ntViewpc1: tabZDM
Service:tabZDMServiceSetti ngs:zdmDet ailsForm:m sglockfile upload class=formField size=40 type=file name=zdmSummaryDetailsSubv iew:relCon tentViewpc 1:tabZDMSe rvice:tabZ DMServiceS ettings:zd mDetailsFo rm:msglock fileupload >
and I also see the save anchor element:
<A id=zdmSummaryDetailsSubvie w:relConte ntViewpc1: tabZDMServ ice:tabZDM ServiceSet tings:zdmD etailsForm :saveZDMSe ssionConfi g class=ButtonLeft onclick="return oamSubmitForm('zdmSummaryD etailsSubv iew:relCon tentViewpc 1:tabZDMSe rvice:tabZ DMServiceS ettings:zd mDetailsFo rm','zdmSu mmaryDetai lsSubview: relContent Viewpc1:ta bZDMServic e:tabZDMSe rviceSetti ngs:zdmDet ailsForm:s aveZDMSess ionConfig' );" href="#">
So since I'm clicking the anchor element, I need to somehow associate the INPUT file type to reference the external file, correct?
In the form loop, it hits i=6, as expected, attaches the event handler to "onsubmit", sets the attribute "hasBrowserHandler" to 1, and that's where I attempt the form.RaiseEvent("submit"). Hitting that line throws an ArgumentException was unhandled by user code: Value does not fall within the expected range.
<sigh> - It was all so 'easy' compared to this... :\
"application/x-www-form-ur
? doc.forms(1).getattribute(
"application/x-www-form-ur
? doc.forms(2).getattribute(
"application/x-www-form-ur
? doc.forms(3).getattribute(
"application/x-www-form-ur
? doc.forms(4).getattribute(
"application/x-www-form-ur
? doc.forms(5).getattribute(
"application/x-www-form-ur
? doc.forms(6).getattribute(
"multipart/form-data zdmSummaryDetailsSubview:r
? doc.forms(7).getattribute(
"application/x-www-form-ur
? doc.forms(8).getattribute(
"application/x-www-form-ur
So, it appears that element 6 is the one I want, and the only one with multipart/form-data.
The inner/outer html shows:
" <FORM id=zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm encType=multipart/form-data method=post name=zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm action=/console/services/zdm/index.jsf file="\\hfdp-spd-020\email\voltagepoc\message locking\msglocking.csv"><DIV class=leftPaddedSection> <DIV class=form> <TABLE border=0 cellSpacing=2 width="100%"> <TBODY> <TR> <TD class=formLabelNoWrap>Default Domain *</TD> <TD><INPUT id=defaultDomain class=formField value=aetna.com size=30 name=defaultDomain></TD></TR> <TR> <TD class=formLabelNoWrap>Message Format</TD> <TD><SELECT id=msgFormat class=formField size=1 name=msgFormat> <OPTION value=V2>Version 2</OPTION> <OPTION selected value=V3>Version 3</OPTION></SELECT></TD></TR> <TR> <TD class=formLabelNoWrap><NOBR>Session Timeout Period (minutes) *</NOBR></TD> <TD><INPUT id=sessionTimeout class=formField value=20 size=12 name=sessionTimeout></TD></TR> <TR> <TD class=
formLabelNoWrap>Identity Timeout Policy</TD> <TD><SELECT id=identityTimeoutPolicy class=formField onchange=submit() size=1 name=identityTimeoutPolicy> <OPTION value=OFF>Disabled</OPTION> <OPTION value=NEVER>Enabled - Never Times Out</OPTION> <OPTION selected value=TIMEOUT>Enabled - With Timeout Period</OPTION></SELECT></TD></TR> <TR> <TD class=formLabelNoWrap>Identity Timeout Period</TD> <TD><INPUT id=identityTimeout class=formField value=12 size=12 name=identityTimeout> <SELECT id=identityTimeoutUnit class=formField size=1 name=identityTimeoutUnit> <OPTION selected value=HOUR>Hour(s)</OPTION> <OPTION value=DAY>Day(s)</OPTION> <OPTION value=WEEK>Week(s)</OPTION></SELECT></TD></TR> <TR> <TD class=formLabelNoWrap><SPAN class=formLabelTop>Message Locking Configuration</SPAN></TD> <TD><BR><SPAN class=formTip>Browse to select a CSV file, then click the Save button to upload it.</SPAN> <TABLE border=0 cellSpacing=0 cellPadding=2> <TBODY> <TR> <TD><INPUT id=zdmSummaryDetailsSubview:relContentViewpc1:tabZDM
Service:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload class=formField size=40 type=file name=zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload></TD> <TD></TD></TR></TBODY></TABLE> <TABLE border=0 cellSpacing=0 cellPadding=3> <TBODY> <TR> <TD><A id=zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:downloadMsgLockConfig onclick="return oamSubmitForm('zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm','zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:downloadMsgLockConfig');" href="#">Download current configuration</A></TD> <TD></TD> <TD><A id=zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:clearMsgLockConfig onclick="var cf = function(){if (!confirm('Are you sure you want to delete all message locking filters?')) return false};var oamSF = function(){return oam
SubmitForm('zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm','zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:clearMsgLockConfig');};return (cf()==false)? false : oamSF();" href="#">Clear current configuration</A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></DIV></DIV><BR> <TABLE border=0 cellSpacing=0 cellPadding=0 width="100%"> <TBODY> <TR> <TD> <DIV class=ButtonRowR> <TABLE class=ButtonWrapper> <TBODY> <TR> <TD><A id=zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:saveZDMSessionConfig class=ButtonLeft onclick="return oamSubmitForm('zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm','zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:saveZDMSessionConfig');" href="#"> <DIV class=ButtonRight> <DIV class=ButtonMiddle>Save</DIV></DIV></A></TD></TR></TBODY></TABLE></DIV></
TD></TR></TBODY></TABLE><INPUT value=1 type=hidden name=zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm_SUBMIT><INPUT value=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAN0AAE1cHQAFy9zZXJ2aWNlcy96ZG0vaW5kZXguanNw type=hidden name=javax.faces.ViewState></FORM>"
Within there, I see the INPUT file type:
<INPUT id=zdmSummaryDetailsSubvie
Service:tabZDMServiceSetti
and I also see the save anchor element:
<A id=zdmSummaryDetailsSubvie
So since I'm clicking the anchor element, I need to somehow associate the INPUT file type to reference the external file, correct?
In the form loop, it hits i=6, as expected, attaches the event handler to "onsubmit", sets the attribute "hasBrowserHandler" to 1, and that's where I attempt the form.RaiseEvent("submit").
<sigh> - It was all so 'easy' compared to this... :\
ASKER
Took a step even further back, just to see if I could get 'any' success clicking an anchor.
So, immediately after logon, I grab the anchor for the Service tab and try to click, but it's coming up as 'nothing' when choosing HTMLAnchorElement. Could it be that these should be defined as something besides an anchor? :\
So, immediately after logon, I grab the anchor for the Service tab and try to click, but it's coming up as 'nothing' when choosing HTMLAnchorElement. Could it be that these should be defined as something besides an anchor? :\
ASKER
Or could it be that it's supposed to reference the 'name' value? I notice some have id & name, some only have ID... :\
ASKER
Don't know why I had such trouble locating the Service tab, but once I did, by stepping throuh to the GetHtmlElementById, I was able to locate it. Once clicked, however, and this is only changing tabs, it barfed on the window.external script error again. Looks like that's expecting a value each time that function is called.
ASKER
I'm guessing this part of the function is ensuring it's not a mobile device, and attempting to enable autocomplete? Though I don't know why, or how to disable that, it appears to be the only source of this window.external in the source.
if (agentString.indexOf('msie ') != -1) {
if (!(agentString.indexOf('pp c') != -1 && agentString.indexOf('windo ws ce') != -1 && version >= 4.0)) {
window.external.AutoComple teSaveForm (form)
}
}
if (agentString.indexOf('msie
if (!(agentString.indexOf('pp
window.external.AutoComple
}
}
ASKER
I'm stumped. :(
I even tried having my code 'wait' till I populated the file field manually, and follow up with a save click, and it still throws the script error for window.external...
I'll upload the source, in case that helps trigger anything on your end.
zdm.txt
I even tried having my code 'wait' till I populated the file field manually, and follow up with a save click, and it still throws the script error for window.external...
I'll upload the source, in case that helps trigger anything on your end.
zdm.txt
You need to pass the correct User Agent string in the headers, that includes "msie" in the request headers, since it really is Internet Explorer, which is why it barfs on the AutoCompleteSaveForm.
Changing the User Agent in a web browser control
http://www.lukepaynesoftware.com/articles/programming-tutorials/changing-the-user-agent-in-a-web-browser-control/
Remember that Fiddler comment? You can look at what Internet Explorer passes as the user agent.
Changing the User Agent in a web browser control
http://www.lukepaynesoftware.com/articles/programming-tutorials/changing-the-user-agent-in-a-web-browser-control/
Remember that Fiddler comment? You can look at what Internet Explorer passes as the user agent.
ASKER
I went back and 'fiddled' with fiddler - still couldn't get it to grab anything, though it does state that some policies might prevent that.
I'll have a look at the user agent.
I'll have a look at the user agent.
ASKER
User error with fiddler...under my admin account it captures, so that's sorted....
ASKER
I see upon logon, the user agent is set to this:
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MS-RTC LM 8)
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MS-RTC LM 8)
That Javascript goes is looking for "msie", which is "MSIE 8.0".
ASKER
Although I'm seeing a lot more in fiddler now, I'm not sure how to implement it.
The user agent method above indicates to use .navigate to pass the user agent, but if I'm grabbing an anchor reference, I don't have .navigate.
However, I did get a successful "service tab" click/navigate using:
WebBrowser1.Navigate(Site. Uri.ToStri ng, "_self", Nothing, "User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MS-RTC LM 8)")
Would I just replace the .click method with a navigate to the href="#"? So long as I can locate and modify the file= attribute?
The user agent method above indicates to use .navigate to pass the user agent, but if I'm grabbing an anchor reference, I don't have .navigate.
However, I did get a successful "service tab" click/navigate using:
WebBrowser1.Navigate(Site.
Would I just replace the .click method with a navigate to the href="#"? So long as I can locate and modify the file= attribute?
I looked at the HTML text that you sent me, but I wouldn't be able to set up a mock web site without the Javascript that is referenced:
<script language="JavaScript" type="text/javascript" src="/console/scripts/help Popup.js?5 .1.2"></sc ript>
<script language="JavaScript" type="text/javascript" src="/console/scripts/posi tion.js?5. 1.2"></scr ipt>
<script language="JavaScript" type="text/javascript" src="/console/scripts/util s.js?5.1.2 "></script >
<script language="JavaScript" type="text/javascript" src="/console/scripts/prog ress.js?5. 1.2"></scr ipt>
<script language="JavaScript" type="text/javascript" src="/console/scripts/iefl icker.js?5 .1.2"></sc ript>
<script language="JavaScript" type="text/javascript" src="/console/scripts/even ts.js?5.1. 2"></scrip t>
You could use developer tools on the web browser, and capture the Javascript text, and send me the files, and I could set up a web site with that HTML, and see if I can't get an upload.
<script language="JavaScript" type="text/javascript" src="/console/scripts/help
<script language="JavaScript" type="text/javascript" src="/console/scripts/posi
<script language="JavaScript" type="text/javascript" src="/console/scripts/util
<script language="JavaScript" type="text/javascript" src="/console/scripts/prog
<script language="JavaScript" type="text/javascript" src="/console/scripts/iefl
<script language="JavaScript" type="text/javascript" src="/console/scripts/even
You could use developer tools on the web browser, and capture the Javascript text, and send me the files, and I could set up a web site with that HTML, and see if I can't get an upload.
ASKER
I don't know if that opens up a new can of worms or not...you make it sound so simple, and yet... ;^)
I think I might be able to play with Fiddler over the weekend and see if I can come up with at least something helpful. I tried navigating to the "#" reference link, but didn't work.
For the 'data' that is submitted from the csv, I do see this in fiddler:
I think I might be able to play with Fiddler over the weekend and see if I can come up with at least something helpful. I tried navigating to the "#" reference link, but didn't work.
For the 'data' that is submitted from the csv, I do see this in fiddler:
Content-Disposition: form-data; name="zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload"; filename="\\unc_path\filename.csv"
Content-Type: application/vnd.ms-excel
ASKER
Sheesh - I don't know if I'm close or not.
After submitting save, adding the file info to the header, I got
Problem accessing /%23. Reason:
Not Found
Haha. I hope I don't break something. :^)
After submitting save, adding the file info to the header, I got
Problem accessing /%23. Reason:
Not Found
Haha. I hope I don't break something. :^)
That sounds like an HTTP 404 error, which means "Resource not found". Is this a Javascript error?
I found the Javascript that I was looking for, embedded in the HTML:
I found the Javascript that I was looking for, embedded in the HTML:
function oamSubmitForm(formName, linkId, target, params) {
var clearFn = 'clearFormHiddenParams_' + formName.replace(/-/g, '\$:').replace(/:/g, '_');
if (typeof window[clearFn] == 'function') {
window[clearFn](formName);
}
var form = document.forms[formName];
var agentString = navigator.userAgent.toLowerCase();
if (agentString.indexOf('msie') != -1) {
if (!(agentString.indexOf('ppc') != -1 && agentString.indexOf('windows ce') != -1 && version >= 4.0)) {
window.external.AutoCompleteSaveForm(form);
}
}
var oldTarget = form.target;
if (target != null) {
form.target = target;
}
if ((typeof params != 'undefined') && params != null) {
for (var i = 0, param;
(param = params[i]); i++) {
oamSetHiddenInput(formName, param[0], param[1]);
}
}
oamSetHiddenInput(formName, formName + ':' + '_idcl', linkId);
if (form.onsubmit) {
var result = form.onsubmit();
if ((typeof result == 'undefined') || result) {
try {
form.submit();
} catch (e) {}
}
} else {
try {
form.submit();
} catch (e) {}
}
form.target = oldTarget;
if ((typeof params != 'undefined') && params != null) {
for (var i = 0, param;
(param = params[i]); i++) {
oamClearHiddenInput(formName, param[0], param[1]);
}
}
oamClearHiddenInput(formName, formName + ':' + '_idcl', linkId);
return false;
}
%23 = # in URL encoding.
.jsf extensions are related to the Java FacesServlet. It looks like it is trying to show a Home page.
ASKER
Well that's a pretty good representation of the site. :^)
Are you using IE? When I ran it from chrome it looked more like that. IE showed the save button on the right and uses 'browse' instead of 'choose file'.
I thought index.jsf was the home page. :\
Are you using IE? When I ran it from chrome it looked more like that. IE showed the save button on the right and uses 'browse' instead of 'choose file'.
I thought index.jsf was the home page. :\
I don't like IE, so I always use Chrome as my browser of choice.
The anchor tags have an href="#", which means scroll to the top of the page:
Example:
<a href="#" onclick="var cf = function(){window.open('/c onsole/hel p/Vg_secur email_cons ole_help.h tm', 'VgSMConsoleHelp', 'height=500,width=700,stat us,toolbar =0,menubar =0,status= 0,scrollba rs,resizab le'); return false;}
I would like to understand how that error comes up. Is it a Javascript error? Can you attach a screen shot?
The anchor tags have an href="#", which means scroll to the top of the page:
Example:
<a href="#" onclick="var cf = function(){window.open('/c
I would like to understand how that error comes up. Is it a Javascript error? Can you attach a screen shot?
I am wondering if "zdm" refers to this:
Voltage SecureMail Cloud
https://www.voltage.com/vsn/login-pages.htm
Zero Download Messenger (ZDM);
Voltage SecureMail Cloud
https://www.voltage.com/vsn/login-pages.htm
Zero Download Messenger (ZDM);
ASKER
Indeed it does. We are using their secure mail product.
We currently have to manually append to this csv file to lock a message.
This would allow the customer to get immediate message locking rather than wait on a tech to see the email and respond...
Which error did you want a screenshot of?
We currently have to manually append to this csv file to lock a message.
This would allow the customer to get immediate message locking rather than wait on a tech to see the email and respond...
Which error did you want a screenshot of?
The /%23 not found error.
ASKER
Sure, it was kind of bland, but I'll upload it...
ASKER
Oh, I looked at the code again, and it was one attempt I had made to change the uri path to simply "#".
When I used the debugger to view the site's path value, it was "%23" - that must be where that came from...
When I used the debugger to view the site's path value, it was "%23" - that must be where that came from...
ASKER
Yeah, it's no longer appearing...was apparently just a mistake I made yesterday testing.
ASKER
Was trying to use the .navigate with the useragent and the data I saw from fiddler.
Clearly I don't know what I'm doing...
WebBrowser1.Navigate("#", "_self", Nothing, UserAgent & vbCrLf & "Content-Disposition: form-data; name=" & Chr(34) & "zdmSummaryDetailsSubview: relContent Viewpc1:ta bZDMServic e:tabZDMSe rviceSetti ngs:zdmDet ailsForm:m sglockfile upload" & Chr(34) & "; filename=" & Chr(34) & "\\UNCpath\lockfile.csv" & Chr(34) & vbCrLf & "Content-Type: application/vnd.ms-excel")
Clearly I don't know what I'm doing...
WebBrowser1.Navigate("#", "_self", Nothing, UserAgent & vbCrLf & "Content-Disposition: form-data; name=" & Chr(34) & "zdmSummaryDetailsSubview:
ASKER
This is why the %23, and I tried the .navigate with the suggestion, but it didn't seem to work - went back to the first service page. :\
http://social.msdn.microsoft.com/Forums/en-US/11459b7a-1ee1-4a54-a4fb-76967ee22c96/webbrowser-control-how-to-navigate-to-an-anchor-new-uri-conversion-issue-23?forum=netfxcompact
Seems like my problem now is that I can navigate using the useragent, but I can't "click" with it...
http://social.msdn.microsoft.com/Forums/en-US/11459b7a-1ee1-4a54-a4fb-76967ee22c96/webbrowser-control-how-to-navigate-to-an-anchor-new-uri-conversion-issue-23?forum=netfxcompact
Seems like my problem now is that I can navigate using the useragent, but I can't "click" with it...
Would that be the first time that you navigate to a URL? I would think that you need to send it on every navigate. Another possibility might be to create a custom WebBrowser class, and in the BeforeNavigate, set the user agent.
public class ExtendedWebBrowser : WebBrowser
{
bool renavigating = false;
public string UserAgent { get; set; }
public ExtendedWebBrowser()
{
DocumentCompleted += SetupBrowser;
//this will cause SetupBrowser to run (we need a document object)
Navigate("about:blank");
}
void SetupBrowser(object sender, WebBrowserDocumentCompletedEventArgs e)
{
DocumentCompleted -= SetupBrowser;
SHDocVw.WebBrowser xBrowser = (SHDocVw.WebBrowser)ActiveXInstance;
xBrowser.BeforeNavigate2 += BeforeNavigate;
DocumentCompleted += PageLoaded;
}
void PageLoaded(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
void BeforeNavigate(object pDisp, ref object url, ref object flags, ref object targetFrameName,
ref object postData, ref object headers, ref bool cancel)
{
if (!string.IsNullOrEmpty(UserAgent))
{
if (!renavigating)
{
headers += string.Format("User-Agent: {0}\r\n", UserAgent);
renavigating = true;
cancel = true;
Navigate((string)url, (string)targetFrameName, (byte[])postData, (string)headers);
}
else
{
renavigating = false;
}
}
}
}
VB.NET:
Public Class ExtendedWebBrowser
Inherits WebBrowser
Private renavigating As Boolean = False
Public Property UserAgent() As String
Public Sub New()
AddHandler DocumentCompleted, AddressOf SetupBrowser
'this will cause SetupBrowser to run (we need a document object)
Navigate("about:blank")
End Sub
Private Sub SetupBrowser(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
RemoveHandler DocumentCompleted, AddressOf SetupBrowser
Dim xBrowser As SHDocVw.WebBrowser = DirectCast(ActiveXInstance, SHDocVw.WebBrowser)
AddHandler xBrowser.BeforeNavigate2, AddressOf BeforeNavigate
AddHandler DocumentCompleted, AddressOf PageLoaded
End Sub
Private Sub PageLoaded(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
End Sub
Private Sub BeforeNavigate(pDisp As Object, ByRef url As Object, ByRef flags As Object, ByRef targetFrameName As Object, ByRef postData As Object, ByRef headers As Object, _
ByRef cancel As Boolean)
If Not String.IsNullOrEmpty(UserAgent) Then
If Not renavigating Then
headers += String.Format("User-Agent: {0}" & vbCr & vbLf, UserAgent)
renavigating = True
cancel = True
Navigate(url.ToString(), targetFrameName.ToString(), DirectCast(postData, Byte()), headers.ToString())
Else
renavigating = False
End If
End If
End Sub
End Class
ASKER
Hmm, that seems promising. I'll try to implement it... haha.
ASKER
Would I need to move my documentcompleted sub into there as well?
No, your code could stand as it is, since you are just extending the WebBrowser class to add additional behavior. That class would have a UserAgent property, that you set once, and would be passed to the web site every time before the control needed to navigate.
BTW, what version of Visual Studio are you working with?
ASKER
2010
ASKER
SHDocVw.Webbrosser is not defined - I need to add reference to that dll, yes? Cause that's what I'm doing unless you tell me otherwise. :^)
ASKER
And I change my designer to
Me.Webbrowser1 = New ExtendedWebBrowser, yes?
Me.Webbrowser1 = New ExtendedWebBrowser, yes?
ASKER
I don't really see much of a change, other than I did remove the user agent from my doccompleted sub and that's working...
Here's my sub - maybe I've simply set something up bogus...
Here's my sub - maybe I've simply set something up bogus...
Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
If e.Url.AbsolutePath.ToLower.Contains("login") Then Exit Sub 'still at the logon page
If ServiceTabClicked Then
If ZDMConfigTabClicked Then
If SaveButtonClicked Then
'read form to find 'success' or 'error/else'
'todo: once file successfully uploaded, form displays results in red/green
Else
Dim filename As String = "\\URLPath\LockFile.csv"
Dim browseButton As mshtml.HTMLInputElement = helper.GetHtmlElementById(Of mshtml.HTMLInputElement)("zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:msglockfileupload")
browseButton.setAttribute("filename", filename) 'something I've tried - doesn't work
Dim SaveButton As mshtml.HTMLAnchorElement = helper.GetHtmlElementById(Of mshtml.HTMLAnchorElement)("zdmSummaryDetailsSubview:relContentViewpc1:tabZDMService:tabZDMServiceSettings:zdmDetailsForm:saveZDMSessionConfig")
Dim doc As HtmlDocument = WebBrowser1.Document
For i As Integer = 0 To doc.Forms.Count - 1
' must be declared inside the loop because there's a closure
form = doc.Forms(i)
If form.GetAttribute("enctype").ToLower() <> "multipart/form-data" Then Continue For
form.AttachEventHandler("onsubmit", AddressOf OnSubmit)
' form.AttachEventHandler("onclick", AddressOf OnSubmit)
form.SetAttribute("hasBrowserHandler", "1")
'have also found this elsewhere as form.SetAttribute("hasBrowserHandlers", "true") but doesn't seem to change anything
Next
SaveButtonClicked = True 'technically it's not at this point
'VoltageSite.Path += "#" 'this was throwing my %23 error
WebBrowser1.Navigate(VoltageSite.Uri.ToString) ' not working
'SaveButton.click() ' still throws the script error :(
End If
Else
Dim zdmCfgTab As mshtml.HTMLInputElement = helper.GetHtmlElementById(Of mshtml.HTMLInputElement)("zdmSummaryDetailsSubview:relContentViewpc1:configZDMTabbedPane.2")
zdmCfgTab.click()
zdmCfgTab = Nothing
ZDMConfigTabClicked = True
End If
Else
VoltageSite.Path = "console/services/zdm/index.jsf"
WebBrowser1.Navigate(VoltageSite.Uri.ToString) ', "_self", Nothing, UserAgent)
'WebBrowser1.Navigate(VoltageSite.Uri.ToString)
ServiceTabClicked = True
End If
End Sub
Which edition of Visual Studio 2010 do you have? Do you have the ability to record Coded UI tests?
How to: Create a Coded UI Test
http://msdn.microsoft.com/en-us/library/dd286681(v=vs.100).aspx
How to: Create a Coded UI Test
http://msdn.microsoft.com/en-us/library/dd286681(v=vs.100).aspx
Using Visual Studio Premium or Visual Studio Ultimate, you can create a coded UI test that can test that the user interface for an application functions correctly
ASKER
If I don't, I can probably get permissions to install another edition...I'll check and get back to you.
Thanks.
Thanks.
ASKER
Well apparently 'permission' will be very hard to come by. :(
Nonetheless, I'm still testing. I'm going to run through fiddler once more and try to build a new project from the ground up using what I find there. Hopefully the new/fresh perspective will help.
Nonetheless, I'm still testing. I'm going to run through fiddler once more and try to build a new project from the ground up using what I find there. Hopefully the new/fresh perspective will help.
I was curious what edition you were using after some out-of-the-box thinking. With Coded UI unit tests, you can record a test, generate some code, and play it back with different arguments, which might get you what you need.
ASKER
I have VS 2010 Professional :(
ASKER
I've walked through recreating the entire thing from scratch...though I didn't use mshtml this time.
Everything works up until that point. :(
In Fiddler, I can see that it's setting the input, type=file, value to the path of the csv.
Yet, when I try to use setattribute against that, it remains blank. I'm guessing because that field is essentially 'locked' unless using the browse button, so I'm wondering if I'm back to trying to track down the handle of the file dialogue...
Everything works up until that point. :(
In Fiddler, I can see that it's setting the input, type=file, value to the path of the csv.
Yet, when I try to use setattribute against that, it remains blank. I'm guessing because that field is essentially 'locked' unless using the browse button, so I'm wondering if I'm back to trying to track down the handle of the file dialogue...
ASKER
Yep, once I programmatically clicked the browse button and selected the file, it's holding the "value" attribute... ugh.
ASKER
Apparenlty this is 'by design'... http://www.cs.tut.fi/~jkorpela/forms/file.html#value
<sigh>
<sigh>
"Yet, when I try to use setattribute against that, it remains blank."
Can you explain what you mean by that?
You can't set the value attribute for the <input type="file">, since it is a security violation. This whole exercise has been detecting the submit, and posting the file. I am lost why that didn't work as expected.
Can you explain what you mean by that?
You can't set the value attribute for the <input type="file">, since it is a security violation. This whole exercise has been detecting the submit, and posting the file. I am lost why that didn't work as expected.
ASKER
I think I know why - I had previously been focused on grabbing the button ID.
Re-reading that site I've modified that to grabbing the correct form ID and now it's working through the loop and located the FILE element...stay tuned.
Re-reading that site I've modified that to grabbing the correct form ID and now it's working through the loop and located the FILE element...stay tuned.
ASKER
I don't know if I'm more hard-headed or more ignorant, but I think much of this is starting to make more sense to me...
So, here's what I'm seeing now:
Still throws the script error (window.external) on the button click, but I don't know how the useragent can be added to a click event (like we had with the navigate method).
It runs through the GetValusFromForm - it does locate the "FILE" element, but obviously it's blank.
But it includes several of the other settings that it's passing.
It returns to the event handler, and sets the file (I changed this to "filename" since it's actually showing in fiddler as filename).
Right before postData.Submit(), I examine the data.
I have 8 values (the aforementioned settings) listed in PostData.values (count=8).
I have a files (count=1) property as well.
For PostData.Files(0) I have
name:"zdmSummaryDetailsSub view:relCo ntentViewp c1:tabZDMS ervice:tab ZDMService Settings:z dmDetailsF orm:msgloc kfileuploa d"
value: ""
I would have expected that to be the path of the file... :(
So, here's what I'm seeing now:
Still throws the script error (window.external) on the button click, but I don't know how the useragent can be added to a click event (like we had with the navigate method).
It runs through the GetValusFromForm - it does locate the "FILE" element, but obviously it's blank.
But it includes several of the other settings that it's passing.
It returns to the event handler, and sets the file (I changed this to "filename" since it's actually showing in fiddler as filename).
Right before postData.Submit(), I examine the data.
I have 8 values (the aforementioned settings) listed in PostData.values (count=8).
I have a files (count=1) property as well.
For PostData.Files(0) I have
name:"zdmSummaryDetailsSub
value: ""
I would have expected that to be the path of the file... :(
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
As it continues through to GetEncodedPostData(),
headerTemplate is equal to
"Content-Disposition: form-data; name="{0}"; filename="{1}" Content-Type: application/octet-stream "
Since the file path was empty, I forced it in that same routine, and it got to the point where it read the file and added it to the memStream, but I couldn't tell once it hit the navigate if it worked. (Hope that makes sense)
headerTemplate is equal to
"Content-Disposition: form-data; name="{0}"; filename="{1}" Content-Type: application/octet-stream "
Since the file path was empty, I forced it in that same routine, and it got to the point where it read the file and added it to the memStream, but I couldn't tell once it hit the navigate if it worked. (Hope that makes sense)
ASKER
Tried hard coding it in there, but it didn't seem to take the file.
I'll run through again after I grab a bite and turn fiddler back on to try to see if I can find the difference.
Meanwhile, do you know of a way to have the .Click() procedure include the UserAgent? Not sure if that sorts it, or if I need to ensure that it's added in this additional class...just thinking outloud.
I'll run through again after I grab a bite and turn fiddler back on to try to see if I can find the difference.
Meanwhile, do you know of a way to have the .Click() procedure include the UserAgent? Not sure if that sorts it, or if I need to ensure that it's added in this additional class...just thinking outloud.
"but I couldn't tell once it hit the navigate if it worked. (Hope that makes sense)"
There are two indications that I could think of:
1) Error
2) The file didn't upload
There are two indications that I could think of:
1) Error
2) The file didn't upload
ASKER
Running it through fiddler, I have 4 warnings:
Content-length mismatch; Request Header indicated 17,185 bytes, but client sent 0 bytes (twice)
Failed to obtain requestbody.System.IO.Inva lidDataExc eption The request body did not contain the specified number of bytes. Got 0, expected 17185 (twice)
Content-length mismatch; Request Header indicated 17,185 bytes, but client sent 0 bytes (twice)
Failed to obtain requestbody.System.IO.Inva
ASKER
But, fidder does show the same body info:
Content-Disposition: form-data; name="zdmSummaryDetailsSub view:relCo ntentViewp c1:tabZDMS ervice:tab ZDMService Settings:z dmDetailsF orm:msgloc kfileuploa d"; filename="My CSV File!"
Content-Type: application/octet-stream
Content-Disposition: form-data; name="zdmSummaryDetailsSub
Content-Type: application/octet-stream
ASKER
I'm finding the reference for hasBrowserHandler to be hasBrowserHandlers and instead of a value of 1, examples show a value of "true".
I'm not sure if setting attributes for both versions is a bad idea or not...so I've been flip-flopping them.
I'm not sure if setting attributes for both versions is a bad idea or not...so I've been flip-flopping them.
ASKER
Not sure if that's eliminated my script error, or my change to
form.RaiseEvent("onsubmit" )...
But, running fiddler again, it almost seems like it's only pushing part of the file. The details of that field don't scroll all the way down as if it's been truncated. I'm thinking maybe it has something to do with that error I'm seeing repeatedly about Content-length mismatch...
form.RaiseEvent("onsubmit"
But, running fiddler again, it almost seems like it's only pushing part of the file. The details of that field don't scroll all the way down as if it's been truncated. I'm thinking maybe it has something to do with that error I'm seeing repeatedly about Content-length mismatch...
ASKER
Looking through the working session vs non-working session today.
I see the definition passed for content-type was application/octet-stream, but the
working session shows it as "vnd.ms-excel", so I've changed that in the code.
These other things, I'm unsure of, but pointing out what I see as far as differences:
Obviously these lines are different, but I think they're unique per session:
-------------------------- ----8d1831 79e024d12
However, I did see the automated version had one additional hyphen, so I shortened that in the code.
The non working session has an empty/line feed at the top.
Both have 'form-data' for defaultDomain, msgFormat, sessionTimeout, identityTimeoutPolicy,
identityTimeout, and identityTimeoutUnit - values all correct.
Removing that, they both have
Content-Disposition: form-data; name="zdmSummaryDetailsSub view:relCo ntentViewp c1:tabZDMS ervice:tab ZDMService Settings:z dmDetailsF orm_SUBMIT "; (value of 1)
but these are in different places within the session data (not sure if that matters?)
The working session has one additional form-data info, that I don't see in the non-working session:
Content-Disposition: form-data; name="zdmSummaryDetailsSub view:relCo ntentViewp c1:tabZDMS ervice:tab ZDMService Settings:z dmDetailsF orm:_idcl"
zdmSummaryDetailsSubview:r elContentV iewpc1:tab ZDMService :tabZDMSer viceSettin gs:zdmDeta ilsForm:sa veZDMSessi onConfig
-------------------------- ---7de1684 362508--
Finally, this may be nit-picking, but the working session shows this line:
Content-Disposition: form-data; name="javax.faces.ViewStat e"
The non-working has a trailing semi-colon (;).
I see the definition passed for content-type was application/octet-stream, but the
working session shows it as "vnd.ms-excel", so I've changed that in the code.
These other things, I'm unsure of, but pointing out what I see as far as differences:
Obviously these lines are different, but I think they're unique per session:
--------------------------
However, I did see the automated version had one additional hyphen, so I shortened that in the code.
The non working session has an empty/line feed at the top.
Both have 'form-data' for defaultDomain, msgFormat, sessionTimeout, identityTimeoutPolicy,
identityTimeout, and identityTimeoutUnit - values all correct.
Removing that, they both have
Content-Disposition: form-data; name="zdmSummaryDetailsSub
but these are in different places within the session data (not sure if that matters?)
The working session has one additional form-data info, that I don't see in the non-working session:
Content-Disposition: form-data; name="zdmSummaryDetailsSub
zdmSummaryDetailsSubview:r
--------------------------
Finally, this may be nit-picking, but the working session shows this line:
Content-Disposition: form-data; name="javax.faces.ViewStat
The non-working has a trailing semi-colon (;).
ASKER
Oh, and Fiddler is now down to 2 complaints, instead of 4 about the content length mismatch...
Just let me know when I can help, because you are outside the boundaries now...
ASKER
I'll just go ahead and close this one. You've helped me a lot. Thanks!
Open in new window