Tag Archives: View

View

[RESOLVED]Reading CSV file for validation and after that saving it on server in MVC 4

Hi,

I have CSV file upload functionality in MVC4. Below my code is working fine on local machine, when I deploy same code on server I am getting error "Could not find file at C:WindowsSystem32InetSrv".

  [HttpPost]
        public ActionResult Upload(HttpPostedFileBase UploadedFile)
        {
            try
            {
                var fp = Path.GetFileName(UploadedFile.FileName);
                var reader = new StreamReader(UploadedFile.FileName);
                while (!reader.EndOfStream)
                {

                        string[] str = reader.ReadLine().Split(‘,’);  //Validation Logic.

                 }

                reader.Close();
                reader.Dispose();
                UploadedFile.SaveAs(@"d:FileUploadDemo" + fp);
                return View("Index");
            }
            catch (Exception)
            {
                return View("Index");
            }
        }

But If I comment below file reading code,

  var fp = Path.GetFileName(UploadedFile.FileName);
                var reader = new StreamReader(UploadedFile.FileName);
                while (!reader.EndOfStream)
                {
                    string[] str = reader.ReadLine().Split(‘,’);
                }
                reader.Close();
                reader.Dispose();

then my file is getting saved on the server perfectly fine.

But, Before saving a file, I want to validate the file data. I have implemented client side code but it is not working in IE browsers. So wanted to do server side validation.

Or any client side code, working in IE8+ browsers (without asking user to activate ActiveX object) is greatly appreciated.

The filename only contains the name of the file itself, it is for "information" purposes, the file isn’t actually saved to disc until you save it using SaveAs, so you can’t access it yet via StreamReader.  If you want to read its contents you need to access
the file data via the InputStream and convert it to a string that you can then validate

http://stackoverflow.com/questions/16030034/asp-net-mvc-read-file-from-httppostedfilebase-without-save

[RESOLVED]Bind IDictionary List to MVC WebGrid

I’m dont know how to bind an IDictionary list to a MVC WebGrid. This is what I have so far

 public List<IDictionary> GetAddress()
        {
            List<IDictionary> names = new List<IDictionary>();
        //List<string> names = new List<string>();
            using (MVCDBEntities example = new MVCDBEntities())
            {
                var Uus = from U1 in example.Users where U1.Name != null select U1;
                names = Uus.OfType<IDictionary>().ToList();
            }
            return names;
        }

I now need to some how bind  this to a webgrid, how would I achieve this ?

Hi,

taken from

http://forums.asp.net/t/1719060.aspx?Binding+MVC3+webgrid+from+DataTable+AsEnumerable+:

Model method:

public List<IDictionary> FetchEmployeeDetails()
         {
             DataSet dsEmployee = new DataSet();
             DbCommand dbCmd = m_DbAccess.SqlDb.GetStoredProcCommand("Test_FetchEmployeeDetails");
             dbCmd.CommandType = CommandType.StoredProcedure;
             dsEmployee = m_DbAccess.SqlDb.ExecuteDataSet(dbCmd);

             return ConvertToListDictionary(dsEmployee.Tables[0]);
         }

Controller Code:

public ActionResult FetchDataForGrid()
         {
             EmployeeModels modelObject = new EmployeeModels();
             var resultSet = modelObject.FetchEmployeeDetails();
             return View(resultSet);
        }

View Code:

@using System.Dynamic
 @model List<System.Collections.IDictionary>
 @{
     var result = new List<dynamic>();

     foreach (var emprow in Model)
     {
         var row = (IDictionary<string, object>)new ExpandoObject();
         Dictionary<string, object> eachEmpRow = (Dictionary<string, object>)emprow;

         foreach (KeyValuePair<string, object> keyValuePair in eachEmpRow)
         {
             row.Add(keyValuePair);
         }
         result.Add(row);
     }
     var grid = new WebGrid(result);
 }

 @if (@Model != null)
 {
     @grid.GetHtml(tableStyle: "grid", headerStyle: "head", alternatingRowStyle: "alt");
 }

Grz, Kris.

Thanks for the reply, I am just getting an error with the IDictionary list anyways thanks for your time.  Is there anyway you can just use a asp.net Gridview control with something like this with the entity framework ? As binding data to a webgrid in mvc
is a joke, so much extra work, in php its easier than this

Hi,

you can’t really make use of the gridview in MVC.

What you can do, and what I did in the past, is make use of jqGrid and bind the grid client side. There are also commercial tools for this like KendoUI and others.

Grz, Kris.

[RESOLVED]how can i use url.action in @helper method ?

Hi dear ,

 I create a @helper method and use @Url.Action helper in it.(in App_Code Folder)

@helper GetNews(int CategoryID, int Rows)
{
         <div class="@Style" id="@CategoryID">
         
                  <a style="padding-right:10px" href="@Url.Action("Rss", "Home", new { type="News" , cid = CategoryID})"><img src="@Url.Content("~/images/icon/rss.png")" /></a>
                                &nbsp;
                                <a href="@Url.Action("Details", "News", new { cid=CategoryID,sid=Model})">arshive</a>
                             </div>
                        
}

