সমস্ত পৃষ্ঠায় সাধারণ যে লেআউটে ডেটা দিন


124

আমার একটি ওয়েবসাইট রয়েছে যার একটি বিন্যাস পৃষ্ঠা রয়েছে। তবে এই লেআউট পৃষ্ঠায় এমন ডেটা রয়েছে যা সমস্ত পৃষ্ঠাগুলির অবশ্যই এমন পৃষ্ঠার শিরোনাম, পৃষ্ঠার নাম এবং সেই অবস্থানটি সরবরাহ করতে হবে যেখানে আমরা আসলে কোনও HTML সম্পাদকের হয়েছি যা কিছু কাজ করে। এছাড়াও প্রতিটি পৃষ্ঠার নিজস্ব ভিউ মডেলের বৈশিষ্ট্য রয়েছে।

কিভাবে আমি এটি করতে পারব? দেখে মনে হচ্ছে একটি লেআউট টাইপ করা এটির একটি খারাপ ধারণা তবে আমি কীভাবে এই ইনফসগুলি পাস করব?


10
এখানে উত্তরগুলি পড়ার জন্য, দয়া করে stackoverflow.com/a/21130867/706346 দেখুন যেখানে আপনি এখানে পোস্ট করা অনেক সহজ এবং সুন্দর সমাধান দেখতে পাবেন।
অভ্রোহম ইয়িস্রোয়েল

5
@ অ্যাভ্রোহম ইয়েস্রোয়েল ভাল পরামর্শ। তবে আমি @ কলিন বেকনের পদ্ধতির পছন্দ করি কারণ এটি শক্তিশালী টাইপযুক্ত এবং এতে নেই ViewBag। সম্ভবত পছন্দ বিষয়। যদিও আপনার মন্তব্যে উত্সাহিত করেছেন
জেপি

এমভিসি 5 এর জন্য এই উত্তরটি দেখুন: stackoverflow.com/a/46783375/5519026
জিয়া

উত্তর:


142

আপনার যদি প্রতিটি পৃষ্ঠায় একই বৈশিষ্ট্যগুলি পাস করার প্রয়োজন হয়, তবে আপনার ভিউ মডেলগুলি ব্যবহার করে একটি বেস ভিউ মডেল তৈরি করা বুদ্ধিমানের কাজ হবে। আপনার লেআউট পৃষ্ঠাটি তখন এই বেস মডেলটি নিতে পারে।

যদি এই ডেটার পিছনে যুক্তি প্রয়োজন হয়, তবে এটি একটি বেস নিয়ামক হিসাবে রাখা উচিত যা আপনার সমস্ত কন্ট্রোলার ব্যবহার করে।

আপনি করতে পারেন এমন অনেকগুলি বিষয় রয়েছে, একাধিক স্থানে একই কোডটির পুনরাবৃত্তি না করানো গুরুত্বপূর্ণ পন্থা।

সম্পাদনা করুন: নীচের মন্তব্যগুলি থেকে আপডেট করুন

ধারণাটি প্রদর্শনের জন্য এখানে একটি সাধারণ উদাহরণ।

এমন একটি বেস ভিউ মডেল তৈরি করুন যা সমস্ত দর্শন মডেলদের উত্তরাধিকার সূত্রে প্রাপ্ত হবে।

public abstract class ViewModelBase
{
    public string Name { get; set; }
}

public class HomeViewModel : ViewModelBase
{
}

আপনার লেআউট পৃষ্ঠাটি এটি মডেল হিসাবে নিতে পারে।

@model ViewModelBase
<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Test</title>
    </head>
    <body>
        <header>
            Hello @Model.Name
        </header>
        <div>
            @this.RenderBody()
        </div>
    </body>
</html>

শেষ পর্যন্ত অ্যাকশন পদ্ধতিতে ডেটা সেট করুন।

public class HomeController
{
    public ActionResult Index()
    {
        return this.View(new HomeViewModel { Name = "Bacon" });
    }
}

12
তবে ডেটা বিন্যাসে ব্যবহৃত হয়। আমি কীভাবে ডেটাটি লেআউটে পাস করতে পারি?
রুশিনো

2
পারফেক্ট! আমি আমার ত্রুটি দেখেছি। আমি মডেলটি ভিউতে পাস করতে ভুলে গেছি .. কি লম্পট ত্রুটি। ধন্যবাদ!
রুশিনো

7
এই পদ্ধতির সমস্যাটি হ'ল কখনও কখনও প্রতিটি দৃশ্যের একটি ভিউমোডেল থাকে না, সুতরাং এটি সেই ক্ষেত্রে কাজ করবে না: ও /
কচো সান্তা

