एमवीसी 4 स्टार्टर फोटो साइट

बोंगिओज़ो फोटोसाइट

अगर किसी को अपनी फोटो साइट बनाने या ASP.NET MVC से एक उदाहरण के रूप में परिचित होने की इच्छा है, तो ऐसी साइट बनाने में मेरा अनुभव उपयोगी हो सकता है और स्रोत कोड मेरे स्वयं के प्रोजेक्ट का आधार बनेगा।

यह स्पष्ट करने के लिए कि क्या चर्चा की जाएगी, साइट का लिंक www.bongiozzo.ru है

और अब, वास्तव में, यह कैसे किया गया था।

तुम क्या चाहते थे?

कार्य निर्धारित है, चलो चलते हैं ...



विकास के माहौल और रूपरेखा का निर्धारण करें

सबसे पहले, मैंने Visual Studio 2012 RC को स्वतंत्र रूप से डाउनलोड और इंस्टॉल किया। वेब फॉर्म और एमवीसी वेबसाइट विकास के लिए उपलब्ध हैं - मेरी पसंद पूरी तरह से एमवीसी के पक्ष में हैं, क्योंकि इस पैटर्न का उपयोग पर्ल में साइटों को बनाने के लिए किया गया था, जब वेब फॉर्म दृष्टि में नहीं थे :)।
MVC संस्करण के बारे में कोई विशेष विचार नहीं था - चूंकि सब कुछ नया है (विंडोज 8 पर वीएस 2012), मैं इसे एमवीसी 4 के नवीनतम संस्करण पर विकसित करूंगा।

मुख्य बात सामग्री है

फ़्लिकर पर मेरा पहले से ही एक समर्थक खाता था, हालांकि यह एक बिल्कुल वैकल्पिक स्थिति है। फ़्लिकर पर एल्बमों द्वारा स्वचालित ग्रुपिंग और तस्वीरों को सॉर्ट करना मेरे लिए पहले से ही स्मार्टसेट सेवा का उपयोग करके कॉन्फ़िगर किया गया था। इसलिए, मैंने जो पहला काम किया, वह Nuget Package Manager को खोलना था, और फ़्लिकर को शुरू करने से, मुझे फ़्लिकर .NET लाइब्रेरी का उपयोग करके प्रोजेक्ट में फ़्लिकर एपीआई के लिए समर्थन मिला।
शायद बाद में मैं सीएमएस को 500px पर पोर्ट करने पर विचार करूंगा, या हो सकता है कि कोई इसे मुझसे भी तेज कर देगा।

फ्लिकर को एक सीएमएस के रूप में उपयोग करने का विचार सरल था - विवरण में प्रोजेक्ट कीवर्ड के साथ फोटो एल्बम मेरी साइट पर प्रदर्शित होंगे (फ़्लिकर में उन्हें फोटोसेट कहा जाता है)। एल्बम में तस्वीरों को फ़्लिकर उपयोगकर्ताओं द्वारा निर्धारित लोकप्रियता से क्रमबद्ध किया जाएगा।

यहाँ फ़्लिकरमॉडल डेटा मॉडल के लिए कुछ सरल तरीके दिए गए हैं।

public List<FlickrProject> GetProjects(string language) { PhotosetCollection flickrPhotosets = flickr.PhotosetsGetList(Properties.Settings.Default.FlickrUserId); Regex reg_Project = new Regex(@"^Project\s+([^\|].*)\s+\|\s+(.*)"); Match m; List<FlickrProject> returnProjects = new List<FlickrProject>(); foreach (Photoset item in flickrPhotosets) { m = reg_Project.Match(item.Description); if (m.Success) { FlickrProject prj = new FlickrProject(); prj.Description = getDescription(item.Description, language); prj.PhotosetId = item.PhotosetId; prj.Photos = GetPhotosetPhotos(item.PhotosetId, language); prj.PrimaryPhoto = prj.Photos.ToList().Find( delegate(Photo ph) { return ph.PhotoId == item.PrimaryPhotoId; }); returnProjects.Add(prj); } } return returnProjects; } public PhotosetPhotoCollection GetPhotosetPhotos(string photosetId, string language) { PhotosetPhotoCollection photos = flickr.PhotosetsGetPhotos(photosetId, PhotoSearchExtras.Description ); foreach (Photo item in photos) { item.Title = getTitle(item.Title, language); item.Description = getDescription(item.Description, language); } return photos; } 