after run i get an error :

Compilation Error 
  Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. 

 Compiler Error Message: CS0103: The name 'Url' does not exist in the current context

Source Error:


 

Line 193:                                </table>*@
Line 194:
Line 195:                                <a style="padding-right:10px" href="@Url.Action("Rss", "Home", new { type="News" , cid = CategoryID})"><img src="@Url.Content("~/images/icon/rss.png")" /></a>
Line 196:                                &nbsp;
Line 197:                                <a href="@Url.Action("Details", "News", new { cid=CategoryID,sid=Model})">arshive</a>
 

Also,
I had
to have
a class named ExtensionMethodHelper
for create external helpers and use it ( in Model folder ).but i
can not call
this
external helpers on the page(.cshtml) that
I’ve created
in
App_Code folder.

in fact after write @Html.  i dont find my favorite external helper (in ExtensionMethod class in Model folder).

for e.g : Html.PersianDate made in ExtensionMethodHelper in Model Folder

   <span class="date">@Html.ToPersianDate(item.DateToShow)</span>

in :

below helper create in App_Code

@helper GetNews(int CategoryID, int Rows)
{
       <div class="@Style" id="@CategoryID">
                <a style="padding-right:10px" href="@Url.Action("Rss", "Home", new { type="News" , cid = CategoryID})"><img src="@Url.Content("~/images/icon/rss.png")" /></a>
                       &nbsp;
                   <a href="@Url.Action("Details", "News", new { cid=CategoryID,sid=Model})">arshive</a>
       </div>
                        
}

 how can i solve it

please help me

thanks

I use the "UrlHelper" class to do this.  Here’s a helper I always used in my projects (prior to bundles).  Use it as an example to expand on your own:

// file name is "Content.cs" stored in App_Code folder

@using System.Web.Mvc; @helper Script(string scriptName, UrlHelper url) { <script type="text/javascript" src="@url.Content("~/Scripts/" + scriptName)"></script> }

the helper in my View then looks like:

@Content.Script("jquery-1.10.1.min.js", Url)

You can see that I pass the "Url" to the helper.  Your helper would then look like…

@helper GetNews(int CategoryID, int Rows, UrlHelper url)
{
  ...

  <a href="@url.Action("Rss", "Home", ...)">

  ...
}

the "url" is lowercase fyi.  Don’t confuse it with Url

[RESOLVED]Re-using the same model, same controller with different views

I didn’t think that this was going to cause me so much difficulty .. and I have only just started with this project Surprised

I have one model which I want to populate the model’s properties over multiple views. I was planning on using the controller to determine which View should be displayed.

The model looks like this:

public class QC_Rework
{
    public int nViewToDisplay { get; set; }
    public int nReworkNumber { get; set; }
    public string cSecondaryReferenceType { get; set; }
    public string cSecondaryReferenceNumber { get; set; }
    public int nLineQuantity { get; set; }
}

My "Create" controller looks like this:

[HttpGet]
public ActionResult Create([Bind(Prefix = "ReworkNumber")] int ReworkNumber=0)
{

    var oQC = new QC_Rework();
    oQC.nReworkNumber = ReworkNumber;
    oQC.nViewToDisplay = 1;
    return View("GetSecondaryReferenceType2", oQC);

}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(QC_Rework oQC_Rework)
{
    // After GetSecondaryReferenceNumber2 the value of nViewToDisplay is "1"!!!
    // Even though the value in the Source Code and in the form says "2"!!!
    if (ModelState.IsValid)
    {
        switch (oQC_Rework.nViewToDisplay)
        {
            // Coming from Secondary Reference Type View
            case 1:
                if (String.IsNullOrEmpty(oQC_Rework.cSecondaryReferenceType) == true)
                {
                    ModelState.AddModelError("Model", "A secondary reference type needs to be selected!");
                    return View("GetSecondaryReferenceType2", oQC_Rework);
                }
                else
                {
                    oQC_Rework.nViewToDisplay = 2;
                    return View("GetSecondaryReferenceNumber2", oQC_Rework);

                }
            // Coming from Secondary Reference Type View
            case 2:
                {
                    oQC_Rework.nViewToDisplay = 3;
                    return View("GetQCDetails2", oQC_Rework);
                }
        }
    }
    // Should not get here at this stage!
    return View("NotFound", oQC_Rework);
}

The model’sproperty nViewToDisplay controls which Views get displayed.

When I debug the code, before the View GetSecondaryReferenceNumber2 gets called, the value in oQC_Rework.nViewToDisplay is set to 2 … but in the view itself it is "1′!!

What am I doing wrong?

Many thanks …

you don’t show the view code, but most likely its something like:

   @Html.HiddenFor(m=>m.nViewToDisplay)

