Friday, October 12, 2012

Validate, Update data with asp.net MVC2

Lets see how to design the form for edit operation, we need to load data based on unique id (here ContactId) , and when updated data submitted to server we have to perform a validation if data looks good then we update else display the error message. so let's look at the html code of form tag


< % using (Ajax.BeginForm("EditClient", new AjaxOptions
               {
                   UpdateTargetId = "dvUpdateClient",
                   InsertionMode = InsertionMode.Replace,
                   OnBegin = "ajaxValidate",
                   OnSuccess = "getGbPostSuccess",
                   OnFailure = "showFaliure",
                   Confirm = "You sure you want to update this information?",
                   HttpMethod ="Post"
               }))
           {%>
        < %: Html.ValidationSummary(true) % >


As we have defined onBegin, OnSuccess, and OnFailure method in ajax, we have write some javascript methods with specified name, so this is how the script function will look like.


function ajaxValidate() {
            $get("dvResult").innerHTML = "Updating...";
            $get("btnUpdateClient").disabled = true;

        }

        function getGbPostSuccess(ajaxContext) {
            $get("dvResult").innerHTML = "Updated successfully";
            // $get("btnAddClient").disabled = false;
        }

        function showFaliure(ajaxContext) {
            $get("dvResult").innerHTML = "Update fail.";
            $get("btnUpdateClient").disabled = false;
        }


This is how we store the unique id in mvc2 form, this unique id is required to perform update operation in database. so the html code will look like
< %: Html.HiddenFor(model => model.ContactId) % >

now lets see some fields on the form that we need to validate & update, if validation fail it will display the inline error message.

Organisation Name : < %: Html.TextBoxFor(model => model.OrgName) %>
                            < %: Html.ValidationMessageFor(model => model.OrgName) %>
Remember  you must specify the following line of code before form tag , so the validation works properly.
  < % Html.EnableClientValidation(); %>

Now we see how to design the model where we can implement business validation as we need.


 public class ClientEdit
    {
        public long ContactId { get; set; }

        [Required(ErrorMessage = "Organisation name required.")]
        [DisplayName("Organisation Name")]
        public string OrgName { get; set; }
}


You must be thinking how the controller will look like, as there are two need on this form, one to load the data and second to update the data. so here is the code.

to load the data:

 public ActionResult EditClient(string ContactId)
        {
            object _contactId = ContactId as object;
            long clientId = Convert.ToInt64(_contactId);

            tbContact c = ClientService.GetClient(clientId);
            Models.ClientEdit ce = new ClientEdit()
            {
                ContactId = c.ContactId,
                OrgName = c.OrgName
             
            };

            return View(ce);
        }

to update the data:


        [HttpPost]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditClient(ClientEdit clnt)
        {
            tbContact updateContact = null;

            if (Request.IsAjaxRequest())
            {
                if (ModelState.IsValid)
                {
                    clnt.UpdateDate = DateTime.Now;

                    tbContact c = new tbContact()
                    {
                        ContactId = clnt.ContactId,
                        OrgName = clnt.OrgName                     

                    };

                    updateContact = ClientService.UpdateClient(c);

                    if (updateContact != null)
                    {
                        return RedirectToAction("ResultClient", "Client", new { action = "?action=ClientUpdated" });
                    }
                }

            }

            return View(updateContact);
        }


So we are done ! Hope you find this helpful.

Thursday, October 11, 2012

Form Validation in Asp.net MVC2

Now we learn how to do validation in MVC2 ! Yes that's not exactly the way we used to do in asp.net , (i am assuming you are familiar with Model View Controller), in MVC2 we can specify each field validation in model level, So let's  take a look at how the model will look like!


 public class ClientModel : BaseModel
    {
        public long ContactId { get; set; }

        [Required(ErrorMessage = "Organisation name required.")]
        [DisplayName("Organisation Name")]
        public string OrgName { get; set; }

        [DisplayName("Address")]
        public string Address { get; set; }

        [Required(ErrorMessage = "Organisation type required.")]
        [DisplayName("Type")]
        public string OrgType { get; set; }

        [DataType(DataType.EmailAddress)]
        [DisplayName("Email")]
        public string Email { get; set; }

        [Required(ErrorMessage = "Enter contact person name.")]
        [DisplayName("Concern Person")]
        public string ConcernPerson { get; set; }

[ValidateClientDOBAttribute]
        public DateTime? ClientDOB { get; set; }

        [DataType(DataType.Date)]
        public DateTime? ClientAnniversery { get; set; }
    }

the below is an example of custom validation class that we have used for some field validation above (ClientDOB), we can write custom validation for any field as per our business need

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]

    public sealed class ValidateClientDOBAttribute : ValidationAttribute
    {
        private const string _defaultErrorMessage = "Provide valid date format- dd/MM/yyyy";
        private readonly string _pastDate = "past date not allowed";

        public ValidateClientDOBAttribute()
            : base(_defaultErrorMessage)
        {
        }

        public override string FormatErrorMessage(string name)
        {
            return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
                name, _pastDate);
        }

        public override bool IsValid(object value)
        {
            bool Valid = false;
            DateTime? valueAsDate = value as DateTime?;
            // if null then allowed.
            if (valueAsDate == null)
                Valid = true;
            return Valid;
        }
    }

Now we are ready to see how to consume this validation in aspx page!

