Domanda

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 enter image description here

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

È stato utile?

Soluzione

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top