with the html helpers, the lambda expression is just to get the name. ("nViewToDisplay") in your case. this name is then used to lookup the value. The postback form collection is searched before the ViewBag.Model (where you changed the data). so the postback
value is used.

just use a vanilla hidden field:

  <input type="hidden" name="nViewToDisplay" value="@Model.ViewBag.nViewToDisplay" />

or original helper that takes the value

   @Html.Hidden("nViewToDisplay",ViewBag.nViewToDisplay)

[RESOLVED]How to Post with foreign keys

public List<Job> PostNewJob(Job newJob)
        {
            Job job = new Job();

            job.JobId = newJob.JobId;
            job.JobNumber = newJob.JobNumber;
            job.JobName = newJob.JobName;
            job.JobDescription = newJob.JobDescription;
           
            db.Jobs.Add(newJob);
            db.SaveChanges();

            return db.Jobs.ToList();
        }

 public class Job
    {
        public Job()
        {
            this.Customers = new HashSet<Customer>();
            this.ChangeOrders = new HashSet<ChangeOrder>();
        }
        public int JobId { get; set; }
        public int JobNumber { get; set; }
        public string JobName { get; set; }
        public string JobDescription { get; set; }

        public virtual ICollection<Customer> Customers { get; set; }
        public virtual ICollection<ChangeOrder> ChangeOrders { get; set; }
    }


public List<Customer> PostNewCustomer(Customer newCustomer)
        {
            Customer customer = new Customer();

            customer.CustomerId = newCustomer.CustomerId;
            customer.CustomerName = newCustomer.CustomerName;
            customer.CustomerPhoneNumber = newCustomer.CustomerPhoneNumber;
            customer.CustomerFaxNumber = newCustomer.CustomerFaxNumber;
            customer.JobId = newCustomer.JobId;

            db.Customers.Add(newCustomer);
            db.SaveChanges();

            return db.Customers.ToList();
        }

 public class Customer
    {

        public int CustomerId { get; set; }
        public string CustomerName { get; set; }
        public Int64 CustomerPhoneNumber { get; set; }
        public Int64 CustomerFaxNumber { get; set; }

        public int? JobId { get; set; }
    }


 $scope.submitJob = function () {
        var id = $scope.currentItem.JobName
        var data = {
            JobId: $scope.currentItem.JobId,
            JobNumber: $scope.currentItem.JobNumber,
            JobName: $scope.currentItem.JobName,
            JobDescription: $scope.currentItem.JobDescription
            
            
        }
        $http.post('/api/apiJob/PostNewJob', data).success(function (data, status, headers) {
            console.log(data);
               $scope.PrintPreviewModal();
               window.top.location.reload();
            
        });
 };

  <form ng-submit="submitJob()" enctype="multipart/form-data">
                            <fieldset>
                                <div>
                                    <div class="inline-fields">
                                        <label>Number:</label>
                                        <input ng-model="currentItem.JobNumber" type="text">

                                        <label>Job Name:</label>
                                        <input ng-model="currentItem.JobName" type="text">
                                        <label>Customer:</label>
                                        <input type="text" ng-model="currentItem.CustomerName">
                                    </div>
                                    <div class="inline-fields">
                                        <label>Address:</label>
                                        <input ng-model="currentItem.CustomerAddress" type="text">
                                    </div>
                                    <div class="inline-fields">
                                        <label>City:</label>
                                        <input ng-model="currentItem.CustomerCity" type="text">

                                        <label>St:</label>
                                        <input ng-model="currentItem.CustomerState" type="text">

                                        <label>Zip:</label>
                                        <input ng-model="currentItem.CustomerZipcode" type="text">

                                <input type="submit" value="Save" />

                            </fieldset>
                        </form>

I am trying to change how I post and update my primary class JOB. Previously I was using the Customer Class as a List and I was storing the JOB Customer information in the Job class itself. The problem with this was If I went to go update a Customers information
in the Customer List I would have to go to every Job that has that Customer and Manually update everyone separately. So I am unsure how to do this. When I am creating a New Job how do I  Connect the appropriate Customer with that Job? I am already doing this
with another class called ChangeOrder but the difference is the Job has to be already been created before I can make that Post.. And also, the Customer can be assigned to multiple Jobs. So How does the foreign key work with this? How can you have a Customer
with multiple foreign keys "JobIds" attached to it?

What you are looking is a many to many relationship. Please take a look at this article in MSDN magazine

Handle Many-to-Many Relationships in Entity Framework and ASP.NET MVC

ok, so I created a linking table. What am I doing wrong? Here is what is coming back from the database

 {$id:1, JobCustomerId:1, JobId:1, Job:null, CustomerId:2, Customer:null}
$id: "1"
Customer: null
CustomerId: 2
Job: null
JobCustomerId: 1
JobId: 1

public class JobCustomer
    {
        public int JobCustomerId { get; set; }
        public int JobId { get; set; }
        public virtual Job Job { get; set; }
        public int CustomerId { get; set; }
        public virtual Customer Customer { get; set; }
    }