16
তবে এর জন্য কি প্রতিটি নিয়ামক এবং প্রতিটি ক্রিয়ায় {Name = "বেকন"} কোড অন্তর্ভুক্ত করা দরকার হয় না? এবং যদি আমি ভিউমোডেলবেসে অন্য সম্পত্তি যুক্ত করতে চাই, আমাকে প্রতিটি নিয়ামক এবং প্রতিটি ক্রিয়াতে যেতে হবে এবং সেই সম্পত্তিটি জনপ্রিয় করার জন্য কোড যুক্ত করতে হবে? আপনি উল্লেখ করেছেন "যদি সেখানে যুক্তি প্রয়োজন হয় [...] এটি একটি বেস নিয়ামকের মধ্যে রাখা উচিত [...]"। প্রতিটি নিয়ামক এবং প্রতিটি ক্রিয়াকলাপে এই পুনরাবৃত্ত কোডটি কীভাবে দূর করতে এই কাজ করবে?
লি

5
@ লী যদি এটি সমস্ত পৃষ্ঠাগুলির মধ্যে সাধারণ তথ্য হয় তবে একটি বেস নিয়ামক যেখানে আপনি এটি স্থাপন করবেন। আপনার নিয়ামকরা তখন এই বেস নিয়ামক থেকে উত্তরাধিকারী। যেমন public class HomeController : BaseController। এইভাবে সাধারণ কোডটি একবারে লিখতে হবে এবং সমস্ত নিয়ামককে প্রয়োগ করা যেতে পারে।
কলিন বেকন 16

73

লেআউটে রেজারের জন্য আমি রেন্ডারএকশন এইচটিএমএল সহায়ক ব্যবহার করেছি।

@{
   Html.RenderAction("Action", "Controller");
 }

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

 public PartialViewResult Action()
    {
        var model = someList;
        return PartialView("~/Views/Shared/_maPartialView.cshtml", model);
    }

আপনার তৈরি করা আংশিক দর্শন '_maPartialView.cshtml' এর জন্য আপনাকে কেবল আপনার মডেলটি রাখা উচিত

@model List<WhatEverYourObjeIs>

তারপরে আপনি এইচটিএমএল সহ আংশিক দৃশ্যে মডেলটিতে ডেটা ব্যবহার করতে পারেন।


18
এটিই এখন পর্যন্ত সবচেয়ে ভাল উত্তর!
জিঞ্জারব্রেডবয়

@ ভার্জারব্রেডবয় সম্মত হয়েছেন যে এটি ভাল এনক্যাপসুলেশন এবং উদ্বেগের পৃথকীকরণের প্রচার করে।
এ-ডাব

35

অন্য বিকল্পটি হ'ল লেআউটে আপনার প্রয়োজনীয় সমস্ত বৈশিষ্ট্য সহ একটি পৃথক লেআউটমোডেল ক্লাস তৈরি করা এবং তারপরে এই শ্রেণীর কোনও উদাহরণ ভিউব্যাগে স্টাফ করুন। আমি এটিকে জনপ্রিয় করতে কন্ট্রোলারঅঅন্যাকশনএক্সেকুটিং পদ্ধতি ব্যবহার করি। তারপরে, বিন্যাসের শুরুতে আপনি ভিউব্যাগ থেকে এই বিষয়টিকে আবার টানতে পারেন এবং দৃ strongly়ভাবে টাইপ করা এই অবজেক্টটিতে অ্যাক্সেস চালিয়ে যেতে পারেন।


1
এটি আসলে কমপক্ষে বেদনাদায়ক সমাধানের মতো শোনাচ্ছে, কোনও ডাউনসাইড আছে কি? +1
formatc

2
অবশ্যই সর্বোত্তম সমাধান এবং আমি কোনও ডাউনসাইড দেখতে পাচ্ছি না।
উইক্টর জ্যাচলা

7
আমি আপনাকে দেখতে পাচ্ছি না। আপনার যদি লেআউটের জন্য প্রয়োজনীয় সমস্ত বৈশিষ্ট্যগুলির সাথে একটি শ্রেণি পাওয়া যায়, তবে কেন এটি আবার ফিরিয়ে দিতে হবে তা ভিউব্যাগে যুক্ত করা কেন বিরক্ত করবেন? লেআউট ভিউতে মডেলটি ব্যবহার করুন, আপনি এখনও মডেলটিকে পপুলেট করতে পারেন OnActionExecuting। ভিউ ব্যাগ ব্যবহারের অর্থ হ'ল আপনি আপনার নিয়ামকটিতে সুরক্ষার ধরণটি হ'ল কখনও ভাল জিনিস নয়।
কলিন বেকন

3
এটি আমাকে যা দেয় তা হ'ল একটি কন্ট্রোলারের সমস্ত পদ্ধতিতে একক "সুপার" মডেল থেকে উত্তরাধিকারী সমস্ত মডেল পুনর্গঠন না করে বিন্যাসের জন্য একটি মডেল যুক্ত করার ক্ষমতা, ইতিমধ্যে বিদ্যমান একটি প্রকল্পে। আপনি যদি স্ক্র্যাচ থেকে শুরু করে থাকেন তবে পরিবর্তে আপনি আপনার সমস্ত মডেল সাধারণ শিকড় থেকে নেওয়া বেছে নিতে পারেন।
DenNukem

