مطالب
راه حل ساده برای عکس‌هایی که از کادر بیرون می‌زنند

ارسال تصویر در سایت‌ها، انجمن‌ها و امثال آن همیشه مشکل زا است؛ خصوصا نمایش تصاویری در قطع یک تابلوی دیواری در یک کادر کوچک.
راه ساده و دم دستی زیر، منهای استفاده از اسکریپت‌هایی که اندازه تصاویر را تشخیص داده و بر این اساس خودشان آن‌ها را بند انگشتی نمایش می‌دهند، هم برای حل این مشکل وجود دارد:
فرض کنید مطلبی که قرار است ارسال شود در یک DIV نمایش داده می‌شود و کلاس آن مثلا post-body است.
اولین کاری که می‌شود انجام داد این است:
در CSS سایت قسمت مرتبط با post-body تعریف زیر را اضافه می‌کنیم تا اضافات عکس که از کادر بیرون زده، خودبخود توسط مرورگر نمایش داده نشود:

overflow: hidden;

سپس در همین DIV که کلاس آن post-body است، با استفاده از jQuery به دنبال تصاویر گشته و موارد یافت شده را داخل یک لینک پویا قرار می‌دهیم (استفاده از متد wrap برای این محصور سازی). این لینک هم همان آدرس اصلی تصویر است. به این ترتیب کاربر با کلیک بر روی آن تصویر می‌تواند نتیجه را در صفحه‌ای دیگر مشاهده کند:

$(document).ready(function(){  
$('.post-body img').each(function(){
var $img = $(this);
var src = $img.attr("src");
$img.attr({border:"0"}).wrap('<a target="_blank" alt="Click here to enlarge (opens new window)" title="Click here to enlarge (opens new window)" href="'+src+'" />');
});
});

مطالب
خلاصه اشتراک‌های روز سه شنبه 3 آبان 1390
مطالب
روش از کار انداختن صفحه‌ی Add service reference در VS.NET

در جهت تکمیل بحث "بررسی امنیتی، حین استفاده از jQuery Ajax"، یک مورد دیگر را هم می‌توان اضافه کرد: چگونه صفحه‌ی معروف Add service reference را در VS.NET جهت سرویس WCF خود از کار بیندازیم؟
راه حل آن هم بسیار ساده است اما چون عموما در منابع مرتبط با جملات و کلمات بیش از حد فنی بیان می‌شود، شاید از دید دور مانده باشد:
اگر WCF Service تولیدی شما تنها قرار است توسط برنامه‌ی Silverlight یا جاوا اسکریپتی موجود در پروژه‌ی جاری مورد استفاده قرار گیرد، باید Meta Data مرتبط با آن سرویس را جهت بالابردن امنیت سیستم، حذف نمود. توسط این Meta Data می‌توان ServiceContract ، OperationContract و سایر اطلاعات یک WCF Service را استخراج نمود.

الف) روش غیر فعال کردن متادیتا در یک Ajax enabled WCF Service

به فایل وب کانفیگ برنامه مراجعه کرده و تغییر زیر را اعمال کنید:
...
<behavior name="">
<serviceMetadata httpGetEnabled="false" httpsGetUrl="false" />
...
</behavior>
...

ب) روش غیرفعال کردن متادیتا در یک Silverlight enabled WCF Service

ابتدا قسمت الف را اعمال نموده سپس تغییر زیر را نیز لحاظ نمائید (IMetadataExchange به صورت کامنت درآمده):
<!-- <endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" /> -->

با این تغییرات ساده، گزینه‌ی Add service reference دیگر قابلیت تشخیص خودکار اطلاعات سرویس شما را نداشته و با یک خطا متوقف خواهد شد:
The HTML document does not contain Web service discovery information.
Metadata contains a reference that cannot be resolved.

