asp.net-mvc - شرح - mvc ماهو




كيفية تصفية نتيجة في مفك 4 على أساس المستخدم (5)

النهج - 1

وظيفة

private void userInfo(ResultExecutingContext filtercontext)
{                                        
    if (filtercontext.Controller.TempData[userId.ToString()] == null)
        filtercontext.Controller.ViewBag.userId =
            filtercontext.Controller.TempData[userId.ToString()] = 
            repository.GetAll().Where(x => x.Id == userId);

    else      //This will load the data from TempData. So, no need to 
              //hit DataBase.
        filtercontext.Controller.ViewBag.userId =
            filtercontext.Controller.TempData[userId.ToString()];

    TempData.Keep();  // This will save your Database hit.
}

طريقة التصفية

public class MyActionFilter : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filtercontext)
    {
        //Call the Action Method before executing the View and after 
        //executing the Action.
        userInfo(filtercontext);
        base.OnResultExecuting(filtercontext);
    }
}

طريقة عمل وحدة التحكم

[MyActionFilter] 
//Whenever Action Method will execute. We will check TempData contains 
//Data or not.
public ActionResult Index()
{
    return View();
}

النقطة الرئيسية حول TempData و TempData.Keep()

  1. سيتم وضع علامة على العناصر في TempData فقط للحذف بعد قراءتها.
  2. العناصر في TempData يمكن أن تكون غير TempData عن طريق استدعاء TempData.Keep(key) .
  3. TempData.Keep() يدعو دائما TempData.Keep() للاحتفاظ العناصر في TempData .

يمكنك استخدام متغير Session أيضا، المشكلة الرئيسية الوحيدة هي أن متغير Session ثقيلة جدا مقارنة مع TempData . وأخيرا كنت قادرا على الحفاظ على البيانات عبر وحدات التحكم / المنطقة أيضا.

TempData يعمل في علامات تبويب جديدة / ويندوز أيضا، مثل متغير Session لا.

النهج - 2

يمكنك Cache البيانات في بعض المتغيرات ويمكن إعادة استخدامها مرة أخرى بنفس الطريقة التي تم القيام بها ل TempData .

لدي أوثنتانتيون العرف، عندما يسجل المستخدم في، وأظل المعلومات اللازمة على جلسة / ذاكرة التخزين المؤقت ...

لذلك، لدي بعض المشاهدات مع دروبدونز التي يجب أن تظهر البيانات التي تمت تصفيتها بواسطة معرف المستخدم ... أود أن أعرف ما هي أفضل طريقة لتصفية هذه النتيجة ...

1 - مباشرة على المراقب المالي؟

...   
Model.MyList = repository.GetAll().Where(x => x.User.Id == userId);
return View(Model);

2 - إنشاء عامل تصفية عامل (كيف يمكنني القيام بذلك دون الاستعلام عن البيانات غير الضرورية من دب)

3 - طريقة أخرى؟

المشكلة مع 1 هو أن لدي عدة وجهات نظر التي لها نفس القائمة المنسدلة، ولذا فإنني سوف تضطر إلى تكرار نفس التعليمات البرمجية.


أفضل طريقة: الحصول على قائمة مخبأة من جميع المستخدمين. +: كفاءة قاعدة البيانات. -: يستخدم الكثير من الذاكرة إذا طاولة كبيرة. -: النتيجة ليست حتى الآن (ضبط الوقت ذاكرة التخزين المؤقت).

في أوداتا هناك مرشح طلب قاعدة بيانات الذي يفعل هذا الفلتر، ولكن ليس المقصود أن يتم استخدامها بالطريقة التي تريدها. انها هنا للحماية من الأخطاء في بروكس المخزنة والاستفسارات التي ترجع الصفوف التي لم يتم المصرح بها لهذا المستخدم. هذا هو المستوى الثاني من الحماية ضد البيانات "التسريبات".

var model = new Model(userId)

في مكان آخر:

Model(Guid userID)
{
    MyList = CacheStore.Get("allUsers", () => repository.GetAll())
                .Where(x => x.Id == userId).ToList();
}

تنويه: أنا مؤلف الكيان ريست سك.