5
@ কলিনব্যাকন এই বিকল্পের আরেকটি সুবিধা হ'ল আপনার ক্রিয়াকলাপগুলিতে সর্বদা দেখার মডেল থাকা দরকার না। এছাড়াও, আমি যুক্তি দিয়েছি যে বিকাশকারীদের এটি জানতে হবে যে তাদের সর্বদা বেস থেকে তাদের দর্শন মডেলদের উত্তরাধিকারী হওয়া অবশ্যই অসুবিধা।
জোশ নোয়ে

28

সম্ভবত, এর প্রাথমিক ব্যবহারের ক্ষেত্রে কন্ট্রোলারের সমস্ত (বা সংখ্যাগরিষ্ঠ) ক্রিয়াকলাপের জন্য ভিউতে একটি বেস মডেল পাওয়া।

এটি দেওয়া, আমি এই উত্তরগুলির বেশ কয়েকটিটির সংমিশ্রণটি ব্যবহার করেছি, কলিন বেকনের উত্তরের প্রাথমিক পিগি সমর্থন।

এটি সঠিক যে এটি এখনও নিয়ন্ত্রক যুক্তিযুক্ত কারণ আমরা একটি ভিউতে ফিরে আসার জন্য একটি ভিউমডেলকে পপুলেট করছি। সুতরাং এটি রাখার সঠিক জায়গাটি নিয়ামকের মধ্যে রয়েছে।

আমরা সব কন্ট্রোলারে এটি ঘটতে চাই কারণ আমরা এটি লেআউট পৃষ্ঠার জন্য ব্যবহার করি। আমি এটি আংশিক দর্শনের জন্য ব্যবহার করছি যা বিন্যাস পৃষ্ঠায় রেন্ডার করা হয়।

আমরা এখনও দৃ strongly়ভাবে টাইপ করা ভিউমোডেলের অতিরিক্ত সুবিধাটি চাই

সুতরাং, আমি একটি বেসভিউমোডেল এবং বেসকন্ট্রোলার তৈরি করেছি। সমস্ত ভিউমোডেলস নিয়ন্ত্রকগণ যথাক্রমে বেসভিউমোডেল এবং বেসকন্ট্রোলারের কাছ থেকে উত্তরাধিকারী হবেন।

কোড:

BaseController

public class BaseController : Controller
{
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        var model = filterContext.Controller.ViewData.Model as BaseViewModel;

        model.AwesomeModelProperty = "Awesome Property Value";
        model.FooterModel = this.getFooterModel();
    }

    protected FooterModel getFooterModel()
    {
        FooterModel model = new FooterModel();
        model.FooterModelProperty = "OMG Becky!!! Another Awesome Property!";
    }
}

এই এসও পোস্ট থেকে নেওয়া হিসাবে অন্যাকশনএক্সেকটেডের ব্যবহারটি নোট করুন

HomeController

public class HomeController : BaseController
{
    public ActionResult Index(string id)
    {
        HomeIndexModel model = new HomeIndexModel();

        // populate HomeIndexModel ...

        return View(model);
    }
}

BaseViewModel

public class BaseViewModel
{
    public string AwesomeModelProperty { get; set; }
    public FooterModel FooterModel { get; set; }
}

HomeViewModel

public class HomeIndexModel : BaseViewModel
{

    public string FirstName { get; set; }

    // other awesome properties
}

FooterModel

public class FooterModel
{
    public string FooterModelProperty { get; set; }
}

Layout.cshtml

@model WebSite.Models.BaseViewModel
<!DOCTYPE html>
<html>
<head>
    < ... meta tags and styles and whatnot ... >
</head>
<body>
    <header>
        @{ Html.RenderPartial("_Nav", Model.FooterModel.FooterModelProperty);}
    </header>

    <main>
        <div class="container">
            @RenderBody()
        </div>

        @{ Html.RenderPartial("_AnotherPartial", Model); }
        @{ Html.RenderPartial("_Contact"); }
    </main>

    <footer>
        @{ Html.RenderPartial("_Footer", Model.FooterModel); }
    </footer>

    < ... render scripts ... >

    @RenderSection("scripts", required: false)
</body>
</html>

_Nav.cshtml

@model string
<nav>
    <ul>
        <li>
            <a href="@Model" target="_blank">Mind Blown!</a>
        </li>
    </ul>
</nav>

আশা করি এটি সাহায্য করবে।


2
আমি এই পদ্ধতির ব্যবহার করেছি, তবে বেস শ্রেণীর চেয়ে ইন্টারফেস থেকে উত্তরাধিকার সূত্রে পছন্দ করি। সুতরাং আমি করেছি: var মডেল = ফিল্টারকন্টেক্সট.কন্ট্রোলার.ভিউউডাটা.মোডেল আইবেসভিউমোডেল হিসাবে যদি (মডেল! = নাল) {মডেল Aআলভীমোডেলপ্রোপার্টি = "অসাধারণ সম্পত্তি মান"; }
টম জারকেন