the first line you need to specify before you start the form tag is  < % Html.EnableClientValidation(); %> this will indicate that the model validation message to be displayed on your form

now we start form tag, you can use normal form or ajax form, this will work with both types.

  < % using (Ajax.BeginForm("AddClient", new AjaxOptions
               {
                   UpdateTargetId = "dvAddClient",
                   InsertionMode = InsertionMode.Replace,
                   OnBegin = "ajaxValidate",
                   OnSuccess = "getGbPostSuccess",
                   OnFailure = "showFaliure",
                   Confirm = "You sure?"
               }))
% >

now you can display the validation message both way either in form of validation summary or inline, or both. in case you want to display validation summary at the top of the form put the line below.
  < %: Html.ValidationSummary(false, "Client addintion was unsuccessful. Please correct the errors and try again.")% >

Or if you want to display inline validation message, please write this way:
 <%: Html.ValidationMessageFor(m => m.OrgName)%>

i hope you find this helpful.



Wednesday, October 10, 2012

how to delete row from datalist using ajax in asp.net mvc2

Let's design the form and load data, so it look like a datalist, in mvc2 you don't need to use any datalist control for that, this is more likely how we used to write classic asp in earlier days. here at the end of each row i have added a delete link, and we see how on click on that link the respective row gets deleted.

< div id="dvClients">

< % using (Html.BeginForm("ShowClient", "Client", FormMethod.Get))
{%>
< table>
< % foreach (var item in Model.Clients)
{ %>
< tr>
< td>
< %: Html.ActionLink("Edit", "EditClient", "Client", new { ContactId = item.ContactId }, new { })%>
< %: Html.ActionLink("Details", "Details", new { ContactId = item.ContactId }, new { })%>
< /td>
< td>
< %: item.ContactId%>
< /td>
< td>
< %: item.OrgName%>
< /td>
< td>
< %: item.Address%>
< /td>
< td>
< a href="javascript:DeleteClient('< %: item.ContactId%>')">Delete< /a>
< /td>
< /tr>
< % } %>
< /table>
< %} %>
< /div>  

Now we write some javascript function to make ajax call. lets see how the simple javascript will look like!!

< script language="javascript" type="text/javascript">
function DeleteClient(clientId) {
var isConfrm = window.confirm("Are you sure you want to delete?");
if (isConfrm) {
DeleteCall(clientId);
}
}

function DeleteCall(cId) {
var data = "clientId=" + cId;
$.ajax({
url: "DeleteClient",
data: data,
type: "POST",
dataType: "json",
success: function (data, status, xhr) {
alert("the row has been deleted successfully.");
},
error: function (xhr, status, err) {
alert(err + xhr + status);
}
});
}
< /script>

Now we write a controller to delete the data from database, here in this example i have set myclass = clientid, you can send the complete object to your javascript, so the script function can create appropriate message for end user to read the operation result.

[HandleError]

public class ClientController : Controller
{
[HttpPost]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult DeleteClient(string clientId)
{
ClientService.DeleteClient(Convert.ToInt64(clientId));
return Json(new { success = true, value = "done", newClass = clientId });
}
}

populate a DropDownList in ASP.Net MVC2 from wcf client service


First we see how to pull data from wcf client into our mvc, (here i am not giving the example of how to create wcf and publish the service, i hope you are already familier with that process)

we create an interface that will consume the wcf client.
 public interface IClientService
    {
 List GetProducETGProducts();
}

public class ClientService : BaseModel, IClientService
    {
        private readonly ICustomerService _provider;

        public ClientService()
            : this(null)
        {

        }

        public ClientService(CustomerServiceClient provider)
        {
            _provider = provider ?? new CustomerServiceClient();
// this service client is WCF service client.

        }

// finally database / wcf call done here.

 public List GetProducETGProducts()
        {
            List custs = null;
            tbProductMaster[] custArry = _provider.GetProductMaster();

            custs = custArry.ToList();

            return custs;
        }

}

Now we create a controller class that will fetch data from client service we have just create in above example

[HandleError]
    public class ClientController : Controller
    {


// this interface has all defination    
public IClientService ClientService { get; set; }

        protected override void Initialize(RequestContext requestContext)
        {
             if (ClientService == null) { ClientService = new ClientService(); }

            base.Initialize(requestContext);
        }

// here now we load data into model from our data access layer, in this example we are using a WCF service to pull data from data source, so i am not putting to code of wcf call, you can use any data access to pull data from datasource

public ActionResult ManageClients()
        {
            ViewData["Message"] = "Manage Clients!";

            var model = new ClientViewModel();
            model.ProductMaster = ClientService.GetProducETGProducts();

            return View(model);
        }
}


Lets take a look at how the model will look like, we have already used in above ManageClients() method, and this same model we will be using to create a view (.aspx / .ascx ) pages

public class ClientViewModel : BaseModel
    {
        public  List< tbContact> Clients { get; set; }
        public List< tbProductMaster> ProductMaster { get; set; }

    }


Finally, now this is how your html .aspx page page will look like

<% @ Page Title="Manage Clients" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
    Inherits="System.Web.Mvc.ViewPage"  %>

< asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

 <%: Html.DropDownList("ProductMaster", new SelectList(Model.ProductMaster, "ProductId", "Product")) %>
</ asp:Content>

You are done! simply run the page, you should be able to see the dropdown list, make sure you have set the property name properly.