سؤال:
1- آیا با این تغییر در عملکرد WCF سرویس ما اخلال ایجاد خواهد شد؟
پاسخ: خیر. تنها Web service discovery information را از کار انداخته‌ایم.
2- در صورت تغییر کدهای WCF Service چه باید کرد؟
پاسخ: اگر امضای متدها و اینترفیس‌های تعریف شده تغییری نداشته‌اند، لزومی به هیچ نوع تغییری نیست. در غیراینصورت، سریع موارد الف و ب فوق را به حالت اول برگردانده، کلاینت مورد استفاده را به روز کنید، مجددا متادیتا را حذف نمائید.

مطالب
خواندنی‌های 8 مرداد
مطالب
آشنایی با کلاس JavaScriptSerializer

برای استفاده از jQuery Ajax یکی از روش‌های ارسال دیتا به برنامه، تبدیل داده‌ها به فرمت JSON می‌باشد. برای داده‌های ساده، تشخیص این فرمت ساده است. مثلا اگر امضای تابع وب سرویس اجکس ما به صورت زیر باشد:
public static bool IsUserAvailable(string username)
اطلاعات جی‌سونی را که قرار است ارسال کنیم، فرمت زیر را باید داشته باشد:
{'username':'value'}
حال اگر آرگومان‌های ما پیچیده‌تر بودند چطور؟ مثلا بجای یک رشته ساده، یک لیست جنریک داشتیم، فرمت ورودی را چگونه باید تشخیص داد؟
برای این منظور در دات نت 3 و نیم، کلاسی جهت انجام اینگونه تبدیلات پیش بینی شده است که شرح مختصر آن به صورت زیر است:
ابتدا باید ارجاعی را به اسمبلی system.web.extensions به برنامه افزود و سپس جهت سهولت کار می‌توان یک extension method از کلاس JavaScriptSerializer مهیا در فضای نام System.Web.Script.Serialization ایجاد کرد:

public static string ToJson(this object data)
{
return new JavaScriptSerializer().Serialize(data);
}
اکنون چند مثال زیر را در نظر بگیرید:
        public static string GetJsonTest0()
{
var data = "a1";
return data.ToJson();
}

public static string GetJsonTest1()
{
var data = new List<string> { "a1", "a2", "a3" };
return data.ToJson();
}

public static string GetJsonTest2()
{

var lst =
new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("Name", "علی"),
new KeyValuePair<string, object>("Number", 10),
new KeyValuePair<string, object>("Desc", "منابع مورد نیاز")
};

return lst.ToJson();

}
خروجی‌های آن‌ها به ترتیب به صورت زیر خواهند بود:

"a1"
["a1","a2","a3"]
[{"Key":"Name","Value":"علی"},{"Key":"Number","Value":10},{"Key":"Desc","Value":"منابع مورد نیاز"}]

این کلاس همچنین قابلیت Deserialize و تبدیل داده‌هایی به فرمت JSON به اشیاء مورد نظر ما را نیز دارا است.

مطالب
بررسی وجود نام کاربر با استفاده از jQuery Ajax در ASP.Net

شاید بعضی از سایت‌ها را دیده باشید که در حین ثبت نام، پس از وارد کردن یک نام کاربری و سپس مشغول شدن به پر کردن فیلد کلمه‌ی عبور، در قسمت نام کاربری شروع به جستجو در مورد آزاد بودن نام کاربری درخواستی می‌کنند یا نمونه‌ای دیگر، فرم پرداخت الکترونیکی بانک سامان. پس از اینکه شماره قبض را وارد کردید، بلافاصله بدون ریفرش صفحه به شما پیغام می‌دهد که این شماره معتبر است یا خیر. امروز قصد داریم این قابلیت را با استفاده از کتابخانه‌ی Ajax مجموعه jQuery در ASP.Net پیاده سازی کنیم (بدون استفاده از ASP.Net Ajax مایکروسافت).
ابتدا سورس کامل را ملاحظه نمائید:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AjaxTest.aspx.cs" Inherits="testWebForms87.AjaxTest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>jQuery Ajax Text</title>