public class Job
    {
       
        public int JobId { get; set; }
        public int JobNumber { get; set; }
        public string JobName { get; set; }
        public string JobDescription { get; set; }

        public ICollection<JobCustomer> JobCustomers { get; set; }
       
    }
public class Customer
    {

        public int CustomerId { get; set; }
        public string CustomerName { get; set; }
        public Int64 CustomerPhoneNumber { get; set; }
        public Int64 CustomerFaxNumber { get; set; }

        public ICollection<JobCustomer> JobCustomers { get; set; }
      }
public List<JobCustomer> GetJobs()
        {
            List<JobCustomer> jobs = new List<JobCustomer>();
             jobs = db.JobCustomers
                .ToList();
            return jobs;
        }

Hi texas697,

You don’t need to create a link table manually, the EF will create it. For the link table, it doesn’t have the entity field, just the keys of these entities.

For your code, the fluent API would be like this:

modelBuilder.Entity<Job>() 
    .HasMany(j => j.Customers) 
    .WithMany(c => c.Jobs) 
    .Map(m => 
    { 
        m.ToTable("JobCustomer"); 
        m.MapLeftKey("JobId"); 
        m.MapRightKey("CustomerId"); 
    });
public class Job
    {
       
        public int JobId { get; set; }
        public int JobNumber { get; set; }
        public string JobName { get; set; }
        public string JobDescription { get; set; }

        public ICollection<Customer> Customers { get; set; }
       
    }
public class Customer
    {

        public int CustomerId { get; set; }
        public string CustomerName { get; set; }
        public Int64 CustomerPhoneNumber { get; set; }
        public Int64 CustomerFaxNumber { get; set; }

        public ICollection<Job> Jobs { get; set; }
      }

More information, please refer to:

# Configuring a Many-to-Many Relationship

http://msdn.microsoft.com/en-in/data/jj591620.aspx#ManyToMany

Best Regards

Starain Chen

that sure does make things easier. Now what if I have additional classes that need to be linked to Job? How would the modelBuilder look? Do i put this in my IdentityModels? If this is the correct way of doing it, I did do a migration without errors. The
tables in the sql where created. But How Do I query the information from my project? I went through the JobApi but the data for Customers, ChangeOrders, etc… came back null. 

 public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool? Hidden { get; set; }
        public string UserEmail { get; set; }
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()

            : base("DefaultConnection", throwIfV1Schema: false)
        {
            this.Configuration.LazyLoadingEnabled = false;
            this.Configuration.ProxyCreationEnabled = false;

        }
        public DbSet<Job> Jobs { get; set; }

        public DbSet<Employee> Employees { get; set; }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<ChangeOrder> ChangeOrders { get; set; }
        public DbSet<JobType> JobTypes { get; set; }
        public DbSet<GeoArea> GeoAreas { get; set; }
        public DbSet<JobClass> JobClasses { get; set; }

        protected override void OnModelCreating
       (DbModelBuilder modelBuilder)
        {
base.OnModelCreating(modelBuilder); modelBuilder.Entity<Job>() .HasMany(j => j.Customers) .WithMany(c => c.Jobs) .Map(m => { m.ToTable("JobCustomer"); m.MapLeftKey("JobId"); m.MapRightKey("CustomerId"); }); modelBuilder.Entity<Job>() .HasMany(j => j.ChangeOrders) .WithMany(c => c.Jobs) .Map(m => { m.ToTable("JobChangeOrder"); m.MapLeftKey("JobId"); m.MapRightKey("ChangeOrderId"); }); modelBuilder.Entity<Job>() .HasMany(j => j.GeoAreas) .WithMany(c => c.Jobs) .Map(m => { m.ToTable("JobGeoArea"); m.MapLeftKey("JobId"); m.MapRightKey("GeoAreaId"); }); modelBuilder.Entity<Job>() .HasMany(j => j.JobTypes) .WithMany(c => c.Jobs) .Map(m => { m.ToTable("JobJobType"); m.MapLeftKey("JobId"); m.MapRightKey("JobTypeId"); }); modelBuilder.Entity<Job>() .HasMany(j => j.JobClasses) .WithMany(c => c.Jobs) .Map(m => { m.ToTable("JobJobClass"); m.MapLeftKey("JobId"); m.MapRightKey("JobClassId"); }); } }

 public class Job
    {
       
        public int JobId { get; set; }
        public int JobNumber { get; set; }
        public string JobName { get; set; }
        public string JobDescription { get; set; }

        
        public ICollection<Customer> Customers { get; set; }
        public ICollection<ChangeOrder> ChangeOrders { get; set; }
        public ICollection<GeoArea> GeoAreas { get; set; }
        public ICollection<JobClass> JobClasses { get; set; }
        public ICollection<JobType> JobTypes { get; set; }
    }

Hi texas697,

Your code is right.

To load the related entities, we could use Include method.

For example:

var data =db.Jobs.Include("Customers");

Best Regards

Starain Chen