2
দুর্দান্ত উত্তর, আমি এইটিকে অন্য সকলের চেয়ে পছন্দ করেছি।
জিন

1
দুর্দান্ত উত্তর, তবে আমার একটি প্রশ্ন আছে। "আমার যদি ভিউমোডেলস না থাকে এমন কিছু ভিউ থাকে ...?"
ইসমা হারো

এটি চেষ্টা করেও ইনডেক্স অ্যাকশনে, অন্যাকশনএক্সেটেড ফুটারমোডেলটি পূরণ করে এবং তারপরে একটি নূতন ফুটারমোডেল দিয়ে একটি নতুন হোমআইডেক্স মডেল তৈরি করা হয় :(
স্টিভক্যাভ

1
@ ডিরিজি: আপনার বেস নিয়ামকটিতে, ফিল্টার পদ্ধতিতে মডেল একটি স্থানীয় ভেরিয়েবল: var মডেল = ফিল্টারকন্টেক্সট.কন্ট্রোলার.ভিউ ডেটা.মোডেল বেসভিউমোডেল হিসাবে। আমি বুঝতে পারি না এমভিসি কীভাবে বুঝতে পারে যে এই স্থানীয় ভেরিয়েবলটি মডেলটিকে দেখার জন্য হোমকন্ট্রোলার পাঠানোর অনুরূপ as
হুমান বাহরাইনি

9

আপনাকে ক্রিয়াতে বা জালিয়াতি বা মডেলটি পরিবর্তন করতে হবে না, কেবলমাত্র একটি বেস নিয়ামক ব্যবহার করুন এবং লেআউট ভিউকনস্টেক্সট থেকে বিদ্যমান নিয়ামকটি কাস্ট করুন।

কাঙ্ক্ষিত সাধারণ ডেটা (শিরোনাম / পৃষ্ঠা / অবস্থান ইত্যাদি) এবং ক্রিয়া সূচনা দিয়ে একটি বেস নিয়ামক তৈরি করুন ...

public abstract class _BaseController:Controller {
    public Int32 MyCommonValue { get; private set; }

    protected override void OnActionExecuting(ActionExecutingContext filterContext) {

        MyCommonValue = 12345;

        base.OnActionExecuting(filterContext);
    }
}

প্রতিটি নিয়ামক বেস নিয়ামক ব্যবহার করে তা নিশ্চিত করুন ...

public class UserController:_BaseController {...

আপনার _Layout.cshmlপৃষ্ঠায় দেখার প্রেক্ষাপট থেকে বিদ্যমান বেস নিয়ন্ত্রকটিকে কাস্ট করুন ...

@{
    var myController = (_BaseController)ViewContext.Controller;
}

এখন আপনি আপনার বিন্যাস পৃষ্ঠা থেকে আপনার বেস নিয়ামকের মানগুলি উল্লেখ করতে পারেন।

@myController.MyCommonValue

হালনাগাদ

আপনি এমন কোনও পৃষ্ঠা এক্সটেনশনও তৈরি করতে পারেন যা আপনাকে ব্যবহার করতে দেয় this

//Allows typed "this.Controller()." in cshtml files
public static class MyPageExtensions {
    public static _BaseController Controller(this WebViewPage page) => Controller<_BaseController>(page);
    public static T Controller<T>(this WebViewPage page) where T : _BaseController => (T)page.ViewContext.Controller;
}

তারপরে আপনি this.Controller()যখন নিয়ামক চান তখন কেবল আপনাকে ব্যবহার করতে হবে ।

@{
    var myController = this.Controller(); //_BaseController
}

বা নির্দিষ্ট নিয়ামক যা উত্তরাধিকার সূত্রে প্রাপ্ত _BaseController...

@{
    var myController = this.Controller<MyControllerType>();
}

। নেট কোর এর সমতুল্য কি? ভিউ কনটেক্সট হিসাবে। নিয়ন্ত্রণকারী উপস্থিত নেই এবং উত্তরাধিকার শৃঙ্খলায় কিছুটা পরিবর্তন রয়েছে
জয়ন্ত থিয়াগারাজন

4

আপনি যদি পুরো মডেলটি পাস করতে চান তবে লেআউটে তেমন যান:

@model ViewAsModelBase
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta charset="utf-8"/>
    <link href="/img/phytech_icon.ico" rel="shortcut icon" type="image/x-icon" />
    <title>@ViewBag.Title</title>
    @RenderSection("styles", required: false)    
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
    @RenderSection("scripts", required: false)
    @RenderSection("head", required: false)
</head>
<body>
    @Html.Action("_Header","Controller", new {model = Model})
    <section id="content">
        @RenderBody()
    </section>      
    @RenderSection("footer", required: false)
</body>
</html>

এবং এটি নিয়ামকটিতে যুক্ত করুন:

public ActionResult _Header(ViewAsModelBase model)

4

আমি মনে করি না যে এগুলির কোনও উত্তর বড় এন্টারপ্রাইজ স্তরের অ্যাপ্লিকেশনের জন্য যথেষ্ট নমনীয়। আমি ভিউব্যাগকে অতিরিক্তভাবে ব্যবহার করার ভক্ত নই, তবে এই ক্ষেত্রে নমনীয়তার জন্য আমি একটি ব্যতিক্রম করব। আমি এখানে যা করব ...

আপনার সমস্ত কন্ট্রোলারের একটি বেস নিয়ামক থাকা উচিত। আপনার বেস কন্ট্রোলারে আপনার লেআউট ডেটা অনঅ্যাকশনএক্সেকটিং যুক্ত করুন (অথবা আপনি যদি এটি স্থগিত করতে চান তবে OnActionExecutes) ...

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext     
        filterContext)
    {
        ViewBag.LayoutViewModel = MyLayoutViewModel;
    }
}

