PDA

View Full Version : مشکل در Upload فایل با وب سرویس



Saeed_m_Farid
سه شنبه 12 خرداد 1388, 16:18 عصر
سلام
من یه وب سرویس (اجباراً VB.net 2003) دارم که قراره یه وب متد واسه آپلود فایل داشته باشه، موقع استفاده از متد موردنظر یا خطای
The remote server returned an error: (401) Unauthorized. می گیرم یا خطای زیر :
The remote server returned an error: (405) Method Not Allowed=========================================== ==============

کارهایی که انجام دادم :


یه VirtualDir تو سرور ایجاد کردم که هم تو IIS و هم واسه دایرکتوری فیزیکی تمام مجوزها رو Allow کردم (تو شکلهای ضمیمه 1و 2)
با توجه به اینکه آپلود فایل از طریق Http صورت می گیره، من یه WebMethod ساده به صورت زیر نوشتم :

<WebMethod()> Public Function Upload_File(ByVal SourcePath As String, _
ByVal ReqUri As String) As String
Try
Dim myWebClient As New WebClient
If (ReqUri.Length > 0) Then
myWebClient.OpenWrite(ReqUri, "PUT")
Dim responseArray As Byte() = myWebClient.UploadFile(ReqUri, "PUT", SourcePath)
Return System.Text.Encoding.ASCII.GetString(responseArray )
Else
Return "Error: Empty Upload Path!"
End If
Catch ex As Exception
Return "Error: Upload_File: " & ex.Message
End Try
End Function

تا اونجایی که من میدونم My.Computer.Network.UploadFile یه درخواست
multipart/form-data POST request توسط کامپوننت های یه web application میفرسته ولی من فقط وب سرویس دارم و از برنامه تحت وب خبری نیست! بنابراین نمیتونم از کامپوننت هایی مثل HttpHandler استفاده کنم. ولی با اینحال
UploadFile(ReqUri, "POST", SourcePath) رو هم امتحان کردم ولی بازم به مشکل خوردم ...
من دلفی کار هستم و زیاد وب کار نکردم، ولی به علت اینکه امکان استفاده از "کلاینت-سرور" ای غیر از SOAP و وب سرویس ها برای اینکار رو ندارم، نمیتونم از سوکت و Indy و ... استفاده کنم، ضمنا حجم زیادی کد واسه این وب سرویس نوشته شده که نمیشه به این راحتی همه رو به یه زبان دیگه کانورت کرد؛ به این دلایل فکر میکنم فقط باید از همین کلاسهای دات نت (اونم فقط 1.1 - بخاطر محدودیت نصب نسخه های بالاتر!) استفاده کنم.

