问题
In MVC 4, you could install this package Twitter.bootstrap.mvc and this would add lots of HTML helpers.
Once istalled you could send alert to view right from controller.
For example:
public class AccountController : BaseController
{
public ActionResult AlertExample()
{
Success("This is a success alert");
Error("This is error alert");
Information("This is information alert");
...
etc.
}
}
This would send the success alert right from controller to the view.
Objective: Sending Growl Messages from controller
I've tried to implement same thing from the project I mentioned.
So, this is what I've added to my project.
Base controller that other controller derives from
public class BaseController : Controller
{
//
// GET: /Base/
public void Warning(string message)
{
TempData.Add(Alerts.WARNING, message);
}
public void Success(string message)
{
TempData.Add(Alerts.SUCCESS, message);
}
public void Information(string message)
{
TempData.Add(Alerts.INFORMATION, message);
}
public void Error(string message)
{
TempData.Add(Alerts.ERROR, message);
}
}
ControlGroupExtensionClass
namespace BootstrapSupport
{
public class ControlGroup : IDisposable
{
private readonly HtmlHelper _html;
public ControlGroup(HtmlHelper html)
{
_html = html;
}
public void Dispose()
{
_html.ViewContext.Writer.Write(_html.EndControlGroup());
}
}
public static class ControlGroupExtensions
{
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty)
{
return BeginControlGroupFor(html, modelProperty, null);
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty, object htmlAttributes)
{
return BeginControlGroupFor(html, modelProperty,
HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty, IDictionary<string, object> htmlAttributes)
{
string propertyName = ExpressionHelper.GetExpressionText(modelProperty);
return BeginControlGroupFor(html, propertyName, null);
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, string propertyName)
{
return BeginControlGroupFor(html, propertyName, null);
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, object htmlAttributes)
{
return BeginControlGroupFor(html, propertyName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, IDictionary<string, object> htmlAttributes)
{
var controlGroupWrapper = new TagBuilder("div");
controlGroupWrapper.MergeAttributes(htmlAttributes);
controlGroupWrapper.AddCssClass("control-group");
string partialFieldName = propertyName;
string fullHtmlFieldName =
html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(partialFieldName);
if (!html.ViewData.ModelState.IsValidField(fullHtmlFieldName))
{
controlGroupWrapper.AddCssClass("error");
}
string openingTag = controlGroupWrapper.ToString(TagRenderMode.StartTag);
return MvcHtmlString.Create(openingTag);
}
public static IHtmlString EndControlGroup(this HtmlHelper html)
{
return MvcHtmlString.Create("</div>");
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty)
{
return ControlGroupFor(html, modelProperty, null);
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty, object htmlAttributes)
{
string propertyName = ExpressionHelper.GetExpressionText(modelProperty);
return ControlGroupFor(html, propertyName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, string propertyName)
{
return ControlGroupFor(html, propertyName, null);
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, object htmlAttributes)
{
return ControlGroupFor(html, propertyName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, IDictionary<string, object> htmlAttributes)
{
html.ViewContext.Writer.Write(BeginControlGroupFor(html, propertyName, htmlAttributes));
return new ControlGroup(html);
}
}
public static class Alerts
{
public const string SUCCESS = "success";
public const string WARNING = "warning";
public const string ERROR = "error";
public const string INFORMATION = "info";
public static string[] ALL
{
get { return new[] { SUCCESS, WARNING, INFORMATION, ERROR }; }
}
}
}
ViewHelperExtensionClass
namespace BootstrapSupport
{
public static class DefaultScaffoldingExtensions
{
public static string GetControllerName(this Type controllerType)
{
return controllerType.Name.Replace("Controller", String.Empty);
}
public static string GetActionName(this LambdaExpression actionExpression)
{
return ((MethodCallExpression)actionExpression.Body).Method.Name;
}
public static PropertyInfo[] VisibleProperties(this IEnumerable Model)
{
var elementType = Model.GetType().GetElementType();
if (elementType == null)
{
elementType = Model.GetType().GetGenericArguments()[0];
}
return elementType.GetProperties().Where(info => info.Name != elementType.IdentifierPropertyName()).ToArray();
}
public static PropertyInfo[] VisibleProperties(this Object model)
{
return model.GetType().GetProperties().Where(info => info.Name != model.IdentifierPropertyName()).ToArray();
}
public static RouteValueDictionary GetIdValue(this object model)
{
var v = new RouteValueDictionary();
v.Add(model.IdentifierPropertyName(), model.GetId());
return v;
}
public static object GetId(this object model)
{
return model.GetType().GetProperty(model.IdentifierPropertyName()).GetValue(model, new object[0]);
}
public static string IdentifierPropertyName(this Object model)
{
return IdentifierPropertyName(model.GetType());
}
public static string IdentifierPropertyName(this Type type)
{
if (type.GetProperties().Any(info => info.PropertyType.AttributeExists<System.ComponentModel.DataAnnotations.KeyAttribute>()))
{
return
type.GetProperties().First(
info => info.PropertyType.AttributeExists<System.ComponentModel.DataAnnotations.KeyAttribute>())
.Name;
}
else if (type.GetProperties().Any(p => p.Name.Equals("id", StringComparison.CurrentCultureIgnoreCase)))
{
return
type.GetProperties().First(
p => p.Name.Equals("id", StringComparison.CurrentCultureIgnoreCase)).Name;
}
return "";
}
public static string GetLabel(this PropertyInfo propertyInfo)
{
var meta = ModelMetadataProviders.Current.GetMetadataForProperty(null, propertyInfo.DeclaringType, propertyInfo.Name);
return meta.GetDisplayName();
}
public static string ToSeparatedWords(this string value)
{
return Regex.Replace(value, "([A-Z][a-z])", " $1").Trim();
}
}
public static class PropertyInfoExtensions
{
public static bool AttributeExists<T>(this PropertyInfo propertyInfo) where T : class
{
var attribute = propertyInfo.GetCustomAttributes(typeof(T), false)
.FirstOrDefault() as T;
if (attribute == null)
{
return false;
}
return true;
}
public static bool AttributeExists<T>(this Type type) where T : class
{
var attribute = type.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
if (attribute == null)
{
return false;
}
return true;
}
public static T GetAttribute<T>(this Type type) where T : class
{
return type.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
}
public static T GetAttribute<T>(this PropertyInfo propertyInfo) where T : class
{
return propertyInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
}
public static string LabelFromType(Type @type)
{
var att = GetAttribute<DisplayNameAttribute>(@type);
return att != null ? att.DisplayName
: @type.Name.ToSeparatedWords();
}
public static string GetLabel(this Object Model)
{
return LabelFromType(Model.GetType());
}
public static string GetLabel(this IEnumerable Model)
{
var elementType = Model.GetType().GetElementType();
if (elementType == null)
{
elementType = Model.GetType().GetGenericArguments()[0];
}
return LabelFromType(elementType);
}
}
//public static class HtmlHelperExtensions
//{
// public static MvcHtmlString TryPartial(this HtmlHelper helper, string viewName, object model)
// {
// try
// {
// return helper.Partial(viewName, model);
// }
// catch (Exception)
// {
// }
// return MvcHtmlString.Empty;
// }
//}
}
and the _alert partial View
@using BootstrapSupport
@if (TempData.ContainsKey(Alerts.WARNING))
{
<div class="alert alert-block">
<a class="close" data-dismiss="alert" href="#">x</a>
<h4 class="toast-title">Attention!</h4>
@TempData[Alerts.WARNING]
</div>
}
@foreach (string key in Alerts.ALL.Except(new[] { Alerts.WARNING }))
{
if (TempData.ContainsKey(key))
{
<div class="toast toast-top-full-width toast-key">
<button type="button" class="toast-close-button" data-dismiss="alert">x</button>
@TempData[key]
</div>
}
}
After all this I can send alert messages right from controller:
And it works!
For example
public ActionResult Test()
{
Success("Person was successfully added to your addressbook");
}
above code would result this in view
but it is just displaying as content block. Not as I expected to work, as it just appears in view, no effect, nothing. I wanted it to work as in this site Toastr.
I'm guessing I have to implement javascript somewhere in my _alert
view and get the message and type(success, error,...) and then use javascript to growl it, to make it behave it as it should.
But i don't have much knowledge about it.
Something like below? Thats just idea, because of my lack of knowledge of Javascript and jquery i couldn't make it work
@*if (TempData.ContainsKey(key))
{
<div class="toastMessageHolder" style="display: none">
<div class="toastMessage">@TempData[key]</div>
<div class="toastMessageType">@key</div>
</div>
if($(".toastMessageHolder"))
{
//loop all toastMessageHolders
$(".toastMessageHolder").foreach(function(){
var message = $(".toastMessage", this).html();
var messageType = $(".toastMessageType", this).html();
});
//feed this parameters to javascript
}*@
Could somebody help me how to make my growling from controller behave as mentioned in example of Toastr?
If I had to growl from any normal view if I hadn't implemented sending msgs from controller to view this is how I would do using toastr:
function foo(response) {
if (response.SomeTest) {
toastr.error(response.ErrorMessage, "Error");
}
else {
$(@Html.IdFor(m=>m.abc)).val('');
}
};
Asp.Net MVC version: 5.1.1
Growling package used: Toastr
回答1:
This is what I ended up doing.
_alert view(partial). To send alert messages right from controller.
@using BootstrapSupport
<script>
toastr.options = {
closeButton: true,
debug: false,
positionClass: "toast-top-full-width",
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
}
</script>
@if (TempData.ContainsKey(Alerts.SUCCESS))
{
foreach (var value in TempData.Values)
{
<script>
toastr.success("@value.ToString()");
</script>
}
TempData.Remove(Alerts.SUCCESS);
}
@if (TempData.ContainsKey(Alerts.ERROR))
{
foreach (var value in TempData.Values)
{
<script>
toastr.error("@value.ToString()");
</script>
}
TempData.Remove(Alerts.ERROR);
}
@if (TempData.ContainsKey(Alerts.INFORMATION))
{
foreach (var value in TempData.Values)
{
<script>
toastr.warning("@value.ToString()");
</script>
}
TempData.Remove(Alerts.INFORMATION);
}
@if (TempData.ContainsKey(Alerts.WARNING))
{
foreach (var value in TempData.Values)
{
<script>
toastr.warning("@value.ToString()");
</script>
}
TempData.Remove(Alerts.WARNING);
}
来源:https://stackoverflow.com/questions/22167497/alert-messages-from-controller-add-alert-behavior-in-partial-view