public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View(homeModel);
    }
}

তারপরে আপনার _ লেআউট.একটিএসটিএমএলে ভিউব্যাগ থেকে আপনার ভিউমোডেলটি টানুন ...

@{
  LayoutViewModel model = (LayoutViewModel)ViewBag.LayoutViewModel;
}

<h1>@model.Title</h1>

অথবা ...

<h1>@ViewBag.LayoutViewModel.Title</h1>

এটি করা আপনার পৃষ্ঠার নিয়ন্ত্রক বা মডেলগুলি দেখার কোডিংয়ের সাথে হস্তক্ষেপ করে না।


আমি আপনার ধারণাটি পছন্দ করি তবে আপনি যদি MyLayoutViewModelগতিশীলভাবে তৈরি করেন তবে কীভাবে আমি কিছু পরামিতিগুলি OnActionExecutingপদ্ধতিতে পাস করতে পারি ?
রাজমন্ড বুরগাজ

1
আহ, আপনার এখনও base.OnActionExecuting(filterContext)আপনার OnActionExecutingপদ্ধতিতে প্রয়োজন !!!
এরিক

4

লেআউট ভিউ মডেলটি উপস্থাপন করে এমন একটি বেস ভিউ তৈরি করা একটি ভয়ানক পদ্ধতির। কল্পনা করুন যে আপনি এমন একটি মডেল রাখতে চান যা বিন্যাসে সংজ্ঞায়িত নেভিগেশনের প্রতিনিধিত্ব করে। আপনি কি করবেন CustomersViewModel : LayoutNavigationViewModel? কেন? সমাধানে থাকা প্রতিটি একক দর্শন মডেলের মাধ্যমে আপনি কেন নেভিগেশন মডেল ডেটা পাস করবেন?

লেআউট ভিউ মডেলটি নিজেই উত্সর্গ করা উচিত এবং বাকি ভিউ মডেলগুলিকে তার উপর নির্ভর করতে বাধ্য করা উচিত নয়।

পরিবর্তে, আপনি নিজের _Layout.cshtmlফাইলে এটি করতে পারেন :

@{ var model = DependencyResolver.Current.GetService<MyNamespace.LayoutViewModel>(); }

সর্বাধিক গুরুত্বপূর্ণ, আমাদের দরকার নেই new LayoutViewModel()এবং আমরা LayoutViewModelআমাদের জন্য নিযুক্ত সমস্ত নির্ভরতা পেয়ে যাব ।

যেমন

public class LayoutViewModel
{
    private readonly DataContext dataContext;
    private readonly ApplicationUserManager userManager;

    public LayoutViewModel(DataContext dataContext, ApplicationUserManager userManager)
    {
    }
}

আপনি এই মডেলটি কোথায় পূরণ করবেন? একটি বেসকন্ট্রোলারে পাশাপাশি?
এনডিবার্গ

আমি Scopedভাবছি এটিএসপি.. নেট কোরতেও একটি বিন্যাস মডেল অবজেক্টের জন্য এটি একটি ভাল ধারণা হবে ।
জেমস উইলকিনস

আমার দৃষ্টিভঙ্গি কোনও নির্ভরতা আনতে চাইবে না। এটি অবশ্যই "এমভিসি" নয়। পরিষেবা লোকেটার একটি অ্যান্টি-প্যাটার্ন
Jiveman

জনপ্রিয় বিশ্বাসের বিপরীতে, সার্ভিস লোকেটার একটি বিরোধী-নিদর্শন নয় এবং আসলে এমভিসির সাথে এটির কোনও যোগসূত্র নেই, আপনি কি কেবল জিভম্যানকে গুঞ্জন শব্দে ছুড়ছেন? blog.gauffin.org/2012/09/service-locator-is-not-an-anti-pattern
হায়ানকভ