<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#<%= TextBox1.ClientID %>").blur(function(event) {
$.ajax({
type: "POST",
url: "AjaxTest.aspx/IsUserAvailable",
data: "{'username': '" + $('#<%= TextBox1.ClientID %>').val() + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
$('#valid').html("<img src='ajaxImages/waiting.gif' alt='لطفا کمی تامل کنید'>");
var delay = function() {
AjaxSucceeded(msg);
};

setTimeout(delay, 2000); //remove this
},
error: AjaxFailed
});
});
});
function AjaxSucceeded(result) {
if (result.d == true)
$('#msg').html("<img src='ajaxImages/available.gif' alt='نام کاربری درخواستی موجود است'>");
else
$('#msg').html("<img src='ajaxImages/taken.gif' alt='متاسفانه نام کاربری مورد نظر پیشتر دریافت شده‌است'>");
}
function AjaxFailed(result) {
alert(result.status + ' ' + result.statusText);
}
</script>

</head>
<body>
<form id="form1" runat="server">
<div>
user name:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<span id="msg"></span>
<br />
pass:
<asp:TextBox ID="TextBox2" TextMode="Password" runat="server"></asp:TextBox>
</div>
<!-- preload -->
<div style="display: none">
<img src="ajaxImages/available.gif" alt="available" />
<img src="ajaxImages/taken.gif" alt="taken" />
<img src="ajaxImages/waiting.gif" alt="waiting" />
</div>
</form>
</body>
</html>


using System;
using System.Web.Services;

namespace testWebForms87
{
public partial class AjaxTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}

[WebMethod]
public static bool IsUserAvailable(string username)
{
// این مورد را با خواندن اطلاعات از دیتابیس می‌شود تعویض کرد
return username != "test";
}
}
}

توضیحات:
همانطور که ملاحظه می‌کنید صفحه‌ی ASP.Net ما بسیار ساده است و از دو تکست باکس استاندارد تشکیل می‌شود، به همراه تصاویر مربوط به Ajax که یک سری تصاویر ساده چرخان معروف منتظر بمانید ، یافت شد یا موجود نیست می‌باشند. این تصاویر در یک div مخفی (display: none) در صفحه قرار گرفته‌اند و در هنگام بارگذاری صفحه، این‌ها نیز بارگذاری شده و حاضر و آماده خواهند بود. بنابراین هنگام استفاده از آن‌ها، کاربر تاخیری را مشاهده نخواهد کرد. همچنین یک span با id مساوی msg‌ را هم پس از تکست باکس اضافه کرده‌ایم تا تصاویر مربوط به رخدادهای Ajax را با استفاده از توانایی‌های jQuery به آن اضافه کنیم.

اسکریپت Ajax ما با دراختیار گرفتن روال رخداد گردان blur شیء textBox1 شروع می‌شود. همانطور که در مقالات پیشین سایت نیز ذکر شد، روش صحیح دریافت ID یک کنترل ASP.Net در کدهای سمت کلاینت جاوا اسکریپتی، بر اساس خاصیت ClientID آن است که در اولین سطر کدهای ما مشخص است (زیرا در ASP.Net نام و ID یک کنترل در هنگام رندر شدن به همراه ID کنترل‌های دربرگیرنده آن نیز خواهد بود، بنابراین بهتر است این مورد را داینامیک کرد).

کار بررسی موجود بودن نام کاربری (یا مثلا یک شماره قبض و امثال آن) توسط WebMethod ایی به نام IsUserAvailable در code behind صفحه انجام می‌شود که پیاده سازی آن‌را ملاحظه می‌کنید. بدیهی است در این مثال ساده، تنها نام کاربری از پیش رزرو شده، کلمه‌ی test است و در یک کد واقعی این مورد با مقایسه‌ی نام کاربری با اطلاعات موجود در دیتابیس باید صورت گیرد (و حملات تزریق اس کیوال را هم فراموش نکنید. برای رهایی از آن‌ها "حتما" باید از پارامترهای ADO.Net استفاده کرد و گرنه کد شما مستعد به این نوع حملات خواهد بود).