البته این پست (http://barnamenevis.org/forum/showpost.php?p=515662&postcount=16)آقای علیرضا مداح روهم خوندم ولی زیاد با وب سرویس من سازگار نبود.
امیدوارم تو base کار اشتباه نداشته باشم و وقت اساتید محترم رو هم زیاد نگرفته باشم.
با تشکر.

Saeed_m_Farid
سه شنبه 12 خرداد 1388, 18:05 عصر
دوستان و اساتید گرامی:
لطفاً ایندفعه رو لطف کنید و یه وقتی واسه سوال بنده بذارید، واقعیتش من که هر موقع کاری یا سوالی از دوستان این سایت رو بتونم حل کنم، درنگ نمی کنم؛ ولی تو این مباحث که بی تجربه ام، خیلی کم تونستم از بچه ها جواب بگیرم، نمونش اینجاها :


نحوه پاس دادن پارامتر به اکتیوایکس (http://barnamenevis.org/forum/showthread.php?t=144331)
نحوه دانلود ActiveX‌ سفارشي در وب سايت؟ (http://barnamenevis.org/forum/showthread.php?t=143474)
نحوه احراز هويت كلاينت ها (Authentication) (http://barnamenevis.org/forum/showthread.php?t=145591)
مشکل در ارتباط با Oracle 9.2 (http://barnamenevis.org/forum/showthread.php?t=100002)

اکثراً هم لاینحل باقی موندن! مطمئنا من اولین کسی نبودم که تو کار با وب و دات نت مورد داشته و از MSDN یا فروم های دیگه نتونسته جواب بگیره ...
از دوستانی هم که از اینورا رد میشن و ایده ای به ذهنشون میرسه، میخوام لطف کنن و مطرح کنند.

با تشکر مجدد :تشویق:

Saeed_m_Farid
چهارشنبه 13 خرداد 1388, 10:53 صبح
مشکل من حل شد، واسه دوستانی که به مشکل مشابه برخورد می کنن باید بگم با توجه به سادگی این تابع
WebClient.UploadFile خبری از authenticate توش نیست و باید از طریق instance ای که از کلاس WebClient ساخته شده و Credentials مقداردهی بشه، یعنی بصورت زیر :


<WebMethod()> Public Function Upload_File_Test(ByVal SourcePath As String, _
ByVal UriPath As String) As String
Try
Dim myWebClient As New WebClient
If System.IO.File.Exists(UriPath) Then ' It isn't work, is any equal method in Network
Return UriPath & " > File Exist before ..."
Else
Dim myCred As NetworkCredential = New NetworkCredential("myUserName", "myPassword")
myWebClient.Credentials = myCred
Dim responseArray As Byte() = myWebClient.UploadFile(UriPath, "PUT", SourcePath)
Return System.Text.Encoding.ASCII.GetString(responseArray )
End If
Catch ex As Exception
Return "Error: Upload_File: " & ex.Message
End Try
End Function

فقط یه مشکلی که هست (همون خطی که جلوش کامنت قرمز گذاشتم) اینه که اگه قبلاً فایل تو مسیر موردنظر موجود باشه، overwrite میشه، اگه دوستان راه حلی برای FileExist تو یه Uri دارن لطف کنن.

ولی خداییش نذارین اینم بره زباله دان تاریخ! حداقل یه نظری بدین در مورد اینکه سوال پرسیدن بنده استاندارد نیست یا ...

با تشکر

Saeed_m_Farid
سه شنبه 09 تیر 1388, 14:13 عصر
سلام
یه چند تا کد در مورد بارگذاری و بارگیری! فایل با وب سرویس ها و معایبشون :


ارسال و دریافت فایل با وب سرویس از طریق بارگذاری محتویات فایل در بافرهای ورودی و خروجی :
[WebMethod]
public byte[] GetFile(string filename) {
BinaryReader binReader = new
BinaryReader(File.Open(Server.MapPath(filename), FileMode.Open,
FileAccess.Read));
binReader.BaseStream.Position = 0;
byte[] binFile =
binReader.ReadBytes(Convert.ToInt32(binReader.Base Stream.Length));
binReader.Close();
return binFile;
}

[WebMethod]
public void PutFile(byte[] buffer, string filename) {
BinaryWriter binWriter = new
BinaryWriter(File.Open(Server.MapPath(filename), FileMode.CreateNew,
FileAccess.ReadWrite));
binWriter.Write(buffer);
binWriter.Close();
}
پارامترهای ورودی و خروجی از نوع []byte هستند که اولاً نوع استانداردی در پلت فرمهای مختلف نیست و فقط تو کلاینتهای مبتنی بر دات نت قابل اعمال هستند (اگه جای دیگه هم بشه استفاده کرد؛ باید یه فایل راهنما همراه وب سرویس موردنظر در مورد نحوه استفاده اش رو هم تحویل بدیم!) و مهمتر اینکه حجم زیادی اطلاعات برای ارسال و دریافت بافرها رو شبکه حمل میشه، که آسیب شدیدی به پهنای باند میزنه و درصورت بروز اشکال در ارتباط شبکه همه چیز از دست میره!
ارسال و دریافت فایل با وب سرویس از طریق دایرکتوری مجازی و IIS :

<WebMethod()> Public Function Upload_File_To_Web(ByVal UriPath As String, _
ByVal SourcePath As String) As String
Try
Dim myWebClient As New WebClient
If (SourcePath.Length > 0) And (UriPath.Length > 0) Then
Dim sUser_Name As String = ConfigurationSettings.AppSettings("UploadUserName")
Dim sPass As String = ConfigurationSettings.AppSettings("UploadPassword")
Dim myCred As NetworkCredential = New NetworkCredential(sUser_Name, sPass)
myWebClient.Credentials = myCred
Dim responseArray As Byte() = myWebClient.UploadFile(UriPath, "PUT", SourcePath)
Return System.Text.Encoding.ASCII.GetString(responseArray )
Else
Return "Error: Upload URI > " + SourcePath
End If
Catch ex As Exception
Return "Error: Upload_File_To_Web: " & ex.Message
End Try
End Function

<WebMethod()> Public Function Download_File_From_Web(ByVal UriPath As String, _
ByVal SourcePath As String) As String
Try
Dim myWebClient As New WebClient
If (SourcePath.Length > 0) And (UriPath.Length > 0) Then
Dim sUser_Name As String = ConfigurationSettings.AppSettings("UploadUserName")
Dim sPass As String = ConfigurationSettings.AppSettings("UploadPassword")
Dim myCred As NetworkCredential = New NetworkCredential(sUser_Name, sPass)
myWebClient.Credentials = myCred

myWebClient.DownloadFile(UriPath, SourcePath)
Return "Download successful form > " & UriPath
Else
Return "Error: Download URI > " + UriPath
End If
Catch ex As Exception
Return "Error: Download_File_From_Web: " & ex.Message
End Try
End Function
اشکال این روش نیاز به دایرکتوری مجازی سمت کلاینت یا سرور و نصب IIS و مشکلات امنیتی و محدودیتهای سمت کلاینت (برای Upload) هست. که مطمئناً کار خنده داری هست که واسه آپلود IIS نصب کنیم.
راهی که شما پیشنهاد میکنید ...
شما که تو سایتتون عکس کاربر رو آپلود می کنید، اگه مثلاً کامپوننت FileUpload رو نداشته باشید چکار میکنید؟ یعنی چطور مسیر فایل مورد نظر کاربر رو تشخیص می دین و فقط با استفاده از مسیر فایل که از کاربر تو Open Dialog برای گرفتن مسیر فایل (مثلاً بارگذاری عکس کاربران) میتونید فایل رو آپلود کنید

خیلی کد مفید و بی نقصی هست و هیچ ایرادی نمیشه ازش گرفت. واقعاً ممنون که به تاپیک بنده توجه کردید.

چند تا هم اندرز از فلسفه کهن به ذهنم رسید گفتم با شما هم در میان بذارم :




اگر میخواهید پر باشید، خالی شوید.
اگر میخواهید چیزی را بدست آورید، ابتدا آنرا ببخشید.
فرزانگان کهن، سعی در آموزش مردم نداشتند. وقتی کسی فکر می کند که جوابها را می داند، راهنمایی کردنش سخت است.
تلاش برای اندوحتن دانش بیماری است. ابتدا باید بدانید که بیمارید، سپس برای سلامتی کوشش کنید.
فرزانه طبیب خود است. او خود را از تمام دانسته هایش رها نموده؛ پس درحقیقت یکپارچه و کامل است.

با این تفاسیر عیبی نداره که من بگم، دوستان من خیلی چیزها رو نمیدونم! با به اشتراک گذاشتن دانسته هاتون یکم خودتون رو سبک کنید.
یه پست قدیمی هم داشتم :

نيست ياري كننده اي كه مرا ياري كند؟
هَل مِن ناصِرِ يَنصُرَني؟
Can anyone help me?
Quelqu'un peut m'aider?
Chiunque può aiutarmi?
Bana yardim edan var mi?
Может ли кто мне помочь?

آثار هنري :

I : دوست آن باشد كه گيرد دست دوست، در پريشان حالي و درماندگي ...
II: غير أنه يود أن يكون صديقه وتصرف واليأس حين
It would like to be his friend, while distracted and helplessness :III
Она хотела бы, чтобы его друга, хотя отвлекаться и беспомощности :IV

متشکرم.

rezaei manesh
چهارشنبه 10 تیر 1388, 14:47 عصر
سلام
من در SourcePath نام مسیری رو مانند (E:\VS2005\HomePrj\BongahPrgV2\images\1.jpeg) و در UriPath نام سایت و مسیری که باید فایل درش درج شود رو مانند
(http://www.amlak66.com/usrpic/img/1.jpeg)
وارد کردم در یوز و پسورد هم یوزر و پسورد ftp رو وارد کردم اما خطای 501 به من داد؟!
مشکل از کجاست آیا آدرس سایت رو باید با آدرس ftp بدم؟

Saeed_m_Farid
جمعه 12 تیر 1388, 15:31 عصر
سلام
من در SourcePath نام مسیری رو مانند (E:\VS2005\HomePrj\BongahPrgV2\images\1.jpeg) و در UriPath نام سایت و مسیری که باید فایل درش درج شود رو مانند
(http://www.amlak66.com/usrpic/img/1.jpeg)
وارد کردم در یوز و پسورد هم یوزر و پسورد ftp رو وارد کردم اما خطای 501 به من داد؟!
مشکل از کجاست آیا آدرس سایت رو باید با آدرس ftp بدم؟
اگه وب سرويس موردنظر بالا مياد و سولوشن شما كامپايل ميشه :


اين مشكل اگه Upload_File_To_Web رو از IE پارامتر ميديد؛ احتمالاً از تنظيمات IE شما ميتونه باشه : HTTP Error 501 - Not implemented
اگه از كلاينت اين پيغام رو دريافت مي كنيد و تو تنظيمات شبكه، از ISA سرورتون يا شبكه هاي مستقل با مسكهاي مختلف استفاده مي كنيد، بايد اونها رو چك كنيد.
به احتمال قوي مشكا از ASP.net يا كدنويسي نيست، تنظيمات IIS و IE يا FF‌ رو بايد چك كنيد.

يه نگاهي اينجا (http://support.microsoft.com/kb/811262)بندازيد.
ضمناً اگه مسير Uri شما ftp‌ هست، بايد ftp مسيردهي كنيد نه Http، يعني هرچي تو Address Bar تايپ ميشه همون رو بعنوان پارامتر ورودي ميدين.

rezaei manesh
شنبه 13 تیر 1388, 09:58 صبح
سلام
من یک برنامه ویندوزی دارم که باید یک فایل رو توی یه مسیر که تو هاست هست ( فولدر اصلیش( usrpic ) پریمیشن رایت رو داره یعنی من از تو برنامه وبیم می تونم فایل تو بزارم اما با این ویندوزی نمی تونم)
کپی کنم از کد شما هم استفاده کردم یعنی این:


<WebMethod()> Public Function Upload_File_To_Web(ByVal UriPath As String, _
ByVal SourcePath As String) As String
Try
Dim myWebClient As New WebClient
If (SourcePath.Length > 0) And (UriPath.Length > 0) Then
Dim sUser_Name As String = ConfigurationSettings.AppSettings("UploadUserName")
Dim sPass As String = ConfigurationSettings.AppSettings("UploadPassword")
Dim myCred As NetworkCredential = New NetworkCredential(sUser_Name, sPass)
myWebClient.Credentials = myCred
Dim responseArray As Byte() = myWebClient.UploadFile(UriPath, "PUT", SourcePath)
Return System.Text.Encoding.ASCII.GetString(responseArray )
Else
Return "Error: Upload URI > " + SourcePath
End If
Catch ex As Exception
Return "Error: Upload_File_To_Web: " & ex.Message
End Try
End Function

اما همون خطای 501 رو میده
در ضمن این خطا رو در زمان اجرا و هنگام رسیدن خط زیر میده
(myWebClient.UploadFile(UriPath, "PUT", SourcePath

Saeed_m_Farid
شنبه 13 تیر 1388, 12:41 عصر
سلام
من یک برنامه ویندوزی دارم که باید یک فایل رو توی یه مسیر که تو هاست هست ( فولدر اصلیش( usrpic ) پریمیشن رایت رو داره یعنی من از تو برنامه وبیم می تونم فایل تو بزارم اما با این ویندوزی نمی تونم)
کپی کنم از کد شما هم استفاده کردم
آقای رضایی، یعنی شما این وب متد رو تو برنامه ویندوزی دارید میذارید؟ یا من درست متوجه نشدم؟ اگه اینطوریه :
این یه متد از وب متدهای وب سرویس هست و همونطوریکه میدونید :


باید یه سولوشن وب سرویس ایجاد کنید، بعد این توابع رو تو وب سرویس موردنظر گذاشته و اسم سرویس رو تعیین کنید، بعد پروژه رو کامپایل کرده و Publish کنید.
فایلهای Publish شده رو تو سرور درنظر گرفته شده، Deploy کنید (تو IIS یه Virtual Directory به نام پروژه درست میکنید با پرمیژن Browse)
WSDL وب سرویس خودتون رو بعنوان وب رفرنس به پروژتون اضافه می کنید و از تابع موردنظر استفاده می کنید.

برای آپلود مستقیم فایل از Win app. میتونید System.Net.FtpWebRequest و System.Net.FtpWebResponse استفاده کنید و نیازی به وب سرویس نیست، همچنین می تونید از Stream ها استفاده کنید : مثلاً اینطوری (http://msdn.microsoft.com/en-us/library/ms751463.aspx)

امیدوارم منظورتون رو درست متوجه شده باشم.

Saeed_m_Farid
شنبه 13 تیر 1388, 12:49 عصر
ضمناً اگه فقط میخواهید آپلود فایل انجام بدین : این پست آقای مداح (http://barnamenevis.org/forum/showpost.php?p=515662&postcount=16) رو هم نگاه کنید

مهدی کرامتی
شنبه 11 مهر 1388, 23:56 عصر
فقط یه مشکلی که هست (همون خطی که جلوش کامنت قرمز گذاشتم) اینه که اگه قبلاً فایل تو مسیر موردنظر موجود باشه، overwrite میشه، اگه دوستان راه حلی برای FileExist تو یه Uri دارن لطف کنن.
من معمولا آدرس فایل های آپلود شده رو در دیتابیس نگهداری می کنم. فایل رو پس از آپلود تغییر نام میدم (به یک نام تصادفی) و نام اصلی فایل و نام جدید فایل رو در دو ستون در جدول مربوطه نگهداری می کنم. این طوری هیچ وقت مشکل نام فایل تکراری پس از آپلود ندارم.