我已经获得了以下可能包含15个不同页面的Razor代码片段,如果可能的话我还想重复使用:
<body>
<div>
@foreach( var item in @VieuBag.Nm)
{
<h3>one</h3>
}
</div>
</body>
我希望能够做的是调用一个方法并让方法返回我在Razor .cshtml文件中的代码。该方法还必须接受参数。在这种情况下,参数将是0到5之间的评级值。然后,我将用参数值替换所有出现的@ Model.Rating。是否有可能做到这一点?如果可能的话,我不必采用部分视图。
答案 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">