سؤال: چرا از web method استفاده شد و همچنین چرا این متد static است؟
زمانیکه یک متد با کلمه کلیدی static‌ مشخص می‌شود حالت state less پیدا می‌کند یعنی مستقل از وهله‌ی کلاس عمل می‌کند. در این حالت نیازی به ارسال ViewState نبوده (بنابراین در کوئری مورد نظر ما بسیار بهینه و سبک عمل می‌کنند) و همچنین نیازی به ایجاد یک وهله‌ای از کلاس صفحه‌ی ما نیز نخواهد بود. برای توضیحات بیشتر به این مقاله مراجعه نمائید. (به صورت خلاصه، دلیل اصلی، کارآیی بالا و بهینه بودن این روش در این مساله ویژه است و در ASP.Net Ajax مایکروسافت به صورت گسترده‌ای در پشت صحنه مورد استفاده قرار می‌گیرد)
استفاده از ویژگی WebMethod عملکرد صفحه‌ی ما را شبیه به یک وب سرویس خواهد کرد و امکان دسترسی به آن در متدهای استاندارد POST به صورت ارسال دیتا به آدرس WebService.asmx/WebMethodName‌ خواهد بود. یک مثال ساده و عملی

بررسی تابع Ajax بکار رفته:
این تابع هنگام فراخوانی رخداد blur تکست‌باکس ما (مطابق کد فوق) فراخوانی می‌شود. ساختار ساده‌ای دارد که به شرح زیر است:
type: "POST"
نحوه‌ی ارسال داده را به متد وب سرویس ما مشخص می‌کند.

url: "AjaxTest.aspx/IsUserAvailable"
اطلاعات پست شده، به صفحه‌ی AjaxTest.aspx و وب متد IsUserAvailable ارسال خواهد شد

data: "{'username': '" + $('#<%= TextBox1.ClientID %>').val() + "'}",
داده‌ای که به آرگومان username ما ارسال می‌شود، همان مقدار تایپ شده در TextBox1 است (که باز هم دریافت ID آن به صورت داینامیک صورت گرفته تا مشکل زا نشود)

contentType: "application/json; charset=utf-8",
dataType: "json",
در این دو سطر از نوع داده‌ی json استفاده شده است که فرمت بسیار سبک و بهینه‌ای برای تبادل اطلاعات در وب به‌شمار می‌آید و توسط کتابخانه‌های جاوا اسکریپتی به سادگی پردازش شده و تبدیل به اشیاء مورد نظر خواهند شد. برای مثال اگر خروجی یک وب سرویس در حالت xml به صورت زیر باشد:

<xx yy="nn"></xx>
معادل json آن به شرح زیر است:
{ "xx": {"yy":"nn"} }
success: function(msg)
Success ، پس از موفقیت آمیز بودن عملیات ajax در jQuery فراخوانی می‌شود
error: AjaxFailed
و اگر در این بین خطایی رخ داده باشد، قسمت error فراخوانی می‌شود.

در این مثال برای نمایش بهتر عملیات، یک وقفه‌ی 2 ثانیه‌ای توسط setTimeout ایجاد شده و بدیهی است در یک مثال واقعی باید آن‌را حذف نمود.

نکته: با استفاده از افزونه‌ی فایرباگ فایرفاکس، می‌توان جزئیات این عملیات را بهتر مشاهده نمود:





مطالب
لینک‌های هفته‌ی آخر بهمن

وبلاگ‌ها ، سایت‌ها و مقالات ایرانی (داخل و خارج از ایران)

امنیت

Visual Studio

ASP. Net

طراحی و توسعه وب

اس‌کیوال سرور

سی شارپ

عمومی دات نت

مسایل اجتماعی و انسانی برنامه نویسی

کتاب‌های رایگان جدید

متفرقه
مطالب
افزونه جملات قصار jQuery

