Alert messages from controller: Add alert behavior in partial view?

孤街浪徒 提交于 2019-12-24 18:06:41

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!