Greetings,

I would like to write a c# program to upload an attachment
to a note.

I've read what I can find that describes how to do this
(including messages here on the board).

My first effort is to use the WebClient object and its
upload method. However, that's not working. I'm getting
a response, 500 "Server error". The webclient is posting
the file directly to the SRF. Can I use the webclient for
this? The key difference between webclient and using a
web browser is that the fields are added to the query
string rather than a "posted" field.

TIA and regards,

Re: SDK to upload attachments by Chris

Chris
Sun Sep 12 21:47:24 CDT 2004

Hi Paul,

I have done this, although in VB. I used an adapted version of the
webclient object, available from:

http://www.c-sharpcorner.com/Code/2003/May/DotNetBugs.asp

Getting a file to attach to a CRM email was probably one of the most
frustrating and time consuming things I have ever done, and the result is a
culmination of numerous attempts at resolution, and therefore there is
probably some redundancy as a result trying different approaches.

I'm sure by now you know how to use the SDK to create the email, and
subsequently the attachment. I am also sure that you have realised that the
emailattachment object returns the ID for the attachment, but does not allow
you to actually specify a file for upload.

The script I wrote creates the email, sets the recipients, sets the sender,
inserts the body and saves the email. After which it creates a new
attachment and associates it with the email. Finally it uploads a
particular file (for my purposes I knew the filename, as it had been
previously created) to the attachment. Finally it uses some client side
script in order to launch a new browser window to display the created email
object, with the file already attached. I did not want to automate the
sendign of the email, as it does not give the user an opportunity to check
it over or attach further files.

The following code assumes that you have downloaded the modified web client
object (norvanco.http.MultipartForm).

So...

Once you have created the email and obtained the ID for the attachment, this
is what you need to do:

Public Sub UploadAttachment(ByVal userID As String, ByVal merchantID As
String, ByVal filename As String, ByVal attachID As String, ByVal emailID As
String)

Dim _attachService As String
Dim _advWC As New norvanco.http.MultipartForm(_attachService)
Dim _advWCFields As New Specialized.NameValueCollection
Dim _reqCookies As String

_attachService = "http://" & AppSettings("crmServer") & "/" &
AppSettings("crmServicesDir") & "/ActivityAttachmentUpload.srf"

'Add the post data
'From memory the 1001 value for AttachmentType comes from the CRM
Enumerations - but you may want to check
_advWCFields.Add("AttachmentType", 1001)
_advWCFields.Add("AttachmentId", attachID)
_advWCFields.Add("UserId", userID)
_advWCFields.Add("MerchantId", merchantID)

'The ErrorURL and SuccessURL can be anything. They are used in the
CRM Web Client to direct a user to a page
'indicating the success/failure of the file upload - Obviously with
the webclient object, they are not relevant
_advWCFields.Add("ErrorURL",
"http://localhost/custom/quotemgmt/test1.aspx")
_advWCFields.Add("SuccessURL",
"http://localhost/custom/quotemgmt/test2.aspx")

'Set the post data fields in the modified web client
_advWC.setFields(_advWCFields)

'Set the protocol - although not sure if this is necessary
_advWC.TransferHttpVersion = New System.Version("1.0")

'Set the attachment type - in my usage, i know that it is going to
be an html file attachment
_advWC.FileContentType = "text/html"

'You need to transfer the current request's cookie string through to
the request made by the modified webclient

_reqCookies = Page.Request.Headers.Get("Cookie") '(conversely you
could use http.context.current.request)

'The sendFile method does not return a value indicating success - so
you can either rely on a try/catch statement or modify accordingly
_advWC.sendFile(filename,
System.Net.CredentialCache.DefaultCredentials, _reqCookies)

'Open the email in a new window for the client

Dim _sb As New Text.StringBuilder
Dim _emailURL As String = "http://" & AppSettings("crmServer") &
"/Activities/Email/edit.aspx?id=" & emailID

