একটি এএসপি.নেট এমভিসি অ্যাপ্লিকেশনটিতে দেখার-নির্দিষ্ট জাভাস্ক্রিপ্ট ফাইলগুলি কোথায় রাখবেন?


96

একটি এএসপি.নেট এমভিসি অ্যাপ্লিকেশনটিতে দৃশ্য-নির্দিষ্ট জাভাস্ক্রিপ্ট ফাইলগুলি রাখার জন্য সেরা স্থান (কোন ফোল্ডার ইত্যাদি)?

আমার প্রকল্পটি সুসংহত রাখার জন্য, আমি সত্যিই তাদের ভিউ এর। এসপিএক্স ফাইলগুলির পাশাপাশি পাশাপাশি রাখতে সক্ষম হতে চাই তবে আমি doing / ভিউগুলি প্রকাশ না করে এগুলি করার সময় তাদের রেফারেন্স করার ভাল কোনও উপায় খুঁজে পাইনি ~ / অ্যাকশন / ফোল্ডার কাঠামো। সেই ফোল্ডারের কাঠামোর বিশদটি ফাঁস হতে দেওয়া কি আসলেই খারাপ জিনিস?

বিকল্পটি হ'ল সেগুলিকে ~ / স্ক্রিপ্টস বা fold / সামগ্রী ফোল্ডারে রেখে দেওয়া, তবে এটি একটি সামান্য জ্বালা কারণ এখন আমাকে ফাইল নাম সংঘর্ষ সম্পর্কে চিন্তিত হতে হবে। এটি একটি জ্বালা যা আমি পরাভূত করতে পারি, যদিও এটি "সঠিক জিনিস"।


4
আমি এর জন্য বিভাগগুলি দরকারী বলে মনে করি। দেখুন: স্ট্যাকওভারফ্লো.com
জিজ্ঞাসা

4
এটি পাগল প্রশ্নের মতো শোনাচ্ছে তবে আপনি যখন .cshtml এর অধীনে কোনও পৃষ্ঠার জাভাস্ক্রিপ্ট ফাইলটি বাসা বেঁধে ফেলেন তখন একটি অত্যন্ত কার্যকর দৃশ্য। (উদাহরণস্বরূপ, নেস্টইন সহ ) এটি সমাধান এক্সপ্লোরার কাছাকাছি বাউন্স না করতে সহায়তা করে।
ডেভিড শেরেট

উত্তর:


126

পুরানো প্রশ্ন, তবে আমি আমার উত্তরটি রাখতে চেয়েছিলাম অন্য যে কোনও ব্যক্তি এটির সন্ধান করতে চাইলে।

আমিও আমার ভিউ ফোল্ডারের অধীনে নির্দিষ্ট জেএস / সিএসএস ফাইলগুলি দেখতে চেয়েছিলাম এবং আমি এটি কীভাবে করেছি তা এখানে:

/ ভিউজের মূলের ওয়েবকনফিগ ফোল্ডারে আপনাকে ওয়েব সার্ভারটি ফাইলগুলি পরিবেশন করতে সক্ষম করতে দুটি বিভাগ সংশোধন করতে হবে:

    <system.web>
        <httpHandlers>
            <add path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
            <add path="*.css" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
            <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
        </httpHandlers>
        <!-- other content here -->
    </system.web>

    <system.webServer>
        <handlers>
            <remove name="BlockViewHandler"/>
            <add name="JavaScript" path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
            <add name="CSS" path="*.css" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
            <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
        </handlers>
        <!-- other content here -->
    </system.webServer>

তারপরে আপনার ভিউ ফাইল থেকে আপনি প্রত্যাশা মতো ইউআরএলগুলি উল্লেখ করতে পারেন:

@Url.Content("~/Views/<ControllerName>/somefile.css")

এটি .js এবং .css ফাইলগুলি পরিবেশন করার অনুমতি দেবে এবং অন্য কোনও কিছুর পরিবেশন করতে নিষেধ করবে।


ধন্যবাদ, ডেভসু ঠিক আমি কী সন্ধান করছিলাম
মিস্টার বেল

4
আমি যখন এটি করি তখন ত্রুটিটি পাই যে পাইপলাইন মোডে httpHandlers ব্যবহার করা যাবে না। এটি সার্ভারের ক্লাসিক মোডে স্যুইচ করতে চায়। যখন কেউ সার্ভারটি ক্লাসিক মোড ব্যবহার না করতে চায় তখন এটি করার সঠিক উপায় কী?
Bjørn

