gpt4 book ai didi

c# - 结合类属性参数和插入到 ViewData 的继承

转载 作者:行者123 更新时间:2023-11-30 16:50:34 26 4
gpt4 key购买 nike

问题仅用于教育目的。

我有一个 MVC 应用程序,它有 3 个 Web Journeys,它们在许多方面相互镜像 - 这使得引入处理公共(public)部分的基类变得很方便。

我还使用了很多被放入 viewData 中的类属性这使得在旅程之间重用 View 时变得很方便,我可以在每个旅程中插入不同的电话号码(或其他位),而无需在每个 viewModel 中继承此数据,因为每个旅程都是相同的(如图所示无法放置到母版页中)在许多不同的观点)。在生成电子邮件等时,这些常量也用在代码中。

[LayoutViewData(ContactNumber = ContactNumber, LegalType = LegalType, LegalReference = LegalReference)]
public class JourneyController : BaseJourneyController
{
private const string ContactNumber = "0800 161 5191";
private const string ContactNumberForPricingPage = "0800 051 3322";
private const string ProductReference = "LS0083";
private const string LegalReference = "conveyancing";
}


public class LayoutViewDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.Controller.ViewData.Add("ContactNumber", this.ContactNumber);
}
...
}

我正在尝试解决的问题:

有些方法在旅程中几乎相同,可以移至基础,但它们需要来自常量的值。问题是只有静态可以传递给属性,这意味着我不能简单地将它们更改为仅具有 setter/getter 的抽象属性并继续我的生活。

我的选择:

  1. 更改方法签名以将这些常量传递给方法 - 我不喜欢这样,因为必须将数据传递给基类表明实现应该在类本身中进行。

  2. 引入抽象的 Get 方法,然后返回常量以用于基类,例如。

    protected override string GetContactNumber()
    {
    return ContactNumber;
    }

    我不喜欢没有办法强制返回那些特定的常量,感觉有点老套,但恕我直言,这是最省力的最佳解决方案。

  3. 摆脱常量和属性,引入具有抽象属性的 BaseViewModel 类,以及为每个旅程设置值的一种机制。或者可以是 3 个已经设置了这些属性的基类。 - 不喜欢,很多替代品。

您能想出一些其他的解决方案,以最少的工作量和最少的黑客攻击来解决我的情况。

最佳答案

我认为您这里的主要问题是您将属性用于不适合的目的。属性用于将元数据添加到代码构造中。但是您正在使用它们来附加数据,这些数据通常应该是实际对象定义的一部分(作为属性 getter )。

此外,我认为您不一定非得求助于类继承才能提出适用于这种情况的设计。但如果您需要,此解决方案仍然有效。

独立接口(interface)

如果将每条数据分解成其自己的接口(interface),则可以利用一个类可以实现多个接口(interface)的事实来根据需要覆盖默认值。

public interface IContactNumber
{
string ContactNumber { get; }
}

单独的 Action 筛选器

与其继承具有自身内置限制的 ActionFilterAttribute,不如实现 IActionFilter 以从等式中删除不必要的属性。

public class ContactNumberActionFilter : IActionFilter
{
private readonly string defaultContactNumber;

public ContactNumberActionFilter(string defaultContactNumber)
{
this.defaultContactNumber = defaultContactNumber;
}

public void OnActionExecuted(ActionExecutedContext filterContext)
{
// No implementation
}

public void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = filterContext.Controller;
var provider = controller as IContactNumber;
var contactNumber = (provider == null) ? this.defaultContactNumber : provider.ContactNumber;

controller.ViewData.Add("ContactNumber", contactNumber);
}
}

那么只需在全局范围内注册您的过滤器即可。

public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());

// Register the action filter globally and provide a default number
filters.Add(new ContactNumberActionFilter("0800 161 5191"));

// TODO: Make filters for ContactNumberForPricingPage,
// ProductReference, and LegalReference and set their default
// values here.
}
}

用法

现在,如果您想覆盖默认联系电话,您只需在 Controller 中实现 IContactNumber。如果您不实现此接口(interface),将使用默认号码。

public class HomeController : Controller, IContactNumber
{
public string ContactNumber
{
get { return "0800 161 5192"; }
}

public ActionResult Index()
{
return View();
}
}

请注意,您可以还添加一种方法来打开或关闭此功能,方法是使用属性并在将 ContactNumber 添加到 之前测试其存在ViewData 如果你真的需要一个开/关开关。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ContactNumberAttribute : Attribute
{
}

关于c# - 结合类属性参数和插入到 ViewData 的继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34919921/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com