_sb.Append(vbCrLf + "<script>")
_sb.Append(vbCrLf + "var EmailWin = window.open('" & _emailURL & "',
'email_win', 'toolbar=no, status=yes, location=no, menubar=no, top=50,
left=50, height=533, width=694', '');")
_sb.Append(vbCrLf + "</script>")

Page.RegisterClientScriptBlock("OpenEmail", _sb.ToString)

End Sub

I've just checked the site for the Advanced WebClient, and there does not
appear to be any restriction on reposting the base code, so here is the code
including the modifications I made. You may want to check the original
against this to find my modifications.

If you have any questions, feel free to reply, and I'll see what I can do.

Cheers

Chris



using System;
using System.Net;
using System.Text;
using System.IO;
using System.Collections;

namespace norvanco.http
{
/// <summary>
/// Allow the transfer of data files using the W3C's specification
/// for HTTP multipart form data. Microsoft's version has a bug
/// where it does not format the ending boundary correctly.
/// Written by: gregoryp@norvanco.com
/// </summary>
public class MultipartForm
{
/// <summary>
/// Holds any form fields and values that you
/// wish to transfer with your data.
/// </summary>
private System.Collections.Specialized.NameValueCollection coFormFields;
/// <summary>
/// Used mainly to avoid passing parameters to other routines.
/// Could have been local to sendFile().
/// </summary>
protected HttpWebRequest coRequest;
/// <summary>
/// Used if we are testing and want to output the raw
/// request, minus http headers, out to a file.
/// </summary>
System.IO.Stream coFileStream;
/// <summary>
/// Difined to build the form field data that is being
/// passed along with the request.
/// </summary>
static string CONTENT_DISP = "Content-Disposition: form-data; name=";
/// <summary>
/// Allows you to specify the specific version of HTTP to use for
uploads.
/// The dot NET stuff currently does not allow you to remove the
continue-100 header
/// from 1.1 and 1.0 currently has a bug in it where it adds the
continue-100. MS
/// has sent a patch to remove the continue-100 in HTTP 1.0.
/// </summary>
public Version TransferHttpVersion
{get{return coHttpVersion;}set{coHttpVersion=value;}}
Version coHttpVersion;

/// <summary>
/// Used to change the content type of the file being sent.
/// Currently defaults to: text/xml. Other options are
/// text/plain or binary
/// </summary>


public string FileContentType
{get{return coFileContentType;}set{coFileContentType=value;}}
string coFileContentType;

/// <summary>
/// Initialize our class for use to send data files.
/// </summary>
/// <param name="url">The web address of the recipient of the data
transfer.</param>
public MultipartForm(string url)
{
URL = url;
coFormFields = new
System.Collections.Specialized.NameValueCollection();
ResponseText = new StringBuilder();
BufferSize = 1024 * 10;
BeginBoundary = "---------------------------7d419e378304a0";
TransferHttpVersion = HttpVersion.Version10;
FileContentType = "text/html";
}
//---------- BEGIN PROPERTIES SECTION ----------
string _BeginBoundary;
/// <summary>
/// The string that defines the begining boundary of
/// our multipart transfer as defined in the w3c specs.
/// This method also sets the Content and Ending
/// boundaries as defined by the w3c specs.
/// </summary>
public string BeginBoundary
{
get{return _BeginBoundary;}
set
{
_BeginBoundary =value;
ContentBoundary = "--" + BeginBoundary;
EndingBoundary = ContentBoundary + "--";
}
}
/// <summary>
/// The string that defines the content boundary of
/// our multipart transfer as defined in the w3c specs.
/// </summary>
protected string ContentBoundary
{get{return _ContentBoundary;}set{_ContentBoundary=value;}}
string _ContentBoundary;
/// <summary>
/// The string that defines the ending boundary of
/// our multipart transfer as defined in the w3c specs.
/// </summary>
protected string EndingBoundary
{get{return _EndingBoundary;}set{_EndingBoundary=value;}}
string _EndingBoundary;
/// <summary>
/// The data returned to us after the transfer is completed.
/// </summary>
public StringBuilder ResponseText
{get{return _ResponseText;}set{_ResponseText=value;}}
StringBuilder _ResponseText;
/// <summary>
/// The web address of the recipient of the transfer.
/// </summary>
public string URL
{get{return _URL;}set{_URL = value;}}
string _URL;
/// <summary>
/// Allows us to determine the size of the buffer used
/// to send a piece of the file at a time out the IO
/// stream. Defaults to 1024 * 10.
/// </summary>
public int BufferSize
{get{return _BufferSize;}set{_BufferSize = value;}}
int _BufferSize;
//---------- END PROPERTIES SECTION ----------
/// <summary>
/// Used to signal we want the output to go to a
/// text file verses being transfered to a URL.
/// </summary>
/// <param name="path"></param>
public void setFilename(string path)
{
coFileStream = new
System.IO.FileStream(path,FileMode.Create,FileAccess.Write);
}
/// <summary>
/// Allows you to add some additional field data to be
/// sent along with the transfer. This is usually used
/// for things like userid and password to validate the
/// transfer.
/// </summary>
/// <param name="key">The form field name</param>
/// <param name="str">The form field value</param>

public void setFields(System.Collections.Specialized.NameValueCollection
nv)
{
coFormFields = nv;
}
public void setField(string key, string str)
{
coFormFields[key] = str;
}
/// <summary>
/// Determines if we have a file stream set, and returns either
/// the HttpWebRequest stream of the file.
/// </summary>
/// <returns></returns>
public virtual System.IO.Stream getStream()
{
System.IO.Stream io;
if( null == coFileStream )
io = coRequest.GetRequestStream();
else
io = coFileStream;
return io;
}

public virtual void getResponse()
{
if( null == coFileStream )
{
System.IO.Stream io;
WebResponse oResponse;
try
{
oResponse = coRequest.GetResponse();
}
catch(WebException web )
{
oResponse = web.Response;
}
if( null != oResponse )
{
io = oResponse.GetResponseStream();
StreamReader sr = new StreamReader(io);
string str;
ResponseText.Length = 0;
while( (str = sr.ReadLine()) != null )
ResponseText.Append(str);
oResponse.Close();
}
else
throw new Exception("MultipartForm: Error retrieving server
response");
}
}
/// <summary>
/// Here we actually make the request to the web server and
/// retrieve it's response into a text buffer.
/// </summary>

/// <summary>
/// Transmits a file to the web server stated in the
/// URL property. You may call this several times and it
/// will use the values previously set for fields and URL.
/// </summary>
/// <param name="aFilename">The full path of file being
transfered.</param>
public void sendFile(string aFilename, ICredentials NetCreds, string
cks)
{
// The live of this object is only good during
// this function. Used mainly to avoid passing
// around parameters to other functions.

coRequest = (HttpWebRequest) WebRequest.Create(URL);
// Set use HTTP 1.0 or 1.1.
coRequest.ProtocolVersion = System.Net.HttpVersion.Version10;
coRequest.Credentials = NetCreds;
coRequest.Method = "POST";
coRequest.ContentType = "multipart/form-data; boundary=" +
BeginBoundary;
coRequest.Headers.Add("Cache-Control","no-cache");
coRequest.KeepAlive = true;
coRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/x-shockwave-flash, application/vnd.ms-excel,
application/vnd.ms-powerpoint, application/msword, */*";
// coRequest.Referer = "http://localhost/custom/quotemgmt/test.aspx";
coRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;
.NET CLR 1.1.4322)";
coRequest.Headers.Add("Accept-Encoding","gzip, deflate");
coRequest.Headers.Add("Accept-Language","en-au");
coRequest.AllowAutoRedirect = false;

coRequest.CookieContainer = new CookieContainer();

coRequest.Headers.Add("Cookie:" + cks);

string strFields = getFormfields();
string strFileHdr = getFileheader(aFilename);
string strFileTlr = getFiletrailer();

FileInfo info = new FileInfo(aFilename);
coRequest.ContentLength = strFields.Length +
strFileHdr.Length +
strFileTlr.Length +
info.Length;
System.IO.Stream io;
io = getStream();
writeString(io,strFields);
writeString(io,strFileHdr);
this.writeFile(io, aFilename);
writeString(io,strFileTlr);

getResponse();
io.Close();
// End the life time of this request object.
coRequest = null;


}


/// <summary>
/// Mainly used to turn the string into a byte buffer and then
/// write it to our IO stream.
/// </summary>
/// <param name="io">The io stream for output.</param>
/// <param name="str">The data to write.</param>
public void writeString(System.IO.Stream io, string str)
{
byte[] PostData = System.Text.Encoding.ASCII.GetBytes(str);
io.Write(PostData,0,PostData.Length);
}
/// <summary>
/// Builds the proper format of the multipart data that
/// contains the form fields and their respective values.
/// </summary>
/// <returns>The data to send in the multipart upload.</returns>
public string getFormfields()
{
string str="";

int ct = coFormFields.Count - 1;
for (int i = 0; i<=ct ; i++)
{
str += ContentBoundary + "\r\n" +
CONTENT_DISP + '"' + coFormFields.Keys[i] + "\"\r\n\r\n" +
coFormFields.Get(i) + "\r\n";
}
return str;
}
/// <summary>
/// Returns the proper content information for the
/// file we are sending.
/// </summary>
/// <remarks>
/// Hits Patel reported a bug when used with ActiveFile.
/// Added semicolon after sendfile to resolve that issue.
/// Tested for compatibility with IIS 5.0 and Java.
/// </remarks>
/// <param name="aFilename"></param>
/// <returns></returns>
public string getFileheader(string aFilename)
{
return ContentBoundary + "\r\n" +
CONTENT_DISP +
"\"userFile\"; filename=\"" +
(aFilename) + "\"\r\n" +
"Content-type: " + FileContentType + "\r\n\r\n";
}
/// <summary>
/// Creates the proper ending boundary for the multipart upload.
/// </summary>
/// <returns>The ending boundary.</returns>
public string getFiletrailer()
{
return ContentBoundary + "\r\n" + CONTENT_DISP + "\"UPL\"" + "\r\n\r\n"
+ "Submit" +
"\r\n" + EndingBoundary + "\r\n";
}
/// <summary>
/// Reads in the file a chunck at a time then sends it to the
/// output stream.
/// </summary>
/// <param name="io">The io stream to write the file to.</param>
/// <param name="aFilename">The name of the file to transfer.</param>
public void writeFile(System.IO.Stream io, string aFilename)
{
FileStream readIn = new FileStream(aFilename, FileMode.Open,
FileAccess.Read);
readIn.Seek(0, SeekOrigin.Begin); // move to the start of the file
byte[] fileData = new byte[BufferSize];
int bytes;
while( (bytes = readIn.Read(fileData,0, BufferSize)) > 0 )
{
// read the file data and send a chunk at a time
io.Write(fileData,0,bytes);
}
readIn.Close();
}
}
}



"Paul Galvin" <anonymous@discussions.microsoft.com> wrote in message
news:9ed101c4977e$4d117640$a601280a@phx.gbl...
> Greetings,
>
> I would like to write a c# program to upload an attachment
> to a note.
>
> I've read what I can find that describes how to do this
> (including messages here on the board).
>
> My first effort is to use the WebClient object and its
> upload method. However, that's not working. I'm getting
> a response, 500 "Server error". The webclient is posting
> the file directly to the SRF. Can I use the webclient for
> this? The key difference between webclient and using a
> web browser is that the fields are added to the query
> string rather than a "posted" field.
>
> TIA and regards,



Re: SDK to upload attachments by Chris

Chris
Sun Sep 12 22:04:09 CDT 2004

Sorry - Just re read your post, and realised that you are trying to upload
an attachment to a note. Regardless, the code I've posted should work, as
it is based on a the attachment ID. Let me know if you have problems, and
I'll see if I can help.

CHeers

Chris

"Chris Ericoli" <cericoliNOspm@removethisfamill.com.au> wrote in message
news:un%23bV0TmEHA.3536@TK2MSFTNGP12.phx.gbl...
> Hi Paul,
>
> I have done this, although in VB. I used an adapted version of the
> webclient object, available from:
>
> http://www.c-sharpcorner.com/Code/2003/May/DotNetBugs.asp
>
> Getting a file to attach to a CRM email was probably one of the most
> frustrating and time consuming things I have ever done, and the result is
a
> culmination of numerous attempts at resolution, and therefore there is
> probably some redundancy as a result trying different approaches.
>
> I'm sure by now you know how to use the SDK to create the email, and
> subsequently the attachment. I am also sure that you have realised that
the
> emailattachment object returns the ID for the attachment, but does not
allow
> you to actually specify a file for upload.
>
> The script I wrote creates the email, sets the recipients, sets the
sender,
> inserts the body and saves the email. After which it creates a new
> attachment and associates it with the email. Finally it uploads a
> particular file (for my purposes I knew the filename, as it had been
> previously created) to the attachment. Finally it uses some client side
> script in order to launch a new browser window to display the created
email
> object, with the file already attached. I did not want to automate the
> sendign of the email, as it does not give the user an opportunity to check
> it over or attach further files.
>
> The following code assumes that you have downloaded the modified web
client
> object (norvanco.http.MultipartForm).
>
> So...
>
> Once you have created the email and obtained the ID for the attachment,
this
> is what you need to do:
>
> Public Sub UploadAttachment(ByVal userID As String, ByVal merchantID
As
> String, ByVal filename As String, ByVal attachID As String, ByVal emailID
As
> String)
>
> Dim _attachService As String
> Dim _advWC As New norvanco.http.MultipartForm(_attachService)
> Dim _advWCFields As New Specialized.NameValueCollection
> Dim _reqCookies As String
>
> _attachService = "http://" & AppSettings("crmServer") & "/" &
> AppSettings("crmServicesDir") & "/ActivityAttachmentUpload.srf"
>
> 'Add the post data
> 'From memory the 1001 value for AttachmentType comes from the CRM
> Enumerations - but you may want to check
> _advWCFields.Add("AttachmentType", 1001)
> _advWCFields.Add("AttachmentId", attachID)
> _advWCFields.Add("UserId", userID)
> _advWCFields.Add("MerchantId", merchantID)
>
> 'The ErrorURL and SuccessURL can be anything. They are used in
the
> CRM Web Client to direct a user to a page
> 'indicating the success/failure of the file upload - Obviously
with
> the webclient object, they are not relevant
> _advWCFields.Add("ErrorURL",
> "http://localhost/custom/quotemgmt/test1.aspx")
> _advWCFields.Add("SuccessURL",
> "http://localhost/custom/quotemgmt/test2.aspx")
>
> 'Set the post data fields in the modified web client
> _advWC.setFields(_advWCFields)
>
> 'Set the protocol - although not sure if this is necessary
> _advWC.TransferHttpVersion = New System.Version("1.0")
>
> 'Set the attachment type - in my usage, i know that it is going to
> be an html file attachment
> _advWC.FileContentType = "text/html"
>
> 'You need to transfer the current request's cookie string through
to
> the request made by the modified webclient
>
> _reqCookies = Page.Request.Headers.Get("Cookie") '(conversely you
> could use http.context.current.request)
>
> 'The sendFile method does not return a value indicating success -
so
> you can either rely on a try/catch statement or modify accordingly
> _advWC.sendFile(filename,
> System.Net.CredentialCache.DefaultCredentials, _reqCookies)
>
> 'Open the email in a new window for the client
>
> Dim _sb As New Text.StringBuilder
> Dim _emailURL As String = "http://" & AppSettings("crmServer") &
> "/Activities/Email/edit.aspx?id=" & emailID
>
> _sb.Append(vbCrLf + "<script>")
> _sb.Append(vbCrLf + "var EmailWin = window.open('" & _emailURL &
"',
> 'email_win', 'toolbar=no, status=yes, location=no, menubar=no, top=50,
> left=50, height=533, width=694', '');")
> _sb.Append(vbCrLf + "</script>")
>
> Page.RegisterClientScriptBlock("OpenEmail", _sb.ToString)
>
> End Sub
>
> I've just checked the site for the Advanced WebClient, and there does not
> appear to be any restriction on reposting the base code, so here is the
code
> including the modifications I made. You may want to check the original
> against this to find my modifications.
>
> If you have any questions, feel free to reply, and I'll see what I can do.
>
> Cheers
>
> Chris
>
>
>
> using System;
> using System.Net;
> using System.Text;
> using System.IO;
> using System.Collections;
>
> namespace norvanco.http
> {
> /// <summary>
> /// Allow the transfer of data files using the W3C's specification
> /// for HTTP multipart form data. Microsoft's version has a bug
> /// where it does not format the ending boundary correctly.
> /// Written by: gregoryp@norvanco.com
> /// </summary>
> public class MultipartForm
> {
> /// <summary>
> /// Holds any form fields and values that you
> /// wish to transfer with your data.
> /// </summary>
> private System.Collections.Specialized.NameValueCollection
coFormFields;
> /// <summary>
> /// Used mainly to avoid passing parameters to other routines.
> /// Could have been local to sendFile().
> /// </summary>
> protected HttpWebRequest coRequest;
> /// <summary>
> /// Used if we are testing and want to output the raw
> /// request, minus http headers, out to a file.
> /// </summary>
> System.IO.Stream coFileStream;
> /// <summary>
> /// Difined to build the form field data that is being
> /// passed along with the request.
> /// </summary>
> static string CONTENT_DISP = "Content-Disposition: form-data; name=";
> /// <summary>
> /// Allows you to specify the specific version of HTTP to use for
> uploads.
> /// The dot NET stuff currently does not allow you to remove the
> continue-100 header
> /// from 1.1 and 1.0 currently has a bug in it where it adds the
> continue-100. MS
> /// has sent a patch to remove the continue-100 in HTTP 1.0.
> /// </summary>
> public Version TransferHttpVersion
> {get{return coHttpVersion;}set{coHttpVersion=value;}}
> Version coHttpVersion;
>
> /// <summary>
> /// Used to change the content type of the file being sent.
> /// Currently defaults to: text/xml. Other options are
> /// text/plain or binary
> /// </summary>
>
>
> public string FileContentType
> {get{return coFileContentType;}set{coFileContentType=value;}}
> string coFileContentType;
>
> /// <summary>
> /// Initialize our class for use to send data files.
> /// </summary>
> /// <param name="url">The web address of the recipient of the data
> transfer.</param>
> public MultipartForm(string url)
> {
> URL = url;
> coFormFields = new
> System.Collections.Specialized.NameValueCollection();
> ResponseText = new StringBuilder();
> BufferSize = 1024 * 10;
> BeginBoundary = "---------------------------7d419e378304a0";
> TransferHttpVersion = HttpVersion.Version10;
> FileContentType = "text/html";
> }
> //---------- BEGIN PROPERTIES SECTION ----------
> string _BeginBoundary;
> /// <summary>
> /// The string that defines the begining boundary of
> /// our multipart transfer as defined in the w3c specs.
> /// This method also sets the Content and Ending
> /// boundaries as defined by the w3c specs.
> /// </summary>
> public string BeginBoundary
> {
> get{return _BeginBoundary;}
> set
> {
> _BeginBoundary =value;
> ContentBoundary = "--" + BeginBoundary;
> EndingBoundary = ContentBoundary + "--";
> }
> }
> /// <summary>
> /// The string that defines the content boundary of
> /// our multipart transfer as defined in the w3c specs.
> /// </summary>
> protected string ContentBoundary
> {get{return _ContentBoundary;}set{_ContentBoundary=value;}}
> string _ContentBoundary;
> /// <summary>
> /// The string that defines the ending boundary of
> /// our multipart transfer as defined in the w3c specs.
> /// </summary>
> protected string EndingBoundary
> {get{return _EndingBoundary;}set{_EndingBoundary=value;}}
> string _EndingBoundary;
> /// <summary>
> /// The data returned to us after the transfer is completed.
> /// </summary>
> public StringBuilder ResponseText
> {get{return _ResponseText;}set{_ResponseText=value;}}
> StringBuilder _ResponseText;
> /// <summary>
> /// The web address of the recipient of the transfer.
> /// </summary>
> public string URL
> {get{return _URL;}set{_URL = value;}}
> string _URL;
> /// <summary>
> /// Allows us to determine the size of the buffer used
> /// to send a piece of the file at a time out the IO
> /// stream. Defaults to 1024 * 10.
> /// </summary>
> public int BufferSize
> {get{return _BufferSize;}set{_BufferSize = value;}}
> int _BufferSize;
> //---------- END PROPERTIES SECTION ----------
> /// <summary>
> /// Used to signal we want the output to go to a
> /// text file verses being transfered to a URL.
> /// </summary>
> /// <param name="path"></param>
> public void setFilename(string path)
> {
> coFileStream = new
> System.IO.FileStream(path,FileMode.Create,FileAccess.Write);
> }
> /// <summary>
> /// Allows you to add some additional field data to be
> /// sent along with the transfer. This is usually used
> /// for things like userid and password to validate the
> /// transfer.
> /// </summary>
> /// <param name="key">The form field name</param>
> /// <param name="str">The form field value</param>
>
> public void
setFields(System.Collections.Specialized.NameValueCollection
> nv)
> {
> coFormFields = nv;
> }
> public void setField(string key, string str)
> {
> coFormFields[key] = str;
> }
> /// <summary>
> /// Determines if we have a file stream set, and returns either
> /// the HttpWebRequest stream of the file.
> /// </summary>
> /// <returns></returns>
> public virtual System.IO.Stream getStream()
> {
> System.IO.Stream io;
> if( null == coFileStream )
> io = coRequest.GetRequestStream();
> else
> io = coFileStream;
> return io;
> }
>
> public virtual void getResponse()
> {
> if( null == coFileStream )
> {
> System.IO.Stream io;
> WebResponse oResponse;
> try
> {
> oResponse = coRequest.GetResponse();
> }
> catch(WebException web )
> {
> oResponse = web.Response;
> }
> if( null != oResponse )
> {
> io = oResponse.GetResponseStream();
> StreamReader sr = new StreamReader(io);
> string str;
> ResponseText.Length = 0;
> while( (str = sr.ReadLine()) != null )
> ResponseText.Append(str);
> oResponse.Close();
> }
> else
> throw new Exception("MultipartForm: Error retrieving server
> response");
> }
> }
> /// <summary>
> /// Here we actually make the request to the web server and
> /// retrieve it's response into a text buffer.
> /// </summary>
>
> /// <summary>
> /// Transmits a file to the web server stated in the
> /// URL property. You may call this several times and it
> /// will use the values previously set for fields and URL.
> /// </summary>
> /// <param name="aFilename">The full path of file being
> transfered.</param>
> public void sendFile(string aFilename, ICredentials NetCreds, string
> cks)
> {
> // The live of this object is only good during
> // this function. Used mainly to avoid passing
> // around parameters to other functions.
>
> coRequest = (HttpWebRequest) WebRequest.Create(URL);
> // Set use HTTP 1.0 or 1.1.
> coRequest.ProtocolVersion = System.Net.HttpVersion.Version10;
> coRequest.Credentials = NetCreds;
> coRequest.Method = "POST";
> coRequest.ContentType = "multipart/form-data; boundary=" +
> BeginBoundary;
> coRequest.Headers.Add("Cache-Control","no-cache");
> coRequest.KeepAlive = true;
> coRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg,
image/pjpeg,
> application/x-shockwave-flash, application/vnd.ms-excel,
> application/vnd.ms-powerpoint, application/msword, */*";
> // coRequest.Referer = "http://localhost/custom/quotemgmt/test.aspx";
> coRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT
5.1;
> .NET CLR 1.1.4322)";
> coRequest.Headers.Add("Accept-Encoding","gzip, deflate");
> coRequest.Headers.Add("Accept-Language","en-au");
> coRequest.AllowAutoRedirect = false;
>
> coRequest.CookieContainer = new CookieContainer();
>
> coRequest.Headers.Add("Cookie:" + cks);
>
> string strFields = getFormfields();
> string strFileHdr = getFileheader(aFilename);
> string strFileTlr = getFiletrailer();
>
> FileInfo info = new FileInfo(aFilename);
> coRequest.ContentLength = strFields.Length +
> strFileHdr.Length +
> strFileTlr.Length +
> info.Length;
> System.IO.Stream io;
> io = getStream();
> writeString(io,strFields);
> writeString(io,strFileHdr);
> this.writeFile(io, aFilename);
> writeString(io,strFileTlr);
>
> getResponse();
> io.Close();
> // End the life time of this request object.
> coRequest = null;
>
>
> }
>
>
> /// <summary>
> /// Mainly used to turn the string into a byte buffer and then
> /// write it to our IO stream.
> /// </summary>
> /// <param name="io">The io stream for output.</param>
> /// <param name="str">The data to write.</param>
> public void writeString(System.IO.Stream io, string str)
> {
> byte[] PostData = System.Text.Encoding.ASCII.GetBytes(str);
> io.Write(PostData,0,PostData.Length);
> }
> /// <summary>
> /// Builds the proper format of the multipart data that
> /// contains the form fields and their respective values.
> /// </summary>
> /// <returns>The data to send in the multipart upload.</returns>
> public string getFormfields()
> {
> string str="";
>
> int ct = coFormFields.Count - 1;
> for (int i = 0; i<=ct ; i++)
> {
> str += ContentBoundary + "\r\n" +
> CONTENT_DISP + '"' + coFormFields.Keys[i] + "\"\r\n\r\n" +
> coFormFields.Get(i) + "\r\n";
> }
> return str;
> }
> /// <summary>
> /// Returns the proper content information for the
> /// file we are sending.
> /// </summary>
> /// <remarks>
> /// Hits Patel reported a bug when used with ActiveFile.
> /// Added semicolon after sendfile to resolve that issue.
> /// Tested for compatibility with IIS 5.0 and Java.
> /// </remarks>
> /// <param name="aFilename"></param>
> /// <returns></returns>
> public string getFileheader(string aFilename)
> {
> return ContentBoundary + "\r\n" +
> CONTENT_DISP +
> "\"userFile\"; filename=\"" +
> (aFilename) + "\"\r\n" +
> "Content-type: " + FileContentType + "\r\n\r\n";
> }
> /// <summary>
> /// Creates the proper ending boundary for the multipart upload.
> /// </summary>
> /// <returns>The ending boundary.</returns>
> public string getFiletrailer()
> {
> return ContentBoundary + "\r\n" + CONTENT_DISP + "\"UPL\"" + "\r\n\r\n"
> + "Submit" +
> "\r\n" + EndingBoundary + "\r\n";
> }
> /// <summary>
> /// Reads in the file a chunck at a time then sends it to the
> /// output stream.
> /// </summary>
> /// <param name="io">The io stream to write the file to.</param>
> /// <param name="aFilename">The name of the file to transfer.</param>
> public void writeFile(System.IO.Stream io, string aFilename)
> {
> FileStream readIn = new FileStream(aFilename, FileMode.Open,
> FileAccess.Read);
> readIn.Seek(0, SeekOrigin.Begin); // move to the start of the file
> byte[] fileData = new byte[BufferSize];
> int bytes;
> while( (bytes = readIn.Read(fileData,0, BufferSize)) > 0 )
> {
> // read the file data and send a chunk at a time
> io.Write(fileData,0,bytes);
> }
> readIn.Close();
> }
> }
> }
>
>
>
> "Paul Galvin" <anonymous@discussions.microsoft.com> wrote in message
> news:9ed101c4977e$4d117640$a601280a@phx.gbl...
> > Greetings,
> >
> > I would like to write a c# program to upload an attachment
> > to a note.
> >
> > I've read what I can find that describes how to do this
> > (including messages here on the board).
> >
> > My first effort is to use the WebClient object and its
> > upload method. However, that's not working. I'm getting
> > a response, 500 "Server error". The webclient is posting
> > the file directly to the SRF. Can I use the webclient for
> > this? The key difference between webclient and using a
> > web browser is that the fields are added to the query
> > string rather than a "posted" field.
> >
> > TIA and regards,
>
>



Re: SDK to upload attachments by fredcaldera

fredcaldera
Mon Sep 27 12:17:02 CDT 2004

Hi Chris,
I read you previous reply and wonder if the following is possible: Can I
attach a file to an email, using the ActivityAttachmentUpload.srf? I have
been trying to do it but no success so far. I followed your initial remarks
but nothing happens. It seems to me that because I do not know which
parameters are required (filename, size and content type), i cannot go
forward... do you have any idea? I want to avoid using other sw such as
modified web client..
Thanks

"Chris Ericoli" wrote:

> Sorry - Just re read your post, and realised that you are trying to upload
> an attachment to a note. Regardless, the code I've posted should work, as
> it is based on a the attachment ID. Let me know if you have problems, and
> I'll see if I can help.
>
> CHeers
>
> Chris
>
> "Chris Ericoli" <cericoliNOspm@removethisfamill.com.au> wrote in message
> news:un%23bV0TmEHA.3536@TK2MSFTNGP12.phx.gbl...
> > Hi Paul,
> >
> > I have done this, although in VB. I used an adapted version of the
> > webclient object, available from:
> >
> > http://www.c-sharpcorner.com/Code/2003/May/DotNetBugs.asp
> >
> > Getting a file to attach to a CRM email was probably one of the most
> > frustrating and time consuming things I have ever done, and the result is
> a
> > culmination of numerous attempts at resolution, and therefore there is
> > probably some redundancy as a result trying different approaches.
> >
> > I'm sure by now you know how to use the SDK to create the email, and
> > subsequently the attachment. I am also sure that you have realised that
> the
> > emailattachment object returns the ID for the attachment, but does not
> allow
> > you to actually specify a file for upload.
> >
> > The script I wrote creates the email, sets the recipients, sets the
> sender,
> > inserts the body and saves the email. After which it creates a new
> > attachment and associates it with the email. Finally it uploads a
> > particular file (for my purposes I knew the filename, as it had been
> > previously created) to the attachment. Finally it uses some client side
> > script in order to launch a new browser window to display the created
> email
> > object, with the file already attached. I did not want to automate the
> > sendign of the email, as it does not give the user an opportunity to check
> > it over or attach further files.
> >
> > The following code assumes that you have downloaded the modified web
> client
> > object (norvanco.http.MultipartForm).
> >
> > So...
> >
> > Once you have created the email and obtained the ID for the attachment,
> this
> > is what you need to do:
> >
> > Public Sub UploadAttachment(ByVal userID As String, ByVal merchantID
> As
> > String, ByVal filename As String, ByVal attachID As String, ByVal emailID
> As
> > String)
> >
> > Dim _attachService As String
> > Dim _advWC As New norvanco.http.MultipartForm(_attachService)
> > Dim _advWCFields As New Specialized.NameValueCollection
> > Dim _reqCookies As String
> >
> > _attachService = "http://" & AppSettings("crmServer") & "/" &
> > AppSettings("crmServicesDir") & "/ActivityAttachmentUpload.srf"
> >
> > 'Add the post data
> > 'From memory the 1001 value for AttachmentType comes from the CRM
> > Enumerations - but you may want to check
> > _advWCFields.Add("AttachmentType", 1001)
> > _advWCFields.Add("AttachmentId", attachID)
> > _advWCFields.Add("UserId", userID)
> > _advWCFields.Add("MerchantId", merchantID)
> >
> > 'The ErrorURL and SuccessURL can be anything. They are used in
> the
> > CRM Web Client to direct a user to a page
> > 'indicating the success/failure of the file upload - Obviously
> with
> > the webclient object, they are not relevant
> > _advWCFields.Add("ErrorURL",
> > "http://localhost/custom/quotemgmt/test1.aspx")
> > _advWCFields.Add("SuccessURL",
> > "http://localhost/custom/quotemgmt/test2.aspx")
> >
> > 'Set the post data fields in the modified web client
> > _advWC.setFields(_advWCFields)
> >
> > 'Set the protocol - although not sure if this is necessary
> > _advWC.TransferHttpVersion = New System.Version("1.0")
> >
> > 'Set the attachment type - in my usage, i know that it is going to
> > be an html file attachment
> > _advWC.FileContentType = "text/html"
> >
> > 'You need to transfer the current request's cookie string through
> to
> > the request made by the modified webclient
> >
> > _reqCookies = Page.Request.Headers.Get("Cookie") '(conversely you
> > could use http.context.current.request)
> >
> > 'The sendFile method does not return a value indicating success -
> so
> > you can either rely on a try/catch statement or modify accordingly
> > _advWC.sendFile(filename,
> > System.Net.CredentialCache.DefaultCredentials, _reqCookies)
> >
> > 'Open the email in a new window for the client
> >
> > Dim _sb As New Text.StringBuilder
> > Dim _emailURL As String = "http://" & AppSettings("crmServer") &
> > "/Activities/Email/edit.aspx?id=" & emailID
> >
> > _sb.Append(vbCrLf + "<script>")
> > _sb.Append(vbCrLf + "var EmailWin = window.open('" & _emailURL &
> "',
> > 'email_win', 'toolbar=no, status=yes, location=no, menubar=no, top=50,
> > left=50, height=533, width=694', '');")
> > _sb.Append(vbCrLf + "</script>")
> >
> > Page.RegisterClientScriptBlock("OpenEmail", _sb.ToString)
> >
> > End Sub
> >
> > I've just checked the site for the Advanced WebClient, and there does not
> > appear to be any restriction on reposting the base code, so here is the
> code
> > including the modifications I made. You may want to check the original
> > against this to find my modifications.
> >
> > If you have any questions, feel free to reply, and I'll see what I can do.
> >
> > Cheers
> >
> > Chris
> >
> >
> >
> > using System;
> > using System.Net;
> > using System.Text;
> > using System.IO;
> > using System.Collections;
> >
> > namespace norvanco.http
> > {
> > /// <summary>
> > /// Allow the transfer of data files using the W3C's specification
> > /// for HTTP multipart form data. Microsoft's version has a bug
> > /// where it does not format the ending boundary correctly.
> > /// Written by: gregoryp@norvanco.com
> > /// </summary>
> > public class MultipartForm
> > {
> > /// <summary>
> > /// Holds any form fields and values that you
> > /// wish to transfer with your data.
> > /// </summary>
> > private System.Collections.Specialized.NameValueCollection
> coFormFields;
> > /// <summary>
> > /// Used mainly to avoid passing parameters to other routines.
> > /// Could have been local to sendFile().
> > /// </summary>
> > protected HttpWebRequest coRequest;
> > /// <summary>
> > /// Used if we are testing and want to output the raw
> > /// request, minus http headers, out to a file.
> > /// </summary>
> > System.IO.Stream coFileStream;
> > /// <summary>
> > /// Difined to build the form field data that is being
> > /// passed along with the request.
> > /// </summary>
> > static string CONTENT_DISP = "Content-Disposition: form-data; name=";
> > /// <summary>
> > /// Allows you to specify the specific version of HTTP to use for
> > uploads.
> > /// The dot NET stuff currently does not allow you to remove the
> > continue-100 header
> > /// from 1.1 and 1.0 currently has a bug in it where it adds the
> > continue-100. MS
> > /// has sent a patch to remove the continue-100 in HTTP 1.0.
> > /// </summary>
> > public Version TransferHttpVersion
> > {get{return coHttpVersion;}set{coHttpVersion=value;}}
> > Version coHttpVersion;
> >
> > /// <summary>
> > /// Used to change the content type of the file being sent.
> > /// Currently defaults to: text/xml. Other options are
> > /// text/plain or binary
> > /// </summary>
> >
> >
> > public string FileContentType
> > {get{return coFileContentType;}set{coFileContentType=value;}}
> > string coFileContentType;
> >
> > /// <summary>
> > /// Initialize our class for use to send data files.
> > /// </summary>
> > /// <param name="url">The web address of the recipient of the data
> > transfer.</param>
> > public MultipartForm(string url)
> > {
> > URL = url;
> > coFormFields = new
> > System.Collections.Specialized.NameValueCollection();
> > ResponseText = new StringBuilder();
> > BufferSize = 1024 * 10;
> > BeginBoundary = "---------------------------7d419e378304a0";
> > TransferHttpVersion = HttpVersion.Version10;
> > FileContentType = "text/html";
> > }
> > //---------- BEGIN PROPERTIES SECTION ----------
> > string _BeginBoundary;
> > /// <summary>
> > /// The string that defines the begining boundary of
> > /// our multipart transfer as defined in the w3c specs.
> > /// This method also sets the Content and Ending
> > /// boundaries as defined by the w3c specs.
> > /// </summary>
> > public string BeginBoundary
> > {
> > get{return _BeginBoundary;}
> > set
> > {
> > _BeginBoundary =value;
> > ContentBoundary = "--" + BeginBoundary;
> > EndingBoundary = ContentBoundary + "--";
> > }
> > }
> > /// <summary>
> > /// The string that defines the content boundary of
> > /// our multipart transfer as defined in the w3c specs.
> > /// </summary>
> > protected string ContentBoundary
> > {get{return _ContentBoundary;}set{_ContentBoundary=value;}}
> > string _ContentBoundary;
> > /// <summary>
> > /// The string that defines the ending boundary of
> > /// our multipart transfer as defined in the w3c specs.
> > /// </summary>
> > protected string EndingBoundary
> > {get{return _EndingBoundary;}set{_EndingBoundary=value;}}
> > string _EndingBoundary;
> > /// <summary>
> > /// The data returned to us after the transfer is completed.
> > /// </summary>
> > public StringBuilder ResponseText
> > {get{return _ResponseText;}set{_ResponseText=value;}}
> > StringBuilder _ResponseText;
> > /// <summary>
> > /// The web address of the recipient of the transfer.
> > /// </summary>
> > public string URL
> > {get{return _URL;}set{_URL = value;}}
> > string _URL;
> > /// <summary>
> > /// Allows us to determine the size of the buffer used
> > /// to send a piece of the file at a time out the IO
> > /// stream. Defaults to 1024 * 10.
> > /// </summary>
> > public int BufferSize
> > {get{return _BufferSize;}set{_BufferSize = value;}}
> > int _BufferSize;
> > //---------- END PROPERTIES SECTION ----------
> > /// <summary>
> > /// Used to signal we want the output to go to a
> > /// text file verses being transfered to a URL.
> > /// </summary>
> > /// <param name="path"></param>
> > public void setFilename(string path)
> > {
> > coFileStream = new
> > System.IO.FileStream(path,FileMode.Create,FileAccess.Write);
> > }
> > /// <summary>
> > /// Allows you to add some additional field data to be
> > /// sent along with the transfer. This is usually used
> > /// for things like userid and password to validate the
> > /// transfer.
> > /// </summary>
> > /// <param name="key">The form field name</param>
> > /// <param name="str">The form field value</param>
> >
> > public void
> setFields(System.Collections.Specialized.NameValueCollection
> > nv)
> > {
> > coFormFields = nv;
> > }
> > public void setField(string key, string str)
> > {
> > coFormFields[key] = str;
> > }
> > /// <summary>
> > /// Determines if we have a file stream set, and returns either
> > /// the HttpWebRequest stream of the file.
> > /// </summary>
> > /// <returns></returns>
> > public virtual System.IO.Stream getStream()
> > {
> > System.IO.Stream io;
> > if( null == coFileStream )
> > io = coRequest.GetRequestStream();
> > else
> > io = coFileStream;
> > return io;
> > }
> >
> > public virtual void getResponse()
> > {
> > if( null == coFileStream )
> > {
> > System.IO.Stream io;
> > WebResponse oResponse;
> > try
> > {
> > oResponse = coRequest.GetResponse();
> > }
> > catch(WebException web )
> > {
> > oResponse = web.Response;
> > }
> > if( null != oResponse )
> > {
> > io = oResponse.GetResponseStream();
> > StreamReader sr = new StreamReader(io);
> > string str;
> > ResponseText.Length = 0;
> > while( (str = sr.ReadLine()) != null )
> > ResponseText.Append(str);
> > oResponse.Close();
> > }
> > else
> > throw new Exception("MultipartForm: Error retrieving server
> > response");
> > }
> > }
> > /// <summary>
> > /// Here we actually make the request to the web server and
> > /// retrieve it's response into a text buffer.
> > /// </summary>
> >
> > /// <summary>
> > /// Transmits a file to the web server stated in the
> > /// URL property. You may call this several times and it
> > /// will use the values previously set for fields and URL.
> > /// </summary>
> > /// <param name="aFilename">The full path of file being
> > transfered.</param>
> > public void sendFile(string aFilename, ICredentials NetCreds, string
> > cks)
> > {
> > // The live of this object is only good during
> > // this function. Used mainly to avoid passing
> > // around parameters to other functions.
> >
> > coRequest = (HttpWebRequest) WebRequest.Create(URL);
> > // Set use HTTP 1.0 or 1.1.
> > coRequest.ProtocolVersion = System.Net.HttpVersion.Version10;
> > coRequest.Credentials = NetCreds;
> > coRequest.Method = "POST";
> > coRequest.ContentType = "multipart/form-data; boundary=" +
> > BeginBoundary;
> > coRequest.Headers.Add("Cache-Control","no-cache");
> > coRequest.KeepAlive = true;
> > coRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg,
> image/pjpeg,
> > application/x-shockwave-flash, application/vnd.ms-excel,
> > application/vnd.ms-powerpoint, application/msword, */*";
> > // coRequest.Referer = "http://localhost/custom/quotemgmt/test.aspx";
> > coRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT
> 5.1;
> > .NET CLR 1.1.4322)";
> > coRequest.Headers.Add("Accept-Encoding","gzip, deflate");
> > coRequest.Headers.Add("Accept-Language","en-au");
> > coRequest.AllowAutoRedirect = false;
> >
> > coRequest.CookieContainer = new CookieContainer();
> >
> > coRequest.Headers.Add("Cookie:" + cks);
> >
> > string strFields = getFormfields();
> > string strFileHdr = getFileheader(aFilename);
> > string strFileTlr = getFiletrailer();
> >
> > FileInfo info = new FileInfo(aFilename);
> > coRequest.ContentLength = strFields.Length +
> > strFileHdr.Length +
> > strFileTlr.Length +
> > info.Length;
> > System.IO.Stream io;
> > io = getStream();
> > writeString(io,strFields);
> > writeString(io,strFileHdr);
> > this.writeFile(io, aFilename);
> > writeString(io,strFileTlr);
> >
> > getResponse();
> > io.Close();
> > // End the life time of this request object.
> > coRequest = null;
> >
> >
> > }
> >
> >
> > /// <summary>
> > /// Mainly used to turn the string into a byte buffer and then
> > /// write it to our IO stream.
> > /// </summary>
> > /// <param name="io">The io stream for output.</param>
> > /// <param name="str">The data to write.</param>
> > public void writeString(System.IO.Stream io, string str)
> > {
> > byte[] PostData = System.Text.Encoding.ASCII.GetBytes(str);
> > io.Write(PostData,0,PostData.Length);
> > }
> > /// <summary>
> > /// Builds the proper format of the multipart data that
> > /// contains the form fields and their respective values.
> > /// </summary>
> > /// <returns>The data to send in the multipart upload.</returns>
> > public string getFormfields()
> > {
> > string str="";
> >
> > int ct = coFormFields.Count - 1;
> > for (int i = 0; i<=ct ; i++)
> > {
> > str += ContentBoundary + "\r\n" +
> > CONTENT_DISP + '"' + coFormFields.Keys[i] + "\"\r\n\r\n" +
> > coFormFields.Get(i) + "\r\n";
> > }
> > return str;
> > }
> > /// <summary>
> > /// Returns the proper content information for the
> > /// file we are sending.
> > /// </summary>
> > /// <remarks>
> > /// Hits Patel reported a bug when used with ActiveFile.
> > /// Added semicolon after sendfile to resolve that issue.
> > /// Tested for compatibility with IIS 5.0 and Java.
> > /// </remarks>
> > /// <param name="aFilename"></param>
> > /// <returns></returns>
> > public string getFileheader(string aFilename)
> > {
> > return ContentBoundary + "\r\n" +
> > CONTENT_DISP +
> > "\"userFile\"; filename=\"" +
> > (aFilename) + "\"\r\n" +
> > "Content-type: " + FileContentType + "\r\n\r\n";
> > }
> > /// <summary>
> > /// Creates the proper ending boundary for the multipart upload.
> > /// </summary>
> > /// <returns>The ending boundary.</returns>
> > public string getFiletrailer()
> > {
> > return ContentBoundary + "\r\n" + CONTENT_DISP + "\"UPL\"" + "\r\n\r\n"
> > + "Submit" +
> > "\r\n" + EndingBoundary + "\r\n";
> > }
> > /// <summary>
> > /// Reads in the file a chunck at a time then sends it to the
> > /// output stream.
> > /// </summary>
> > /// <param name="io">The io stream to write the file to.</param>
> > /// <param name="aFilename">The name of the file to transfer.</param>
> > public void writeFile(System.IO.Stream io, string aFilename)
> > {
> > FileStream readIn = new FileStream(aFilename, FileMode.Open,
> > FileAccess.Read);
> > readIn.Seek(0, SeekOrigin.Begin); // move to the start of the file
> > byte[] fileData = new byte[BufferSize];
> > int bytes;
> > while( (bytes = readIn.Read(fileData,0, BufferSize)) > 0 )
> > {
> > // read the file data and send a chunk at a time
> > io.Write(fileData,0,bytes);
> > }
> > readIn.Close();
> > }
> > }
> > }
> >
> >
> >
> > "Paul Galvin" <anonymous@discussions.microsoft.com> wrote in message
> > news:9ed101c4977e$4d117640$a601280a@phx.gbl...
> > > Greetings,
> > >
> > > I would like to write a c# program to upload an attachment
> > > to a note.
> > >
> > > I've read what I can find that describes how to do this
> > > (including messages here on the board).
> > >
> > > My first effort is to use the WebClient object and its
> > > upload method. However, that's not working. I'm getting
> > > a response, 500 "Server error". The webclient is posting
> > > the file directly to the SRF. Can I use the webclient for
> > > this? The key difference between webclient and using a
> > > web browser is that the fields are added to the query
> > > string rather than a "posted" field.
> > >
> > > TIA and regards,
> >
> >
>
>
>

Re: SDK to upload attachments by Seamus

Seamus
Thu Oct 14 14:03:05 CDT 2004

Chris we are trying to upload a form from our web site with attachments
directly into CRM have you created an app to do this , thanks

"Chris Ericoli" wrote:

> Sorry - Just re read your post, and realised that you are trying to upload
> an attachment to a note. Regardless, the code I've posted should work, as
> it is based on a the attachment ID. Let me know if you have problems, and
> I'll see if I can help.
>
> CHeers
>
> Chris
>
> "Chris Ericoli" <cericoliNOspm@removethisfamill.com.au> wrote in message
> news:un%23bV0TmEHA.3536@TK2MSFTNGP12.phx.gbl...
> > Hi Paul,
> >
> > I have done this, although in VB. I used an adapted version of the
> > webclient object, available from:
> >
> > http://www.c-sharpcorner.com/Code/2003/May/DotNetBugs.asp
> >
> > Getting a file to attach to a CRM email was probably one of the most
> > frustrating and time consuming things I have ever done, and the result is
> a
> > culmination of numerous attempts at resolution, and therefore there is
> > probably some redundancy as a result trying different approaches.
> >
> > I'm sure by now you know how to use the SDK to create the email, and
> > subsequently the attachment. I am also sure that you have realised that
> the
> > emailattachment object returns the ID for the attachment, but does not
> allow
> > you to actually specify a file for upload.
> >
> > The script I wrote creates the email, sets the recipients, sets the
> sender,
> > inserts the body and saves the email. After which it creates a new
> > attachment and associates it with the email. Finally it uploads a
> > particular file (for my purposes I knew the filename, as it had been
> > previously created) to the attachment. Finally it uses some client side
> > script in order to launch a new browser window to display the created
> email
> > object, with the file already attached. I did not want to automate the
> > sendign of the email, as it does not give the user an opportunity to check
> > it over or attach further files.
> >
> > The following code assumes that you have downloaded the modified web
> client
> > object (norvanco.http.MultipartForm).
> >
> > So...
> >
> > Once you have created the email and obtained the ID for the attachment,
> this
> > is what you need to do:
> >
> > Public Sub UploadAttachment(ByVal userID As String, ByVal merchantID
> As
> > String, ByVal filename As String, ByVal attachID As String, ByVal emailID
> As
> > String)
> >
> > Dim _attachService As String
> > Dim _advWC As New norvanco.http.MultipartForm(_attachService)
> > Dim _advWCFields As New Specialized.NameValueCollection
> > Dim _reqCookies As String
> >
> > _attachService = "http://" & AppSettings("crmServer") & "/" &
> > AppSettings("crmServicesDir") & "/ActivityAttachmentUpload.srf"
> >
> > 'Add the post data
> > 'From memory the 1001 value for AttachmentType comes from the CRM
> > Enumerations - but you may want to check
> > _advWCFields.Add("AttachmentType", 1001)
> > _advWCFields.Add("AttachmentId", attachID)
> > _advWCFields.Add("UserId", userID)
> > _advWCFields.Add("MerchantId", merchantID)
> >
> > 'The ErrorURL and SuccessURL can be anything. They are used in
> the
> > CRM Web Client to direct a user to a page
> > 'indicating the success/failure of the file upload - Obviously
> with
> > the webclient object, they are not relevant
> > _advWCFields.Add("ErrorURL",
> > "http://localhost/custom/quotemgmt/test1.aspx")
> > _advWCFields.Add("SuccessURL",
> > "http://localhost/custom/quotemgmt/test2.aspx")
> >
> > 'Set the post data fields in the modified web client
> > _advWC.setFields(_advWCFields)
> >
> > 'Set the protocol - although not sure if this is necessary
> > _advWC.TransferHttpVersion = New System.Version("1.0")
> >
> > 'Set the attachment type - in my usage, i know that it is going to
> > be an html file attachment
> > _advWC.FileContentType = "text/html"
> >
> > 'You need to transfer the current request's cookie string through
> to
> > the request made by the modified webclient
> >
> > _reqCookies = Page.Request.Headers.Get("Cookie") '(conversely you
> > could use http.context.current.request)
> >
> > 'The sendFile method does not return a value indicating success -
> so
> > you can either rely on a try/catch statement or modify accordingly
> > _advWC.sendFile(filename,
> > System.Net.CredentialCache.DefaultCredentials, _reqCookies)
> >
> > 'Open the email in a new window for the client
> >
> > Dim _sb As New Text.StringBuilder
> > Dim _emailURL As String = "http://" & AppSettings("crmServer") &
> > "/Activities/Email/edit.aspx?id=" & emailID
> >
> > _sb.Append(vbCrLf + "<script>")
> > _sb.Append