4
@ BjørnØyvindHalvorsen আপনি এক বা অন্য হ্যান্ডলার অংশটি মুছতে পারেন বা আপনার ওয়েবকনফাইগে কনফিগারেশন বৈধতা বন্ধ করতে পারেন। এখানে দেখুন
দাভসউ

4
এটি কাজ করার জন্য কেবলমাত্র <সিস্টেম.webServer> বিভাগের মোডগুলির প্রয়োজন ছিল, <সিস্টেম.web> মোডগুলির প্রয়োজন ছিল না।
joedotnot

@ জোয়েডোটনোট সঠিক, কেবল একটি বিভাগের প্রয়োজন, তবে কোনটি আপনার ওয়েবসারভার কনফিগারেশনের উপর নির্ভর করে। বর্তমানে বেশিরভাগ লোকদের system.webServer বিভাগের প্রয়োজন হবে, পুরানো system.web বিভাগ নয়।
ডেভসু

5

এটি অর্জনের একটি উপায় হ'ল নিজের সরবরাহ করা ActionInvoker। নীচে অন্তর্ভুক্ত কোডটি ব্যবহার করে আপনি নিজের নিয়ামকের কনস্ট্রাক্টারে যুক্ত করতে পারেন:

ActionInvoker = new JavaScriptActionInvoker();

এখন, আপনি যখনই কোনও .jsফাইল আপনার দর্শনের পাশে রাখবেন:

এখানে চিত্র বর্ণনা লিখুন

আপনি এটি সরাসরি অ্যাক্সেস করতে পারেন:

http://yourdomain.com/YourController/Index.js

নীচে উত্স:

namespace JavaScriptViews {
    public class JavaScriptActionDescriptor : ActionDescriptor
    {
        private string actionName;
        private ControllerDescriptor controllerDescriptor;

        public JavaScriptActionDescriptor(string actionName, ControllerDescriptor controllerDescriptor)
        {
            this.actionName = actionName;
            this.controllerDescriptor = controllerDescriptor;
        }

        public override object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters)
        {
            return new ViewResult();
        }

        public override ParameterDescriptor[] GetParameters()
        {
            return new ParameterDescriptor[0];
        }

        public override string ActionName
        {
            get { return actionName; }
        }

        public override ControllerDescriptor ControllerDescriptor
        {
            get { return controllerDescriptor; }
        }
    }

    public class JavaScriptActionInvoker : ControllerActionInvoker
    {
        protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
        {
            var action = base.FindAction(controllerContext, controllerDescriptor, actionName);
            if (action != null)
            {
                return action;
            } 

            if (actionName.EndsWith(".js"))
            {
                return new JavaScriptActionDescriptor(actionName, controllerDescriptor);
            }

            else 
                return null;
        }
    }

    public class JavaScriptView : IView
    {
        private string fileName;

        public JavaScriptView(string fileName)
        {
            this.fileName = fileName;
        }

        public void Render(ViewContext viewContext, TextWriter writer)
        {
            var file = File.ReadAllText(viewContext.HttpContext.Server.MapPath(fileName));
            writer.Write(file);
        }
    }


    public class JavaScriptViewEngine : VirtualPathProviderViewEngine
    {
        public JavaScriptViewEngine()
            : this(null)
        {
        }

        public JavaScriptViewEngine(IViewPageActivator viewPageActivator)
            : base()
        {
            AreaViewLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.js",
                "~/Areas/{2}/Views/Shared/{0}.js"
            };
            AreaMasterLocationFormats = new[]
            {
                "~/Areas/{2}/Views/{1}/{0}.js",
                "~/Areas/{2}/Views/Shared/{0}.js"
            };
            AreaPartialViewLocationFormats = new []
            {
                "~/Areas/{2}/Views/{1}/{0}.js",
                "~/Areas/{2}/Views/Shared/{0}.js"
            };
            ViewLocationFormats = new[]
            {
                "~/Views/{1}/{0}.js",
                "~/Views/Shared/{0}.js"
            };
            MasterLocationFormats = new[]
            {
                "~/Views/{1}/{0}.js",
                "~/Views/Shared/{0}.js"
            };
            PartialViewLocationFormats = new[]
            {
                "~/Views/{1}/{0}.js",
                "~/Views/Shared/{0}.js"
            };
            FileExtensions = new[]
            {
                "js"
            };
        }

        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            if (viewName.EndsWith(".js"))
                viewName = viewName.ChopEnd(".js");
            return base.FindView(controllerContext, viewName, masterName, useCache);
        }


        protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
        {
            return new JavaScriptView(partialPath);
        }

        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
        {
            return new JavaScriptView(viewPath);
        }
    }
}