چندی قبل مطلبی را در مورد پردازش فایل‌های xml با استفاده از قابلیت Ajax جی کوئری نوشتم. در سایت پی‌سافت، تعدادی فایل XML از شعرا و جملات قصار و امثال آن موجود است (با تقدیر و تشکر از زحمات این عزیزان) که امروز قصد داریم از فایل XML جملات قصار آن یک افزونه jQuery درست کنیم تا آن‌ها را به صورت اتفاقی (random) در صفحه نمایش دهد:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>XML</title>
<script src='jquery-1.3.min.js' type='text/javascript'></script>
<script type="text/javascript">
var ourXml = '';
function parseXml(xml){
ourXml = xml; //for our timer
var i;
var rnd = Math.floor(Math.random() * 130) + 1; //we have 130 entries
for (i = 1; i < 5; i++) //M1 to M4
{
$(xml).find("Ghesaar" + rnd + " > M" + i).each(function(){
$("#output").append($(this).text() +' ');
});
}
}

//ajax loader
$(document).ready(function(){
$.ajax({
type: "GET",
url: "Ghesaar.xml",
dataType: "xml",
success: parseXml
});
});

//timer
window.setInterval(function(){
$("#output").empty().hide();
parseXml(ourXml);
$("#output").fadeIn("slow");
}, 10000);
</script>
</head>
<body>
<span id="output" dir="rtl" style=" "/>
</body>

</html>

توضیحات:
همه چیز از قسمت Ajax کد فوق شروع می‌شود. فایل Ghesaar.xml بارگذاری شده و به تابع parseXml ارسال می‌شود. در این تابع یک کپی از xml دریافت شده را نگهداری می‌کنیم تا در تایمری که بعدا جهت نمایش اتفاقی پیام‌ها درست خواهیم کرد، مجبور نشویم مجددا محتویات فایل xml را بارگذاری کنیم.
در تابع parseXml قصد داریم فایل xml ایی با فرمت زیر را پردازش کنیم:

  <Ghesaar10>
<M1>ناامیدی، آخرین نتیجه گیری </M1>
<M2>بی خردان است</M2>
<M3>
</M3>
<M4>« ضرب المثل انگلیسی »</M4>
</Ghesaar10>

برای مثال در اینجا باید به دنبال Ghesaar10>M1 برای یافتن متن تگ M1 گشت و الی آخر. کلا چهار تگ داریم که در یک حلقه آن‌ها را استخراج خواهیم کرد. سپس یک عدد اتفاقی بین 1 تا 130 هم تولید کرده و بجای عدد پس از Ghesaar قرار می‌دهیم. یعنی هر بار به صورت اتفاقی یک مجموعه از جملات قصار، دریافت و پردازش خواهند شد. نهایتا این جملات استخراج شده را به یک span با id مساوی output‌ اضافه می‌کنیم.
تا اینجا فقط یکی از جملات قصار در هنگام بارگذاری صفحه نمایش داده خواهند شد. برای تکرار نمایش، از یک تایمر می‌توان کمک گرفت که کد آن‌را در بالا ملاحظه می‌کنید.
همین!

برای تبدیل آن به یک پلاگین/افزونه جی‌کوئری ، می‌توان به صورت زیر عمل کرد:

$.fn.ghesaar = function(options){
var defaults = {
interval: 1
};
var options = $.extend(defaults, options);

return this.each(function(){
var obj = $(this);
var ourXml = '';
function parseXml(xml){
ourXml = xml; //for our timer
var i;
var rnd = Math.floor(Math.random() * 130) + 1; //we have 130 entries
for (i = 1; i < 5; i++) //M1 to M4
{
$(xml).find("Ghesaar" + rnd + " > M" + i).each(function(){
obj.append($(this).text() + ' ');
});
}
}

//ajax loader
$.ajax({
type: "GET",
url: "Ghesaar.xml",
dataType: "xml",
success: parseXml
});

//timer
window.setInterval(function(){
obj.empty().hide();
parseXml(ourXml);
obj.fadeIn("slow");
}, options.interval * 1000);

});


};