জাগাফিনের এই নিবন্ধটির মূল বিষয়টি মনে হচ্ছে যে "অ্যান্টি-প্যাটার্ন" শব্দটি পরিষেবা লোকেটারের জন্য প্রয়োগ করা উচিত নয়, কারণ এসএল-এর কমপক্ষে কিছু বৈধ ব্যবহার থাকতে পারে। একটি সুস্পষ্ট পয়েন্ট। তবে তাঁর নিজের আলোচনার কয়েকটি মন্তব্যে যেমন স্পষ্ট হয়, তিনি পরামর্শ দিয়েছেন যে গ্রন্থাগার ও ফ্রেমওয়ার্ক তৈরি করার সময় এসএল একটি বৈধ পন্থা হতে পারে, তবে অ্যাপ্লিকেশনগুলি তৈরি করার সময় এটি অগত্যা সুপারিশ করা হয় না (যা আমি ওপির প্রশ্ন এবং এই আলোচনাটি এখানে বিবেচনা করব) চারদিকে ঘোরে)।
Jiveman

3

অন্যান্য উত্তরগুলি কীভাবে আমরা আমাদের লেআউট পৃষ্ঠায় মডেলটি পাস করতে পারি সে সম্পর্কে অনেক কিছুই .েকে ফেলেছে। তবে আমি এমন একটি উপায় পেয়েছি যার সাহায্যে আপনি আপনার বিন্যাসে কোনও মডেল বা আংশিক দৃষ্টিভঙ্গি ব্যবহার না করেই আপনার লেআউট পৃষ্ঠায় পরিবর্তনশীলগুলি প্রেরণ করতে পারবেন। আমাদের বলুন যে আপনার কাছে এই মডেল রয়েছে -

public class SubLocationsViewModel
{
    public string city { get; set; }
    public string state { get; set; }
}

এবং আপনি গতিশীলভাবে শহর এবং রাজ্য পেতে চান। যেমন যেমন

আপনার ইনডেক্স.সিএসটিএমএলে আপনি এই দুটি ভেরিয়েবল ভিউব্যাগে রাখতে পারেন

@model  MyProject.Models.ViewModel.SubLocationsViewModel
@{
    ViewBag.City = Model.city;
    ViewBag.State = Model.state;
}

এবং তারপরে আপনার বিন্যাসে। Shtml এ আপনি সেই ভিউব্যাগ ভেরিয়েবলগুলি অ্যাক্সেস করতে পারেন

<div class="text-wrap">
    <div class="heading">@ViewBag.City @ViewBag.State</div>
</div>

এটি দুর্দান্ত কাজ করে, @ স্টুন_গ্রাভিউ কি ভূমিকা বা ব্যবহারকারীর অ্যাক্সেস স্তরের মতো ডেটা পাস করতে ভিউব্যাগ ব্যবহার করে কোনও পতন আছে?
3not3

3

এটি পরিচালনা করার আরও একটি উপায় আছে। কোনও স্থাপত্য দৃষ্টিকোণ থেকে পরিষ্কার উপায় নাও হতে পারে, তবে এটি অন্যান্য উত্তরের সাথে জড়িত প্রচুর ব্যথা এড়িয়ে চলে। কেবল রেজার লেআউটে একটি পরিষেবা ইনজেক্ট করুন এবং তারপরে একটি পদ্ধতিতে কল করুন যা প্রয়োজনীয় ডেটা পায়:

@inject IService myService

তারপরে পরে লেআউট ভিউতে:

@if (await myService.GetBoolValue()) {
   // Good to go...
}

আবার, আর্কিটেকচারের দিক থেকে পরিষ্কার নয় (স্পষ্টতই পরিষেবাটি সরাসরি দৃষ্টিতে ইঞ্জেকশন করা উচিত নয়), তবে এটি কাজটি করে gets


সবচেয়ে পরিষ্কার উপায় না? আমি একমত নই আমি মনে করি এটি যতটা পরিষ্কার পায় ততই পরিষ্কার: অবজেক্টটি যেখানে যেখানে আপনি তৈরি করতে চান সেখানে সরাসরি তৈরি করা হয়, অন্য কন্ট্রোলারদের যে আইটেমগুলি দেখার প্রয়োজন হয় না তার সাথে "দূষণকারী" না করেই এটি স্থানটি চলে যায়। @injectআমার মতে ব্যবহার করা সবচেয়ে ভাল সমাধান।
dasblinkenlight

1
এই সম্পর্কে আরও চিন্তা করা হয়ত আপনি ঠিক বলেছেন। এই পদ্ধতিটি এত বেশি ব্যথা এড়িয়ে চলেছে এমন একটি চিহ্ন এটি সম্ভবত এটি সবচেয়ে পরিষ্কার উপায়। আমি একটি খুব বড় এএসপি.নেট কোর অ্যাপটিতে কাজ করছি এবং আমি নেভিগেশন ব্রেডক্রাম্বিক লজিক, বেশিরভাগ পৃষ্ঠায় থাকা শিরোনামের ডেটা, এই জাতীয় জিনিসগুলির জন্য এই প্যাটার্নটি ব্যবহার করছি। পরিবর্তে এইভাবে করে এত ব্যথা এড়ানো করেছি।
অ্যান্ড্রু

2