नवीनतम ट्विटर पोस्ट और किनोपोइक से फिल्म रेटिंग के मॉडल अधिक जटिल नहीं दिखते।

यदि आपने देखा, तो विधि विभिन्न भाषाओं में फ़ोटो के नाम और विवरण लौटाती है।

अपने खुद के या अंग्रेजी में फोटो के नाम बताएं?

मैंने कुछ समय पहले ऐसा सवाल किया था। मैंने फैसला किया कि मैं रूसी और अंग्रेजी में नामों को दोहराऊंगा, उन्हें एक ऊर्ध्वाधर बार के साथ विभाजित करूंगा। अब यह नामकरण साइट पर सबसे अच्छे तरीके से उपयोग करना संभव हो गया है - यदि डिफ़ॉल्ट रूप से आगंतुक ब्राउज़र सेटिंग्स में रूसी का उपयोग करता है - तो उसे अपने मूल नाम दिखाएं, अन्यथा अंग्रेजी। मेरी साइट पर फोटो होस्टिंग साइटों के विपरीत, यह किसी भी विभाजन की छड़ें के बिना स्वाभाविक लगेगा।

MVC में एक फ़िल्टर तंत्र होता है जो सभी या व्यक्तिगत अनुरोधों पर लागू होता है। इस कार्य के लिए, एक LocalizationAware फ़िल्टर लागू किया गया था, जो साइट के मुख्य पृष्ठों के अनुरोधों पर काम करेगा और ब्राउज़र सेटिंग्स के आधार पर वांछित भाषा संस्कृति निर्धारित करेगा:

  public class LocalizationAwareAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var httpContext = filterContext.HttpContext; string language = "en"; HttpCookie langCookie = httpContext.Request.Cookies["lang"]; if (langCookie == null) { if (httpContext.Request.UserLanguages != null && httpContext.Request.UserLanguages[0].IndexOf("ru", StringComparison.OrdinalIgnoreCase) != -1) language = "ru"; httpContext.Response.AppendCookie(createCookie(language)); } else if (langCookie.Value == "ru") language = "ru"; Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(language); } public static HttpCookie createCookie(string language) { HttpCookie cookie = new HttpCookie("lang", language); cookie.Expires = DateTime.Now.AddYears(1); return cookie; } } 


बेशक, भाषा को बदलना संभव है अगर डिफ़ॉल्ट चयन सूट नहीं करता है:

  public ActionResult setLanguage(string id) { id = id == "ru" ? "ru" : "en"; Response.AppendCookie(LocalizationAwareAttribute.createCookie(id)); return Redirect("/"); } 


फ़ोटो के नाम के अलावा, सभी पृष्ठ तत्व - हेडर और टेक्स्ट भी अब उजागर भाषा संस्कृति और प्रोजेक्ट में दो संसाधन फ़ाइलों की उपस्थिति के कारण स्वचालित रूप से चयनित भाषा में स्विच हो जाते हैं - Resources.resx और Resources.ru.resx। इसके लिए एन्कोड करने के लिए कुछ अतिरिक्त की आवश्यकता नहीं थी - यह कार्यक्षमता अंतर्निहित है।

प्रदर्शन और कैशिंग

नेटवर्क सेवाओं के लाभ स्पष्ट हैं, लेकिन प्रतिक्रिया धीमी होने पर इन लाभों को शून्य कर दिया जाएगा, खासकर पीक लोड के दौरान। जाहिर है, फ़्लिकर, ट्विटर और अन्य प्रणालियों की प्रतिक्रियाओं को कैश करने की आवश्यकता है।

ऐसा करना सरल है - केवल विधि से पहले आउटपुटचे विशेषता को निर्दिष्ट करके उचित फ़िल्टर कनेक्ट करें।
पृष्ठ बनाने के लिए, मैं कई क्रियाओं का उपयोग करता हूं - मुख्य अनुरोध (सूचकांक, उदाहरण के लिए) और पृष्ठ के कुछ हिस्सों को प्रस्तुत करने के लिए कई चाइल्डएक्शन्स जिनमें विभिन्न बाहरी प्रणालियों से प्रतिक्रियाएं हैं। प्रत्येक प्रकार की सामग्री के लिए, आप परिवर्तनों की गतिशीलता के आधार पर अपनी स्वयं की कैश अवधि का उपयोग कर सकते हैं।

  [LocalizationAware] [OutputCache(Duration = 20 * 60, Location = System.Web.UI.OutputCacheLocation.Server, VaryByCustom = "lang")] public ActionResult Index() { return View(bag); } [ChildActionOnly] [OutputCache(Duration = 10*60*60)] public ActionResult GetProjects(string language) { HomeViewBag bag = new HomeViewBag(); FlickrContext flickr = new FlickrContext(); bag.FlickrProjects = flickr.GetProjects(language); return View(bag); } [ChildActionOnly] [OutputCache(Duration = 60 * 60)] public ActionResult GetLastPhotos(string language) { HomeViewBag bag = new HomeViewBag(); FlickrContext flickr = new FlickrContext(); bag.LastPhotos = flickr.GetLastPhotos(5, language, 1).ToList(); return View(bag); } 