The type or namespace name 'WebGrid' could not be found (are you missing a using directive or an assembly reference?)

i am getting this kind of error message while running the programm as compilation error. previously i didn’t get this kind of error message but suddenly i am getting the error. 

previously in all modules it’s working fine but suddenly in all the modules i am getting the same error. 

what’s problem behind on this

Hi,

did you uninstall / update a nuget package related to System.Web.Helpers?

Grz, Kris.

no i didn’t uninstall any package but in references i have this System.Web.Helpers

Hi,

do you have a CVS ready so that you can go back in history of your code to a state where it worked? If so check the differences. Likely some using statement got lost.

Grz, Kris.

Hi,

You may not have "WebGrid.*.dll" with your project, or you may update your project, and "WebGrid.*.dll" is incompatible. Or accidentally deleted from your project dll libs.

You may need to add reference again to your project.

Please check carefully and Have fun

i was installed the webgridmvc from nuget also but it is not working

Hi,

Make sure that name is "WebGrid" or "WebGridMVC". It is case sensitive. Please check.

I’ll try to test it and come to you then.

WebGrid grid = new WebGrid();

i am using this thing only from the entire project upto few days back also it’s working fine. right now we are trying to add a new view with the webgrid then we are getting this

problem and we run the entire project which have this webgrid all are getting the same error. we shocked what happend and how to regetting the Webgrid we dont want to change any other things right now because i have so many forms this webgrid

Hi,

If you install webgridmvc, you must use "@using WebGridMvc;" for the nameSpace.

Please post the detail errors.

if i changed to WebgridMvc then i have to change my entire code where i have this webgrid this will again long time taken thing 

 Layout = "~/Views/Shared/_AdminLayout.cshtml";