এটি তবে এটি একটি ভাল সমাধান বলে মনে হচ্ছে, তবে এটি কি কল করার সময় কর্মকে প্রভাবিত করে?
লিয়ান্দ্রো সোয়ারেস

এটি ভাল কাজ করতে পারে, কিন্তু কি? আমি কম কোড লিখতে চাই, আরও বেশি নয়।
joedotnot

4
@ জয়েডোট আপনি একবারে আরও কোড এবং কম কোড চিরকাল লিখবেন না। একজন প্রোগ্রামারের মন্ত্র, না? :)
কার্ক ওল

পছন্দ করুন সেখানে কোন মতবিরোধ নেই। হতাশ হয়েছি যে "সাধারণ বৈশিষ্ট্য" কী হওয়া উচিত, এটি বাক্স থেকে বেরিয়ে আসেনি। সুতরাং আমি ডেভস এর উত্তর (গ্রহণযোগ্য উত্তর) বেছে নিতে পছন্দ করেছি। তবে আপনার কোডটি ভাগ করে নেওয়ার জন্য ধন্যবাদ, এটি অন্যের পক্ষে কার্যকর হতে পারে।
joedotnot

@ কির্কওয়ল আমি এমভিসিতে নতুন এবং আমি আপনার সমাধানটি এমভিসি 5 তে প্রয়োগ করার চেষ্টা করছি। "অ্যাকশনআইনভোকার = নতুন জাভাস্ক্রিপ্টঅ্যাকশনআইভোকার ()" কোথায় রাখবেন বা "ব্যবহার" করবেন তা আমি নিশ্চিত নই ??
ড্রু

3

আপনি দাভসুর পরামর্শটি উল্টাতে পারেন এবং কেবল। Cshtml ব্লক করতে পারেন

<httpHandlers>
    <add path="*.cshtml" verb="*" type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>

পারফেক্ট! :) একটি দুর্দান্ত সংক্ষিপ্ত সমাধান! এবং এটি কাজ করে! :) কেন এটি ডিফল্ট সেটিংস নয় তা আমার কোনও ধারণা নেই, কারণ আসল মতামতের সাথে মতামত সম্পর্কিত স্ক্রিপ্টগুলি রাখতে সক্ষম হওয়া আরও ভাল। ধন্যবাদ, ভডিয়াম
ব্রুসহিল

24
আমি এই পদ্ধতির সাথে সতর্ক থাকব, যদিও এটি দেখতে সুন্দর এবং পরিষ্কার মনে হচ্ছে। ভবিষ্যতে যদি এই অ্যাপ্লিকেশনটিতে রেজার ছাড়া অন্য দেখার ইঞ্জিনগুলি অন্তর্ভুক্ত থাকে (প্রাক্তন ওয়েব ফর্মস, স্পার্ক ইত্যাদি), তারা নিঃশব্দে সর্বজনীন হবে। মত ফাইল প্রভাবিত Site.Master
শ্বেত তালিকাটি

আমি @ arserbin3 এর সাথে একমত যে শ্বেত-তালিকাটি নিরাপদ বলে মনে হচ্ছে; একই সময়ে, আমি এন্টারপ্রাইজ অ্যাপ্লিকেশনটির ভিউ ইঞ্জিনের এক থেকে অন্যটিতে পরিবর্তনের সম্ভাবনা অনুভব করতে পারছি না। এটি করার জন্য কোনও নিখুঁত অটোমেশন সরঞ্জাম নেই। রূপান্তরটি হাতে হাতে করা দরকার। একবার আমি একটি বড় ওয়েব অ্যাপ্লিকেশনটির জন্য এটি করেছি; ওয়েবফর্ম ভিউজিনাইজাকে রেজারে রূপান্তরিত করে, এবং আমি মনে করি দুঃস্বপ্নের দিনগুলি, কয়েক মাস ধরে, জিনিসগুলি এখানে এবং সেখানে কাজ করে না ... আবার এই জাতীয় জিনিসটি করার কথা ভাবতে পারে না :)। যদি আমাকে যাইহোক এই জাতীয় দৈত্য পরিবর্তন করতে হয় তবে আমি বিশ্বাস করি যে এই জাতীয় ওয়েবকনফিগ সেটিংস পরিবর্তনটি ভুলে যাবেন না।
এমরান হুসেন

1