ASP.NET MVC स्वयं इनपुट मापदंडों के मूल्यों के आधार पर परिणामों की कैश्ड प्रतियों को विभाजित करता है। चाइल्डएक्शंस के लिए, भाषा के रूप में इनपुट मापदंडों को स्पष्ट रूप से परिभाषित किया गया है, हालांकि, बुनियादी प्रश्नों के लिए, सत्र भाषा के आधार पर कैश को विभाजित करना आवश्यक होगा, और यह पैरामीटर मापदंडों में स्पष्ट रूप से मौजूद नहीं है। यह VaryByCustom = "lang" विशेषता और विशेष GetVaryByCustomString पद्धति का उपयोग करके लागू किया गया है। अब कैश में कोई ओवरले नहीं होना चाहिए।

  public override string GetVaryByCustomString(HttpContext context, string arg) { if (arg.ToLower() == "lang") { string langParam = context.Request.QueryString["lang"]; HttpCookie langCookie = context.Request.Cookies["lang"]; if (langParam != null) return langParam == "ru" ? "ru" : "en"; else if (langCookie != null) return langCookie.Value == "ru" ? "ru" : "en"; return ""; } return base.GetVaryByCustomString(context, arg); } 


डिजाइन और फोटो गैलरी

क्योंकि कार्य मूल रूप से सेट किया गया था - साइट को अपने दम पर बनाने के लिए, और मैं खुद एक डिजाइनर नहीं हूं, यह तुरंत साइट को यथासंभव सरल बनाने और खुद को CSS3 और HTML5 की अभिव्यंजक क्षमताओं तक सीमित करने का निर्णय लिया गया। इसके अलावा, फोटोसाइट पर मुख्य ध्यान तस्वीरों और उनकी प्रस्तुति पर होना चाहिए।

इसलिए, मैंने उपयोग के लिए उपलब्ध दीर्घाओं की तलाश की और स्टाइलिश गैलेरिया समाधान पर बस गया। गैलरी jQuery में लिखी गई है, इसकी अपनी एपीआई है, विस्तार के लिए पर्याप्त बुनियादी संस्करण मुफ्त है और उपयोग के लिए उपलब्ध है। आपको क्या चाहिए

मामूली समायोजन के अलावा, उन्होंने अपने स्वयं के नेविगेशन तत्वों और सामाजिक नेटवर्क के साथ एकीकरण को गैलरी इनिशियलाइज़ेशन मॉड्यूल में जोड़ा:

  this.append({ 'stage': ['closeBG', 'socialBG'] }); this.$('socialBG').html('<div id="div-fblike"></div><div id="div-twitter"></div>'); this.$('closeBG').bind("click", function (e) { window.location = "/"; }); 


फोटो के साथ गैलरी को भरना JSON प्रारूप में सरणी को फ़्लिकरमॉडल से प्राप्त डेटा के साथ भरने जैसा दिखता है।

JSON पीढ़ी नियंत्रक में:

  private string getJSON(List<Photo> list, string p) { List<PhotoJSON> json = new List<PhotoJSON>(); foreach (Photo pht in list) json.Add(new PhotoJSON { thumb = pht.ThumbnailUrl, image = pht.LargeUrl, title = pht.Title, description = pht.Description, link = pht.WebUrl, url = Settings.Default.SiteURL + Url.Action("Gallery", new { controller = "Home", id = pht.PhotoId, photoset = p }) }); JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(json); } 


दर्शक में जावास्क्रिप्ट:

  var data = @Html.Raw(Model.PhotosJSON); Galleria.loadTheme('/galleria/themes/bongiozzo/galleria.bongiozzo.js'); Galleria.run('#galleria', { show: @Model.IndexOfCurrentPhoto, transition: 'slide', initialTransition: 'fade', dataSource: data }); 