أخذت نهجا مختلفا وخلقت سياق الأمان الذي يحتوي على كل ما يلزم من عبارات لامدا التي ينبغي تطبيقها قبل الاستعلام عن أي شيء.

    public class DefaultSecurityContext : BaseSecurityContext {

      public static DefaultSecurityContext Instance = new DefaultSecurityContext();

      // UserID for currently logged in User
      public static long UserID{
           get{
                 return long.Parse( HttpContext.Current.User.Identity.Name );
           }
      }

      public DefaultSecurityContext(){
      }

      protected override void OnCreate(){

            // User can access his own Account only
            var acc = CreateRules<Account>();

            acc.SetRead( y => x=> x.AccountID == UserID ) ;
            acc.SetWrite( y => x=> x.AccountID == UserID );

            // User can only modify AccountName and EmailAddress fields
            acc.SetProperties( SecurityRules.ReadWrite, 
                  x => x.AccountName,
                  x => x.EmailAddress);

            // User can read AccountType field
            acc.SetProperties<Account>( SecurityRules.Read, 
                  x => x.AccountType);

            // User can access his own Orders only
            var order = CreateRules<Order>();
            order.SetRead( y => x => x.CustomerID == UserID );

            // User can modify Order only if OrderStatus is not complete
            order.SetWrite( y => x => x.CustomerID == UserID && x.OrderStatus != "Complete" );

            // User can only modify OrderNotes and OrderStatus
            order.SetProperties( SecurityRules.ReadWrite, 
                  x => x.OrderNotes,
                  x => x.OrderStatus );

            // User can not delete orders
            order.SetDelete(order.NotSupportedRule);
      }
}

كما ترون، يمكننا تصفية أسفل الوصول إلى خصائص كذلك.

في حالة يتم استبدال معظم رمز مكررة الخاص بك مع سياق الأمان، يمكنك إنشاء سياق أمان مختلفة وفقا لدور المستخدم مختلفة & لا تزال تحت نفس وحدة تحكم.

public class OrdersController : WebAtomsController <MyEntities> {
        protected override BaseSecurityContext CreateSecurityContext(){
             return DefaultSecurityContext.Instance;
        }

        public ActionResult SearchOrders( 
               string productName, 
               string orderBy = "OrderID DESC", 
               int start = 0, 
               int size = 10)
        {
               // Where method automatically applies
               // filter based on current SecurityContext

               var aq = Where<Order>();
               if(!string.IsNullOrEmpty(productName)){
                      aq = aq.Where( 
                                  x=> x.OrderItems.Any( 
                                     y=> y.Product.ProductName.StartsWith(productName)));
               }

               // OrderBy accepts string as a parameter
               aq = aq.OrderBy(orderBy);
               return aq.Page(start,size).Select( 
                     y=> new {
                            y.OrderID,
                            y.OrderDate,
                            y.OrderStatus,
                     });
        }
}

لمزيد من التفاصيل، يرجى زيارة https://entityrestsdk.codeplex.com


على سبيل المثال، يمكنك إنشاء فئة ميمبرشيبلوجيك وتحديد كل الطرق التي تستخدمها الآن أو قد تستخدم في المستقبل. سوف الدرجة يعود لك أي بيانات بواسطة أوسيريد

حتى في وحدة تحكم الخاص بك وسوف تبدو مثل:

var db = new DbEntities();
List<a> newList = MembershipLogic.UserList(db, userid);

و في ميمبرشيبلوجيك كنت من الحاجة اتباع الأسلوب:

public static List<a> UserList(DbEntities db, int UserID)
{
var list = db.GetAll().Where(x => x.Id == userId);
return list;
}

أنا استخدم هذا المنطق في مشاريعي. تراكم الطرق واستخدامها إيفيريثير أحتاج.


هذا سيناريو افتراضي جميل تريد من المستخدم مشاهدة البيانات ذات الصلة به فقط.

شخصيا، لم أكن أبدا دب المكالمات داخل وحدة تحكم، وكان دائما داتالاير إضافية التي سلكي مع حاوية أوك.

يجب أن يعرف هذا داتالاير قاعدة البيانات وكيفية تخزين البيانات فقط، وتصفية هذه البيانات بشكل صحيح. يمكنك أن تجادل إذا كان داتالاير يمكن استخدام هتبكونتيكست لاسترداد معرف المستخدم تلقائيا أو يجب الحصول عليه كوسيطة.

حتى لا يكون لديك الكتابة دائما هذا التعبير يمكنك أيضا إنشاء وظيفة، والتي سوف تعطيك الصحيح حيث لامبدا التعبير ويمكنك ببساطة استخدامه:

public Expression<TModel> GetUserFilter<TModel>()
{
    var userId = GetUserId();
    var itemParameter = Expression.Parameter(typeof(TModel), "item");
    var whereExpression = Expression.Lambda<Func<TModel, bool>>
        (
        Expression.Equal(
            Expression.Property(
                itemParameter,
                "Id"
                ),
            Expression.Constant(userId)
            ),
        new[] { itemParameter }
        );
    return whereExpression;
}

والآن يمكنك استدعاء هذه الوظيفة في لك تحكم أو داتالاير:

Model.MyList = repository.GetAll().Where(GetUserFilter<Repository>());

يمكنك بالطبع تغيير الأسماء وجعلها أقصر بحيث انها في الواقع أقل لكتابة :)





asp.net-mvc-4