আমি জানি এটি একটি পুরানো বিষয়, তবে আমার কয়েকটি জিনিস যুক্ত করতে চাই। আমি দাভসির উত্তরের চেষ্টা করেছি তবে স্ক্রিপ্ট ফাইলগুলি লোড করার চেষ্টা করার সময় এটি একটি 500 ত্রুটি ছুঁড়েছিল তাই আমাকে এটি ওয়েবকনফাইগে যুক্ত করতে হয়েছিল:

<validation validateIntegratedModeConfiguration="false" />

system.webServer এ। আমার কাছে যা আছে তা এখানেই রয়েছে এবং আমি এটি কার্যকর করতে সক্ষম হয়েছি:

<system.webServer>
  <handlers>
    <remove name="BlockViewHandler"/>
    <add name="JavaScript" path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
    <add name="CSS" path="*.css" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
    <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
  </handlers>
  <validation validateIntegratedModeConfiguration="false" />
</system.webServer>
<system.web>
  <compilation>
    <assemblies>
      <add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </assemblies>
  </compilation>
  <httpHandlers>
      <add path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
      <add path="*.css" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
      <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
  </httpHandlers>
</system.web>

বৈধকরণ সম্পর্কিত আরও তথ্য এখানে রয়েছে: https://www.iis.net/configreferences/system.webserver/ માન્ય করণ


0

system.web ট্যাগের ভিতরে ওয়েব কোডফাইগ ফাইলটিতে এই কোডটি যুক্ত করুন

<handlers>
    <remove name="BlockViewHandler"/>
    <add name="JavaScript" path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
    <add name="CSS" path="*.css" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
     <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>

0

আমি ভিউয়ের সাথে একই ফোল্ডারে কোনও ভিউ সম্পর্কিত জেএস ফাইলগুলিও রাখতে চেয়েছিলাম।

আমি এই থ্রেডে অন্যান্য সমাধানগুলি কাজ করতে সক্ষম হচ্ছিলাম না, সেগুলি ভেঙে গেছে তবে এমভিসিতে তাদের কাজ করার জন্য আমি খুব নতুন।

এখানে প্রদত্ত তথ্য এবং অন্যান্য বেশ কয়েকটি স্ট্যাক ব্যবহার করে আমি একটি সমাধান নিয়ে এসেছি যা:

  • জাভাস্ক্রিপ্ট ফাইলটি একই ডিরেক্টরিতে যেমন দেখার সাথে যুক্ত হয় তেমনভাবে রাখার অনুমতি দেয়।
  • স্ক্রিপ্ট ইউআরএলটি অন্তর্নিহিত শারীরিক সাইটের কাঠামোটি দেয় না
  • স্ক্রিপ্ট ইউআরএলের শেষের স্ল্যাশ (/) দিয়ে শেষ করা উচিত নয়
  • স্থিতিশীল সংস্থানগুলিতে হস্তক্ষেপ করে না, যেমন: /Scriptts/someFile.js এখনও কাজ করে
  • সক্ষম হওয়ার জন্য রানআল ম্যানেজডমডিউলস ফরঅলরেইকেষ্টগুলির প্রয়োজন হয় না।

দ্রষ্টব্য: আমি এইচটিটিপি অ্যাট্রিবিউট রাউটিংও ব্যবহার করছি। এটা সম্ভব যে আমার আত্মায় যে রুটের ব্যবহার রয়েছে এটি এটিকে সক্ষম না করেই কাজ করার জন্য পরিবর্তন করা যেতে পারে।

নিম্নলিখিত উদাহরণ / ডিরেক্টরি কাঠামো দেওয়া:

Controllers
-- Example
   -- ExampleController.vb

Views
-- Example
   -- Test.vbhtml
   -- Test.js

উপরের উদাহরণ কাঠামোর সাথে একত্রে নীচে প্রদত্ত কনফিগারেশন পদক্ষেপগুলি ব্যবহার করে পরীক্ষা দেখার URL টি এর মাধ্যমে অ্যাক্সেস করা হবে: /Example/Testএবং জাভাস্ক্রিপ্ট ফাইলটির মাধ্যমে রেফারেন্স হবে:/Example/Scripts/test.js

পদক্ষেপ 1 - অ্যাট্রিবিউট রাউটিং সক্ষম করুন:

আপনার / app_start/RouteConfig.vb ফাইলটি সম্পাদনা করুন এবং routes.MapMvcAttributeRoutes()বিদ্যমান রুটগুলির ঠিক উপরে যুক্ত করুন ap ম্যাপরুট:

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.Mvc
Imports System.Web.Routing

