MVC Razor代码重用 - 此代码可以重用吗?

时间:2015-11-21 19:02:08

标签: asp.net-mvc razor

我已经获得了以下可能包含15个不同页面的Razor代码片段,如果可能的话我还想重复使用:

<body>
    <div>
        @foreach( var item in @VieuBag.Nm)
        {
            <h3>one</h3>
        }
    </div>
</body>

我希望能够做的是调用一个方法并让方法返回我在Razor .cshtml文件中的代码。该方法还必须接受参数。在这种情况下,参数将是0到5之间的评级值。然后,我将用参数值替换所有出现的@ Model.Rating。是否有可能做到这一点?如果可能的话,我不必采用部分视图。

3 个答案:

答案 0 :(得分:2)

  

我希望能够做的是调用一个方法并让方法返回我在Razor .cshtml文件中的代码。该方法还必须接受参数。在这种情况下,参数将是0到5之间的评级值。然后,我将用参数值替换所有出现的@ Model.Rating。是否有可能做到这一点?

解决方案1:

您可以像这样创建HtmlHelper类的扩展方法:

public static class RatingExtensions
{
    public static MvcHtmlString Rating(this HtmlHelper helper, short rating)
    {
        var imageSrc = "/Images/Rating/";
        switch (rating)
        {
            case 0:
                imageSrc += "NoRating.jpg";
                break;

            case 1:
                imageSrc += "One.jpg";
                break;


            // And so on....

            default:
                throw new IndexOutOfRangeException(string.Format("The following rating: {0} is not expected.",
                    rating));
        }

        return new MvcHtmlString(String.Format("<img src='{0}' alt='' width='125' />", imageSrc));
    }
}

在将扩展方法的命名空间导入视图后的视图中,您可以通过编写以下行来调用扩展方法:

@Html.Rating(Model.Rating)

解决方案2:

只需创建一个局部视图并将其放入Views文件夹的Shared子文件夹中。让我们将其命名为_Ratring.cshtml。该文件的内容如下(注意@model指令,其中short类型):

@model short
@{
    var imageSrc = "/Images/Rating/";
    switch (Model)
    {
        case 0:
            imageSrc += "NoRating.jpg";
            break;

        case 1:
            imageSrc += "One.jpg";
            break;

        // And so on....

        default:
            throw new IndexOutOfRangeException(string.Format("The following rating: {0} is not expected.",
                Model));
    }
}

<div class="col-xs-12">
    <img src="@imageSrc" alt="" width="125">
</div>

您可以通过调用Html.RenderPartial方法在视图中使用此解决方案:

@{
    Html.RenderPartial("_Rating", Model.Rating);
}

解决方案1 ​​更好,因为您可以在自己的程序集项目中移动扩展方法,并在多个项目中使用它。

答案 1 :(得分:1)

选项1

您可以创建自定义Html帮助程序方法。我更喜欢将图像名称从One.jpg重命名为1.jpg,这样您就不需要从传递给该字符串表示的数字中编写太多代码。您可以简单地将Model.Rating值与图像名称直接匹配。

但是如果您仍然希望将图像名称保留为字符串方式,则可能需要在方法内部编写一个switch语句,以将整数值转换为字符串值(1到1,2到2等...) 。这种方法的问题是,如果您添加了新的评级,如12或13,则需要转到此文件并再次更新switch语句!所以我更喜欢第一种重命名图像名称以匹配Model.Rating

的数字表示的方法
public static class MyCustomImageExtensions
{
    public static MvcHtmlString RatingImage(this HtmlHelper helper, int imageId,
                                                                      string alt,int width)
    {
        var path = "Images/Rating/NoRating.jpg";
        if (imageId > 0)
        {
            path = string.Format("Images/Rating/{0}.jpg", imageId);
        }
        return new MvcHtmlString(string.Format("<img src='{0}' alt='{1}' width='{2}'>"
                                                                  , path, alt, width));

    }
}

你可以在你的剃刀视图中调用它,如

@Html.RatingImage(Model.Rating,"alt test",250)

您可以将Alternate文本属性和宽度添加到模型中,这样就不需要在主视图中对其进行硬编码。

选项2

由于你在辅助方法中没有做太多逻辑,你可以简单地使用部分视图,在那里你将拥有你想要使用的标记,并将模型属性传递给它。

答案 2 :(得分:-1)

我会改变很多,但这确实值得。创建自己的ModelMetadataProvider

INFO 6944 --- [main] config.Application: .... Fetching books
INFO 6944 --- [main] config.Application: isbn-1234 -->
Getting from DB
INFO 6944 --- [main] config.Application: Book [isbn=isbn-1234, title=Some book, author=models.Author@15587018]
INFO 6944 --- [main] config.Application: isbn-4567 -->
Getting from DB
INFO 6944 --- [main] config.Application: Book [isbn=isbn-4567, title=Some book, author=models.Author@15587018]

在global.asax中注册

public class MyModelMetaDataProvider : DataAnnotationsModelMetadataProvider
{
    public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName)
    {
        var result = base.GetMetadataForProperty(modelAccessor, containerType, propertyName);

        if (string.IsNullOrEmpty(result.TemplateHint)
            && typeof(Enum).IsAssignableFrom(result.ModelType))
        {
            result.TemplateHint = result.ModelType.ToString();
        }

        return result;
    }
}

创建一个枚举:

ModelMetadataProviders.Current = new MyModelMetaDataProvider();

更新您的模型

public enum StarRating
{
    NoRating = 0,
    One = 1,
    Two = 2,
    Three = 3,
    Four = 4,
    Five = 5
}

创建展示广告模板

/Views/Shared/DisplayTemplates/StarRating.cshtml

public class SomeMethodViewModel
{
  public StarRating Rating { get; set; }
}

在您看来:

@model StarRating

<img src="/Images/Rating/@(Model.ToString()).jpg" alt="" width="125">