Line 5:  
Line 6:      WebGrid grid = new WebGrid();
Line 7:      grid.Bind(Model,
Line 8:                autoSortAndPage: true

CS0246: The type or namespace name ‘WebGrid’ could not be found (are you missing a using directive or an assembly reference?)

this error i am getting when i run the page 

Are you using the appropriate @using statement?  If so, is it at the top of the page or the web.config file?  If it is in the web.config then try closing VisualStudio then re-opening it as that config setting isn’t dynamically processed as you change it. 
Also check the appropriate dll is in the bin folder.  Something else you can test to see if it is a missing assembly or missing "using" is to use the full classname, eg the namespace and classname, and see if the class is found then.

the problem is solved after remove the System.Web.Helpers from the references and add it again. But i got another problem while do it when  i tried to run the program i am getting the following error

An exception of type ‘System.TypeLoadException’ occurred in Microsoft.Owin.Security.Cookies.dll but was not handled in user code

Additional information: Could not load type ‘Microsoft.Owin.Security.AuthenticationDescription’ from assembly ‘Microsoft.Owin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′.

Hi Siva_540,

Thanks for your post.

Siva_540

Additional information: Could not load type ‘Microsoft.Owin.Security.AuthenticationDescription’ from assembly ‘Microsoft.Owin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′.

You can try install the package from Manage NuGet packages

Microsoft.Owin.Security

Hope this can be helpful.

Best Regards,

Eileen

i have already this in my project

[RESOLVED]How to fill Lists in ViewModel

 public
class
CustomerFeeViewModel

    {

public
int
CustomerId {
get;
set;
}

public
string
Comments {
get;
set;
}

public
IEnumerable<FeeModel>
Fees {
get;
set;
}

public
IEnumerable<ItemModel>
Items {
get;
set;
}

    }

I have trouble understanding how to fill the Fees and Items list in the ViewModel.

I’m using Linq to Entity. Do you have multiply queries? or can join in one query?

 

You can use include keyword in your linq query

e.g

ObjectQuery<SalesOrderHeader> query =
    context.SalesOrderHeaders.Include("Fees").Include("Items");

What does FeeModel and ItemModel contains and how they are related

So each Fee have a Item associated with it.

and each Customer have Fees against it.

var Custfeeitems = (from e in db.CustomerFeesPayments.Where(f => f.CustomerID = 1)
                           select new CustomerFeeViewModel
                           {

                               CustomerId = e.CustomerId,
                               Fees = e.FeeModel,
                               Comments = e.Comments
                           }.FirstOrDefault<CustomerFeeViewModel>()

alphabeatsco

So each Fee have a Item associated with it.

and each Customer have Fees against it.

I think ViewModel must be like following

    public class CustomerFeeViewModel
    {
        public int CustomerId { get; set; }

        public string Comments { get; set; }

        public IEnumerable<FeeModel> Fees { get; set; }
    }

And query, something like this

[RESOLVED]Not able to get name of the image button on Controller side

Hello There, 

I am new to MVC and facing lot of issues :(

I have one image, acting as a button, when I clicked on it, it post back, but not able to find its name in Action. Here is my code snippet

View :-

@using (Html.BeginForm())
{

<input type="image" value="AddRoutine" name="button" src="~/Images/Add.png" id="imgAdd" title="Add" alt="Add" />

}

Controller :- 

[HttpPost]
public ActionResult Index(string button)
{
          // the parameter "button" is always comes null 

it is working fine when I use input type button instead of image 

Where I am doing mistake, what is the problem with input type image ?

Please help me out 

Thanks
Ash

An input type="image" is not an input that can carry a value to the server

try this

<button type="submit" value="AddRoutine" name="button" >
	
    <img src="~/Images/Add.png"  title="Add" alt="Add"/>
	
</button>

thats because the image posts two values containing the x & y positions. name.x and name.y. so you need an object:

public class ImageValue
{
   public int x {get; set;}
   public int y {get; set;}
}

[HttpPost]
public ActionResult Index(ImageValue button)
{

} 

[RESOLVED]Layout Needs a Model

Hi All,

I am working on a project for which the UI was created by someone else.  The project has a Partial View called _ApplicationLayout.cshtml that renders on every view page in the project.   It also hosts several partial views, one of which is the "_Comments.cshtml"
view in which I need to display all of the comments from the database that are associated with the application in the right bar of the layout.  I cannot use a View Model in the _Comments.cshtml partial, because it is rendered in the _ApplicationLayout.cshtml
and of course the View Model clashes with all of the other View Models throughout the project.  Can anyone tell me just how can solve this problem?  The comments do need to show on every page (view) in the project.

You can do it via two different ways,

  1. Call @Html.RenderAction  rather than partial to render the result of an action method, that will give you chance to separate out the code with strongly typed model
  2. Create a base controller and initialize the data and assign it to ViewBag which is required for comments view, now all controllers will inherit from base controller and they will have the data available.

I would prefer the first approach as it is a MVC way of doing things and avoid any accidental miss of controller inheritance.

Either move the comments-partial to the actual View, or replace the Partial helper with an Action helper and pass it an ID/value to process data and return a partial view

Example–

Instead of:

@Html.Partial("_Comments")

do:

@Html.Action("GetComments", new { id = X })

where X could be a ViewBag.Value or a URL parameter, example:

@Html.Action("GetComments", new { id = ViewBag.BlogID })

public ActionResult GetComments(int id)
{
  var comments = db.Comments.Where(c => c.BlogID == id).ToList();

  return PartialView("_Comments", comments);
}

The problem is that there  will be a list of comments, and there is a "textarea" for adding more comments on the fly.  Will the solution you suggested still work?  I don’t have the option of moving the Partial out of the _ApplicationLayout.cshtml.  Also,
how can I specify the controller where the ActionResult is in the code:

@Html.Action("GetComments"new { id = ViewBag.loanApplicationId})
?

You can specify the Controller as another parameter of the Action helper:

@Html.Action("GetComments", "Home", new { id = ViewBag.loanApplicationId })

As for your text-area, just give this input a name that matches the post-action param:

@using Html.BeginForm("AddNewComment"))
{
@Html.Hidden("ApplicationId", ViewBag.loanApplicationId)
<div>
Add Comment: @Html.TextArea("NewComment")
</div>

<input type="submit" value="Submit" />
}

Action:

[HttpPost]
public ActionResult AddNewComment(int ApplicationId, string NewComment)
{
  // use ApplicationId to fetch the record
// add NewComment to the record

return redirectToAction("Index"); }

That’s a fairly simple solution.  If you have questions, ask away

Okay, I think I understand it now.  The only other question I have is if they should add a comment (remember they could be on any View page in the project), Once the comments pane is updated the user is has to return to the same view.  From what I have read
online, this should be some sort of "child action only".  Is that correct?

By the way, you are really awesome to have taken the time to help me!  I wish I could send you a gift!

So what you want to do is use an Ajax form, process the comment, then return a fresh instance of your Partial view back to the main View.  Let’s go through the whole thing, but with the ajax:

1) In your _Layout, you’ve got the Html.Action(…) helper.  We should wrap this in a <div> tag because we’re going to update this after our ajax-post

<div id="commentsDiv">
  @Html.Action("GetComments", "Home", new { id = ViewBag.loanApplicationId })
</div>

2) In your partial view, you’ve got your form that allows the user to add a comment.  We’re going to change this to an Ajax form

@using (Ajax.BeginForm("AddNewComment", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "commentsDiv" }))
{
  @Html.Hidden("AppId", ViewBag.loanApplicationId)
  <div>
    Add Comment: @Html.TextArea("NewComment")
  </div>

  <input type="submit" value="Submit" />
}

3) In the post-action, we process the new comment, then return our *UPDATED* _Comments partial view back to the view

[HttpPost]
public ActionResult AddNewComment(int AppId, string NewComment)
{
  // use ApplicationId to fetch the record
// add NewComment to the record

var comments = db.Comments.Where(c => c.ApplicationId == AppId).ToList();

return PartialView("_Comments", comments); }

And that’s it!  Now it’s important to note that you MUST have the unobtrusive-ajax scripts included in your View.  If you are unsure whether you have these, check your Scripts folder (download them from the NuGet manager if needed).