Public Module RouteConfig
    Public Sub RegisterRoutes(ByVal routes As RouteCollection)
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

        ' Enable HTTP atribute routing
        routes.MapMvcAttributeRoutes()

        routes.MapRoute(
            name:="Default",
            url:="{controller}/{action}/{id}",
            defaults:=New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional}
        )
    End Sub
End Module

পদক্ষেপ 2-আপনার সাইটটিকে চিকিত্সা এবং প্রক্রিয়া করার জন্য কনফিগার করুন / / কন্ট্রোলার / স্ক্রিপ্টগুলি

আপনার /Web.config ফাইলটি সম্পাদনা করুন, নিম্নলিখিতটি সিস্টেমে যুক্ত করুন we ওয়েবে সার্ভার -> ফাইলের হ্যান্ডলার বিভাগে:

<add name="ApiURIs-ISAPI-Integrated-4.0" path="*/scripts/*.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

এখানে এটি আবার প্রসঙ্গে:

  <system.webServer>
    <modules>
      <remove name="TelemetryCorrelationHttpModule"/>
      <add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" preCondition="managedHandler"/>
      <remove name="ApplicationInsightsWebTracking"/>
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler"/>
    </modules>
    <validation validateIntegratedModeConfiguration="false"/>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
      <remove name="OPTIONSVerbHandler"/>
      <remove name="TRACEVerbHandler"/>
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
      <add name="ApiURIs-ISAPI-Integrated-4.0" path="*/scripts/*.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>  

পদক্ষেপ 3 - আপনার কন্ট্রোলার ফাইলে নিম্নলিখিত স্ক্রিপ্ট ক্রিয়া ফলাফল যুক্ত করুন

  • নিয়ামকের জন্য {নিয়ামক} নামের সাথে মিলানোর জন্য রুটের পাথ সম্পাদনা করতে ভুলবেন না, উদাহরণস্বরূপ এটি: <রুট (" উদাহরণ / স্ক্রিপ্ট / {ফাইলের নাম}")>
  • আপনার প্রতিটি কন্ট্রোলার ফাইলগুলিতে এটি অনুলিপি করতে হবে। আপনি যদি চান, সম্ভবত একক, এককালীন, রুট কনফিগারেশন হিসাবে এটি করার কোনও উপায় রয়েছে।

        ' /Example/Scripts/*.js
        <Route("Example/Scripts/{filename}")>
        Function Scripts(filename As String) As ActionResult
            ' ControllerName could be hardcoded but doing it this way allows for copy/pasting this code block into other controllers without having to edit
            Dim ControllerName As String = System.Web.HttpContext.Current.Request.RequestContext.RouteData.Values("controller").ToString()
    
            ' the real file path
            Dim filePath As String = Server.MapPath("~/Views/" & ControllerName & "/" & filename)
    
            ' send the file contents back
            Return Content(System.IO.File.ReadAllText(filePath), "text/javascript")
        End Function
    

প্রসঙ্গে, এটি আমার উদাহরণকন্ট্রোলআরভিবি ফাইল:

Imports System.Web.Mvc

Namespace myAppName
    Public Class ExampleController
        Inherits Controller

        ' /Example/Test
        Function Test() As ActionResult
            Return View()
        End Function


        ' /Example/Scripts/*.js
        <Route("Example/Scripts/{filename}")>
        Function Scripts(filename As String) As ActionResult
            ' ControllerName could be hardcoded but doing it this way allows for copy/pasting this code block into other controllers without having to edit
            Dim ControllerName As String = System.Web.HttpContext.Current.Request.RequestContext.RouteData.Values("controller").ToString()

            ' the real file path
            Dim filePath As String = Server.MapPath("~/Views/" & ControllerName & "/" & filename)

            ' send the file contents back
            Return Content(System.IO.File.ReadAllText(filePath), "text/javascript")
        End Function


    End Class
End Namespace

চূড়ান্ত নোটগুলি টেস্ট.ভিবিএইচটিএমএল ভিউ / টেস্ট.জেএস জাভাস্ক্রিপ্ট ফাইলগুলির জন্য বিশেষ কিছু নেই এবং এখানে দেখানো হয়নি।

আমি আমার সিএসএস ভিউ ফাইলে রাখি তবে আপনি সহজেই এই সমাধানটিতে যুক্ত করতে পারেন যাতে আপনি আপনার সিএসএস ফাইলগুলিকে একইভাবে উল্লেখ করতে পারেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.