আপনি রেন্ডারসেকশনটিও ব্যবহার করতে পারেন , এটি আপনাকে আপনার Modelডেটা _Layoutভিউতে ইনজেক্ট করতে সহায়তা করে ।

আপনি উদ্বুদ্ধ করতে পারেন View Modelতথ্য, Json, Script, CSS, HTMLইত্যাদি

এই উদাহরণে আমি Jsonআমার Indexভিউ থেকে Layoutভিউতে ইনজেকশন দিচ্ছি ।

Index.chtml

@section commonLayoutData{

    <script>

        var products = @Html.Raw(Json.Encode(Model.ToList()));

    </script>

    }

_Layout.cshtml

@RenderSection("commonLayoutData", false)

এটি একটি পৃথক বেস তৈরি করার প্রয়োজনকে সরিয়ে দেয় View Model

আশা কাউকে সাহায্য করে।


1
নিখুঁত সমাধান যখন আপনাকে কেবলমাত্র কয়েকটি দর্শনের জন্য নির্দিষ্ট কিছু রেন্ডার করতে হয়।
কুণাল

1

আমি যা করেছি তা খুব সহজ এবং এটি কাজ করে

যে কোনও নিয়ামক স্থিতিশীল সম্পত্তি ঘোষণা করুন বা আপনি যদি এটি চান তবে স্থির মান সহ একটি ডেটা-শ্রেণি তৈরি করতে পারেন:

public static username = "Admin";
public static UserType = "Administrator";

এই মানগুলি অপারেশনের ভিত্তিতে নিয়ন্ত্রণকারীরা আপডেট করতে পারে। পরে আপনি এগুলি আপনার _ লেআউটটিতে ব্যবহার করতে পারেন

_Layout.cshtml এ

@project_name.Controllers.HomeController.username
@project_name.Controllers.HomeController.UserType

1
এটি আরও পরিষ্কার এবং বোধগম্য করার জন্য, আপনার উত্তরে কিছু ব্যাখ্যা যুক্ত করা সর্বদা সহায়ক। দয়া করে স্ট্যাকওভারফ্লো . com/help/how-to-answer পড়ুন
32cupo

0

কেন ভিউডাটাতে কেউ এক্সটেনশন পদ্ধতিগুলি প্রস্তাব দেয়নি?

বিকল্প 1

আমার কাছে এ পর্যন্ত সমস্যাটির সর্বনিম্ন অন্তর্ভুক্তি এবং সহজ সমাধান বলে মনে হচ্ছে। কোনও হার্ডকোডযুক্ত স্ট্রিং নেই। কোন আরোপিত বাধা নেই কোনও ম্যাজিক কোডিং নেই। জটিল কোড নেই।

public static class ViewDataExtensions
{
    private const string TitleData = "Title";
    public static void SetTitle<T>(this ViewDataDictionary<T> viewData, string value) => viewData[TitleData] = value;
    public static string GetTitle<T>(this ViewDataDictionary<T> viewData) => (string)viewData[TitleData] ?? "";
}

পৃষ্ঠায় ডেটা সেট করুন

ViewData.SetTitle("abc");

বিকল্প # 2

আরেকটি বিকল্প, ক্ষেত্রের ঘোষণা আরও সহজ করে।

public static class ViewDataExtensions
{
    public static ViewDataField<string, V> Title<V>(this ViewDataDictionary<V> viewData) => new ViewDataField<string, V>(viewData, "Title", "");
}

public class ViewDataField<T,V>
{
    private readonly ViewDataDictionary<V> _viewData;
    private readonly string _field;
    private readonly T _defaultValue;

    public ViewDataField(ViewDataDictionary<V> viewData, string field, T defaultValue)
    {
        _viewData = viewData;
        _field = field;
        _defaultValue = defaultValue;
    }

    public T Value {
        get => (T)(_viewData[_field] ?? _defaultValue);
        set => _viewData[_field] = value;
    }
}

পৃষ্ঠায় ডেটা সেট করুন। ঘোষণা প্রথম বিকল্পের চেয়ে সহজ তবে ব্যবহার সিনট্যাক্সটি কিছুটা দীর্ঘ।

ViewData.Title().Value = "abc";

বিকল্প # 3

তারপরে এটি তাদের ডিফল্ট মানগুলির সাথে সমস্ত লেআউট-সম্পর্কিত ক্ষেত্র সমেত একটি একক বস্তু ফেরার সাথে একত্রিত করতে পারে।

public static class ViewDataExtensions
{
    private const string LayoutField = "Layout";
    public static LayoutData Layout<T>(this ViewDataDictionary<T> viewData) => 
        (LayoutData)(viewData[LayoutField] ?? (viewData[LayoutField] = new LayoutData()));
}

public class LayoutData
{
    public string Title { get; set; } = "";
}

পৃষ্ঠায় ডেটা সেট করুন

var layout = ViewData.Layout();
layout.Title = "abc";