हम ट्वीट और लाइक पोस्ट करते हैं

गैलरी में फोटो स्विच करने की स्थिति में हम फेसबुक और ट्विटर बटन को अपडेट करते हैं।

  this.bind("image", function (e) { document.title = galleria.getData().title; $('#div-fblike').html('<fb:like href="' + data[galleria.getIndex()].url + '" layout="button_count" send="false" show_faces="false" colorscheme="dark" />'); $('#div-twitter').html('<a href="https://twitter.com/share" class="twitter-share-button" data-url="' + data[galleria.getIndex()].url + '" data-text="' + galleria.getData().title + '">Tweet</a>'); try { FB.XFBML.parse(document.getElementById('div-fblike')); twttr.widgets.load(); } catch(ex) {} }); 


और फेसबुक और अन्य ओजी संगत सिस्टम पर सही ढंग से प्रदर्शित करने के लिए ओपनग्राफ टैग को भरना न भूलें।

  <meta property="fb:app_id" content="@Model.fb_app_id"/> <meta property="og:title" content="@ViewBag.Title" /> <meta property="og:site_name" content="@Resources.Resources.Title" /> <meta property="og:type" content="website" /> <meta property="og:url" content="@Model.SiteUrl@Url.Action("Gallery", new { controller = "Home", id = Model.GalleryPhotos[Model.IndexOfCurrentPhoto].PhotoId, photoset = Model.PhotosetId})" /> <meta property="og:image" content="@Model.GalleryPhotos[Model.IndexOfCurrentPhoto].SquareThumbnailUrl" /> <meta property="og:description" content="@Html.Raw(Model.GalleryPhotos[Model.IndexOfCurrentPhoto].Description.Replace("\n","<br/>"))" /> 


परियोजना की मेजबानी कहां करें?

जब तक फोटो साइट को लॉन्च किया जा सकता है, तब तक, 10 मुक्त साझा साइटों के साथ विंडोज एज़्योर क्लाउड होस्टिंग उपलब्ध हो गया। डेटाबेस और ट्रैफ़िक के लिए अलग-अलग लागत है, हालांकि, यह देखते हुए कि मेरे पास डेटाबेस नहीं है और फ़ोटो खुद फ़्लिकर पर संग्रहीत हैं, और, तदनुसार, कोई ट्रैफ़िक नहीं है - होस्टिंग लगभग मुफ्त है। इसी समय, एज़्योर के मामले में, मेरे पास सेवा की गुणवत्ता और उपलब्धता के बारे में कोई सवाल नहीं है, जो महत्वपूर्ण है। सेवा का प्रबंधन स्पष्ट और सरल है - एज़्योर से पहले, मैंने अन्य प्रदाताओं से होस्टिंग पर विचार किया और यह विशेष रूप से सहायक सेवाओं के साथ भ्रमित इंटरफ़ेस, पत्राचार और टेलीफोन संचार के विपरीत हड़ताली था।

दुर्भाग्य से, एक BUT है - आप इस साझा साइट पर अपने डोमेन नाम को बाँध नहीं सकते। उन लोगों के लिए जिन्हें वास्तव में अपने स्वयं के डोमेन नाम की आवश्यकता नहीं है और bongiozzo.azurewebsites.net जैसे URL से संतुष्ट हैं, यह वास्तव में सबसे अच्छा विकल्प है।
हालांकि, आशा है कि यह साझा साइटों के लिए एक समय सीमा है। इसलिए, जब मैंने साइट को आरक्षित मोड में रखा, जिसमें ऐसा बंधन किया जा सकता है। किसी भी मामले में, 90-दिवसीय परीक्षण अभी भी चल रहा है और मेरे पास एक निश्चित संख्या में एज़्योर सेवाओं की प्रीपेड राशि के साथ एमएसडीएन सदस्यता है।

एज़्योर वेब साइट्स का अगला संस्करण जारी किया जाएगा - मैं देखूँगा , शायद मैं एक न्यूनतम होस्टिंग Infobox.ru , Parking.ru , इत्यादि या क्लाउड सेवाओं के एक XS उदाहरण में स्थानांतरित कर दूंगा , लेकिन अब के लिए यह काम करता है, यह ठीक काम करता है और पैसे के लायक नहीं है।

निष्कर्ष में

Source: https://habr.com/ru/post/In146216/


All Articles