I received the following error when I tried to run this:

"Additional information: Error executing child request for handler ‘System.Web.Mvc.HttpHandlerUtil"

I tried to run in without the Id in the parameters and just hardcoded the ID in the method just for testing.  Here is what is in my _ApplicationLayout:

  <div id="PageClassDiv" class="@(ViewBag.PageClass) APPLICATION"><!-- page content container-->
        
        @Html.Partial("~/Views/Shared/_NavigationView.cshtml") <!-- Navigation Partial View -->
        @Html.Partial("~/Views/Shared/_SearchAccordionView.cshtml") <!-- Search Accordion Partial View -->

        <!-- All applications should have comments and sidebar ============================================================================================-->
        @Html.Partial("~/Views/Shared/_SideBarView.cshtml");
        @*@Html.Partial("~/Views/Shared/_CommentsView.cshtml");*@
        @Html.Action("GetComments", "LoanApplication")
        
        <!-- content ============================================================================================-->
        @if (angularEnabled)
        {
            <div class="container" ng-app="@angularAppName">@RenderBody()</div>
        }
        else
        {
            <div class="container">@RenderBody()</div>
        }
    </div><!-- end page content container-->

This is the CommentsView:

<span class="comments">
    <a id="right-menu" href="#right-menu" class="icon-comments"></a>
</span>
<span class="clear"></span>

<div id="sidr-right" class="sidr right">
    <header>
        <h4> Application Notes </h4>
        <a href="#" class="icon-print"></a>
        @using (@Html.BeginForm("Comment", "LoanApplication"))
        {
           @Html.TextArea("Comment")
        @*<textarea cols="100" rows="2" name="Comment" placeholder="Leave Comment ..."></textarea>*@
            <input value="Add Comment" type="submit" />
        }
    </header>

And this is what is in my controller:

  [HttpGet]
        [Route("GetComments")]
        public async Task<ActionResult> GetComments()
        {
            var loanApplicationServiceProxy = base.ServiceProvider.LoanApplicationServiceProxy;

            var comments = await loanApplicationServiceProxy.GetLoanApplicationCommentsByLoanApplicationIdAsync(loanApplicationId) ?? new List<LoanApplicationComment>();
            
            return PartialView("_CommentsView", comments);
        }


 [HttpPost]
        [Route("Comment")]
        public async Task<ActionResult> Comment(FormCollection form)
        {

            var loanApplicationServiceProxy = base.ServiceProvider.LoanApplicationServiceProxy;
            var userId = this.User.Identity.GetUserId();
            string comment = Request.Form["Comment"];
            var applicationComment = new LoanApplicationComment
            {
                Comment = comment,
                CreatedDate = DateTime.Now,
                LoanApplicationId = loanApplicationId,
                Id = Guid.NewGuid(),
                CreatedBy = Guid.Parse(userId)
            };
            await loanApplicationServiceProxy.PutLoanApplicationCommentAsync(applicationComment);

            var comments = loanApplicationServiceProxy.GetLoanApplicationCommentsByLoanApplicationIdAsync(loanApplicationId);

            return View(comments);
         
        }

The code in the Controller "GetComments" never gets hit.  The application throws an error as soon as I try to navigate to a View page that has the comments pane.

BeeDev

The code in the Controller "GetComments" never gets hit.

take off the [HttpGet] and [Route("GetComments")] annotations, and see if that works.

I was able to get it to hit the controller, but I can’t figure out how to actually display the comments.  I’m used to using @model.Comment, or something of the sort, but there is not model, so how do I specify the fields that I need to display?  I must display
the user name, date and time of comment, along with the comment.

This is going beyond the original scope of the question.  If I understand everything correctly, your _Comments partial view displays rows of comments that include user name, date & time of comment, and the comment.

The model for Comment may look something like this (I’m just guessing since you have not posted the actual model):

public class Comment
{
public int CommentId { get; set; } public string Comment { get; set; }
public string UserName { get; set; } public string CDate { get; set; }
public int App_ID { get; set; } }

The model includes a primary index key (CommentId), the other required fields, and also a foreign key reference (App_ID)

The _Comment partial view may then look like this:

@model IEnumerable<AppName.Models.Comment>

<h2>Submit Comment</h2>

@using (Ajax.BeginForm("AddNewComment", "LoanApplication", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "commentsDiv" }))
{
  @Html.Hidden("AppID", ViewBag.loanApplicationId)
  <div>
    Comment: @Html.TextArea("NewComment")
  </div>

  <input type="submit" value="Submit" />
}

<h2>Comments</h2>

@foreach (var item in Model)
{
  <div>
    <dl class="dl-horizontal">
      <dt>Username</dt>
      <dd>@Html.DisplayFor(modelItem => item.UserName)</dd>

      <dt>Date</dt>
      <dd>@Html.DisplayFor(modelItem => item.CDate)</dd>

      <dt>Comment</dt>
      <dd>@Html.DisplayFor(modelItem => item.Comment)</dd>
    </dl>
  </div>
}