এই তৃতীয় বিকল্পটির বেশ কয়েকটি সুবিধা রয়েছে এবং আমি মনে করি বেশিরভাগ ক্ষেত্রে সেরা বিকল্প:

  • ক্ষেত্র এবং ডিফল্ট মানগুলির সহজ ঘোষণা।

  • একাধিক ক্ষেত্র সেট করার সময় সহজ ব্যবহার বাক্য গঠন।

  • ভিউডাটাতে বিভিন্ন ধরণের ডেটা সেট করার অনুমতি দেয় (উদাঃ লেআউট, শিরোনাম, নেভিগেশন)।

  • লেআউটডেটা ক্লাসের মধ্যে অতিরিক্ত কোড এবং যুক্তিকে মঞ্জুরি দেয়।

পিএস _ভিউআইম্পোর্টস সিটিএসটিএমএলে ভিউডাটাএক্সটেনশনের নেমস্পেস যুক্ত করতে ভুলবেন না


0

আপনি অ্যাপ_ কোড ফোল্ডারে একটি রেজার ফাইল তৈরি করতে পারেন এবং তারপরে আপনার দর্শন পৃষ্ঠাগুলি থেকে এটি অ্যাক্সেস করতে পারেন।

প্রকল্প> সংগ্রহস্থলের প্রয়োগ / IdentityRepository.cs

namespace Infrastructure.Repository
{
    public class IdentityRepository : IIdentityRepository
    {
        private readonly ISystemSettings _systemSettings;
        private readonly ISessionDataManager _sessionDataManager;

        public IdentityRepository(
            ISystemSettings systemSettings
            )
        {
            _systemSettings = systemSettings;
        }

        public string GetCurrentUserName()
        {
            return HttpContext.Current.User.Identity.Name;
        }
    }
}

প্রকল্প> App_Code / IdentityRepositoryViewFunctions.cshtml:

@using System.Web.Mvc
@using Infrastructure.Repository
@functions
{
    public static IIdentityRepository IdentityRepositoryInstance
    {
        get { return DependencyResolver.Current.GetService<IIdentityRepository>(); }
    }

    public static string GetCurrentUserName
    {
        get
        {
            var identityRepo = IdentityRepositoryInstance;
            if (identityRepo != null)
            {
                return identityRepo.GetCurrentUserName();
            }
            return null;
        }
    }
}

প্রকল্প> দর্শন / ভাগ / _ লেআউট.একএসটিএমএল (বা অন্য কোনও। Cshtml ফাইল)

<div>
    @IdentityRepositoryViewFunctions.GetCurrentUserName
</div>

-1

এর পরিবর্তে আপনি সর্বদা অন্য পদ্ধতির ব্যবহার করতে পারেন যা দ্রুতও

ভাগ করা ডিরেক্টরিতে একটি নতুন আংশিক দৃশ্য তৈরি করুন এবং আপনার বিন্যাসে আপনার আংশিক দৃশ্যটিকে কল করুন

@Html.Partial("MyPartialView")

আপনার আংশিক দৃশ্যে আপনি আপনার ডিবিতে কল করতে পারেন এবং আপনি যা করতে চান তা করতে পারেন

@{
    IEnumerable<HOXAT.Models.CourseCategory> categories = new HOXAT.Models.HOXATEntities().CourseCategories;
}

<div>
//do what ever here
</div>

ধরে নিচ্ছি আপনি নিজের সত্ত্বা ফ্রেমওয়ার্ক ডেটাবেস যুক্ত করেছেন


1
ডাউনকাস্টিং হিসাবে এটির নিজের মডেলটি পাওয়ার ভিউর দায় কখনই হওয়া উচিত নয়।
অক্সনহ্যামার

-1

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


@ কোডস্মিত কি? আমি একটি সমাধান প্রদান করছি।
মকোর

আমার খারাপ, ভেবেছিল এটি একটি প্রশ্ন তবে দেখুন এটি এখন একটি প্রতিক্রিয়া, মুছে ফেলা হয়েছে।
কোডস্মিত

যদি প্রশ্নের উত্তর দেওয়ার চেষ্টা করা হয় তবে তা স্পষ্ট করে দেওয়া উচিত। ভাষ্য সহ্য করা হয় তবে এটি পুরো উত্তরকে প্রাধান্য দেওয়া উচিত নয়; এছাড়াও, কী গুগল করবেন তার পরামর্শগুলি কোনও বৈধ উত্তর গঠন করে না।
ট্রিপলি

-6

আপনি এটির মতো ব্যবহার করতে পারেন:

 @{ 
    ApplicationDbContext db = new ApplicationDbContext();
    IEnumerable<YourModel> bd_recent = db.YourModel.Where(m => m.Pin == true).OrderByDescending(m=>m.ID).Select(m => m);
}
<div class="col-md-12">
    <div class="panel panel-default">
        <div class="panel-body">
            <div class="baner1">
                <h3 class="bb-hred">Recent Posts</h3>
                @foreach(var item in bd_recent)
                {
                    <a href="/BaiDangs/BaiDangChiTiet/@item.ID">@item.Name</a>
                }
            </div>
        </div>
    </div>
</div>

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