فرمت این فایل ساده و استاندارد است. نام فایل jquery.ghesaar.js خواهد بود.
سپس قسمت استاندارد توسعه options اضافه می‌شود تا بتوان به تابع افزونه خود مقدار interval را پاس کرد تا از این حالت خشک و جمود خارج شود.
کل وقایع افزونه درون تابع زیر رخ می‌دهد:

return this.each(function(){
...

});

اینجا همان کدهایی را که پیشتر توسعه دادیم بدون هیچ تغییری قرار می‌دهیم.
سپس در ابتدای کار شیء this که اشاره‌گری است به شیء انتخاب شده توسط جی‌کوئری را دریافت کرده و هرجایی را که قبلا $("#output") داشتیم، تبدیل به obj می‌کنیم. (یعنی این مورد هم به انتخاب کاربر خواهد شد)
جهت دریافت مقدار تنظیمی interval هم می‌توان از options.interval استفاده کرد.
به این صورت کد ما تبدیل به یک افزونه جی‌کوئری می‌شود.

اینبار نحوه‌ی استفاده از افزونه‌ی تولیدی به صورت زیر است: (عدد interval بر اساس ثانیه است)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>XML</title>
<script src='jquery-1.3.min.js' type='text/javascript'></script>
<script src='jquery.ghesaar.js' type='text/javascript'></script>
<script type="text/javascript">
$(document).ready(function(){
$("#output").ghesaar({interval:5});
});

</script>
</head>
<body>
<span id="output" dir="rtl" style=" "/>
</body>

</html>

بهتر شد، نه؟!

به صورت ساده:
برای استفاده از آن، سه فایل jquery-1.3.min.js (یا نگارش جدیدتر آن)، jquery.ghesaar.js و Ghesaar.xml را باید آپلود کنید. چند سطری را که در قسمت head صفحه فوق مشاهده می‌نمائید باید اضافه شوند. سپس یک span یا div را جهت نمایش این جملات قصار به هر جایی از ساختار صفحه خود که علاقمند بودید اضافه کنید (id آن مهم است و در قسمت نمایش جملات قصار مورد جستجو قرار می‌گیرد).

فایل‌های این پروژه را از اینجا دریافت کنید.

مطالب
ویدیوهای رایگان آموزش jQuery

آموزش مقدماتی jQuery

روز 1 : مشاهده سایت اصلی، دریافت
Day 1: Downloading the Library

روز 2 : مشاهده سایت اصلی، دریافت
Day 2: Fade, Slide, and Show Methods

روز 3 : مشاهده سایت اصلی، دریافت
Day 3: The Animate Method

روز 4 : مشاهده سایت اصلی، دریافت
Day 4: Advanced Selectors

روز 5 : مشاهده سایت اصلی، دریافت
Day 5: Creating and Removing Elements

روز 6 : مشاهده سایت اصلی، دریافت
Day 6: The toggle() and toggleClass() Methods

روز 7 : مشاهده سایت اصلی، دریافت
Day 7: The hover() Methods

روز 8 : مشاهده سایت اصلی، دریافت
Day 8: User Request - Image Slides

روز 9 : مشاهده سایت اصلی، دریافت
Day 9: Resizing Text

روز 10 : مشاهده سایت اصلی، دریافت
Day 10: Intro to AJAX: Using the Load Method

روز 11 : مشاهده سایت اصلی، دریافت
Day 11: Fun Image Hovering

روز 12 : مشاهده سایت اصلی، دریافت
Day 12: Advanced Tooltips: Part 1

روز 13 : مشاهده سایت اصلی، دریافت
Day 13: Submitting Information to a Database Asynchronously

مطالب
لینک‌های هفته اول آذر

وبلاگ‌ها و سایت‌های ایرانی


Visual Studio


ASP. Net


طراحی وب


اس‌کیوال سرور


به روز رسانی‌ها


سی‌شارپ


عمومی دات نت


PHP



متفرقه