To explain, our @model is a LIST of comments that will be passed to the partial view.  At the top I’ve included the AJAX form, which allows a user to submit their comment.  Below the form is the Comments section, which loops through each comment, displaying
the User, the Date, and the Comment (I used DL formatting but you can use TABLE or DIV, etc).  Now when the form posts and finishes processing, we’ll be returning a fresh _Comments partial view, which will replace the old one.  We use "UpdateTargetId" to specify
where to update.

Your AJAX post-action in your "LoanApplication" controller:

[HttpPost]
public ActionResult AddNewComment(int AppID, string NewComment)
{
  // create new comment object
  var comment = new Comment();
  comment.Comment = NewComment;
  comment.UserName = User.Identity.Name;
  comment.CDate = DateTime.Now;
  comment.App_ID = AppID;

  // add comment to db
  db.Comments.Add(comment);
  db.SaveChanges();

// query new comments list and return to partial view var comments = db.Comments.Where(c => c.App_ID == AppID).ToList(); return PartialView("_Comments", comments); }

I’ve commented this for explanation.

Your _Layout view now only needs to have the initial Action helper inside a named DIV

<div id="commentsDiv">
  @Html.Action("GetComments", "LoanApplication", new { id = ViewBag.loanApplicationId })
</div>

As said earlier, once the AJAX form posts, a new version of _Comments partial view will replace the contents of "commentsDiv".

Lastly, the "GetComments" action (in the LoanApplication controller):

public ActionResult GetComments(int id)
{
  var comments = db.Comments.Where(App_ID == id).ToList();

  return PartialView("_Comments", comments);
}

And that’s it.  There’s the entire solution…  If all of this works for you, please take a moment to mark all my responses as answers, as they all answer each of your subsequent questions.  Thanks.

Okay, I figured out that I can put a model in the _CommentsView.cshtml since it is being rendered with an @Html.Action.  Thanks for ALL of your help!  You are awesome!!!

[RESOLVED]Convert ajax call into chunked calls of 100 for a URL

Excuse me here, I’m rather new to this, so please bear with me.

I have been given the task as stated in the subject, to break the ajax call into chunks of 100.  This is being done as to not run out of URL space.  My instinct (which is probably wrong) is to pass it through as an array.  This is where I’m hitting a wall.
 Here is a chunk of code in the index of Views.

$(document).ready(function() {
var imageNos = ‘@Model.ImageNos’;
var array = imageNos.split(‘,’);

var oTable = $(‘#imageTable’).dataTable(
{
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "ImageData/GetList",
"bLengthChange": false,
"bFilter": false,
"bSort": false,
"bJQueryUI": true,
"aoColumns": [
{ "bSortable": false, "bSearchable": false },
null,
null,
null,
null,
null,
null,
null
],
"fnServerData": function(sSource, aoData, fnCallback) {
aoData.push({ "name": "ImageNos", "value": array });
$.getJSON(sSource, aoData, function(json) {
fnCallback(json)
});
},
"fnRowCallback":function(nRow, aaData) {
var imageno = aaData[1];
$.get("ImageData/ImageDetails?imageNo=" + imageno, function (details) {
oTable.fnOpen(nRow, details, ‘details’);
});
return nRow;
}
});

here is how I;m trying to pass it through to the controller.

public ActionResult GetList(string[] value)
{
var imageNos = new List<long>();
try
{
if (!string.IsNullOrEmpty(value))
{
/*var imgs = ImageNos.TrimEnd(‘,’).Split(‘,’).ToList();
imageNos.AddRange(imgs.Select(i => Convert.ToInt64(i)));*/
}

long totalImages;
var images = ImageRepository.GetSelectedImages(imageNos);
var imageDataModels = images as IList<ImageDataModel> ?? images.ToList();
return Json(new
{
iTotalRecords = imageDataModels.Count,
iTotalDisplayRecords = imageDataModels.Count,
aaData = imageDataModels.Select(x => new[]
{…………

As it is now, I’m getting errors

Error 1 The best overloaded method match for ‘string.IsNullOrEmpty(string)’ has some invalid arguments and 

Error 2 Argument 1: cannot convert from ‘string[]’ to ‘string’ 

I know this is a lot of code, and i’m not even sure I have posted anything that could help someone assist me, but any help on this would be greatly appreciated; I’m feeling a bit overwhelmed and underwater.

edit: I meant to say beforehand that everything works fine before I try the array above, before I split it in the index

I can’t really follow what the code is doing, but you’re getting that error as

string.IsNullOrEmpty(value)

in the above "value" is an array, and IsNullOrEmpty works on strings, not arrays of strings.  If you want to check if an array isn’t empty try

if (value != null && value.Length >0)

Not saying that’s going to fix your issue, but it will get your code to compiled.  Also if you’re worried about "running out of url space" then just POST your data rather than using GET and you don’t need to worry.