Upload control in Ajax form in partialview

11 posts, 1 answers
  1. Stephen
    Stephen avatar
    158 posts
    Member since:
    Jan 2009

    Posted 21 Feb 2014 Link to this post

    Can the upload control be used in an ajax form within a partial view?  If so can I have an example?  I can make the upload work on a html form but in the ajax form the controller method that is being posted to receives a NULL for the HttpPostedFileBase file parameter.
  2. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 25 Feb 2014 Link to this post

    Hello Stephen,

    Posting a file through an Ajax form is not possible. So the Upload widget will fail again for the same reason.

    http://stackoverflow.com/questions/17037948/not-able-to-upload-file-using-ajax-beginform-asynchronously

    Kind Regards,
    Petur Subev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Stephen
    Stephen avatar
    158 posts
    Member since:
    Jan 2009

    Posted 17 Mar 2014 in reply to Petur Subev Link to this post

    How can I go about doing the following:

    I've got a kendo tabstrib that loads a partial view for attachments. That attachments partial view has an ajax form which is displaying a kendo grid listing all of the uploaded files.  Within that attachments partial view I want to have the kendo upload control.  I understand though that I cannot actually upload the files through ajax.  So I thought I would put a kendo window control  in that partial view and have that window load a view with the kendo upload control and have that submit via an html form instead of ajax.  It works as far as uploading the file but then I'm not sure how to get it to return to the kendo window and just close that window and remain on the attachments partial view and have the kendo grid update the file list.

    Here is my attachments partial view :
    @model PASS.ViewModels.Proposals.AttachmentsViewModel
     
    @using (Ajax.BeginForm("_Attachments", "Proposals", new AjaxOptions { UpdateTargetId = "attachmentsReturnMsg", HttpMethod = "Post", OnComplete = "onDataUpdated()" }))
    {
     
    @Html.HiddenFor(model => model.Proposal_ID, Model.Proposal_ID)
     
    <div class="editor-container">
     
        <p><a href="#" class="attachments link-button">Add Attachments</a></p>
     
        @(Html.Kendo().Window().Name("AddAttachments")
            .Title("Upload Attachments")
            .Visible(false)
            .Modal(true)
            .Draggable(true)
            .LoadContentFrom("AddAttachments", "Proposals", new { proposalID = Model.Proposal_ID })
            .Width(500)
        )
     
        @(Html.Kendo().Grid<PASS.ViewModels.Proposals.AttachmentsViewModel>()
            .Name("gridAttachments")
            .Columns(columns =>
            {
                columns.Bound(c => c.File_Name).ClientTemplate("<a href='" + Url.Action("LoadAttachment", "Proposals") + "/#= ID #'>" + "#= File_Name #"  + "</a>").Title("File Name");
                columns.Bound(c => c.File_Size).Title("Size");
                columns.Bound(c => c.Content_Type).Title("Type");
                columns.Command(command => { command.Destroy(); }).Width(90);
            })
            .Sortable()
            .DataSource(dataSource => dataSource
                .Ajax()
                .Model(model => model.Id(c => c.ID))
                .Read(read => read.Action("GetAttachments", "Proposals", new {proposalID = Model.Proposal_ID}))
                .Destroy(destroy => destroy.Action("DeleteAttachment", "Proposals"))
            )
        )
             
        <div id="attachmentsReturnMsg"></div>
     
    </div>
         
    }
     
    <script type="text/javascript">
    $(document).ready(function () {
        var window = $("#AddAttachments").data("kendoWindow");
        $(".attachments").click(function () {
            window.center();
            window.open();
        });
    });
    </script>

    Here is the AddAttachments view with the kendo upload control:
    @model PASS.ViewModels.Proposals.AttachmentsViewModel
     
    @using (Html.BeginForm("AddAttachments", "Proposals", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
     
    @Html.HiddenFor(model => model.Proposal_ID, Model.Proposal_ID)
     
        <div class="editor-label">
            @Html.Label("File(s):")
        </div>
        <div class="editor-field">
            @(Html.Kendo().Upload().Name("Files"))
        </div>
        <br class="clear" />
        <br />
        <br />
        <p><input type="submit" value="Add Files" /></p>
        <br />
        <br />
       
    }

    And finally here is my controller method for the post of the AddAttachments view:
    [HttpPost]
    public ActionResult AddAttachments(AttachmentsViewModel vm, IEnumerable<HttpPostedFileBase> files)
    {
        try
        {
            var context = new PASSEntities();
     
            foreach (var file in files)
            {
                var model = new Proposal_Attachments();
                model.Proposal_ID = vm.Proposal_ID;
                model.Upload_Date = DateTime.Now;
                model.File_Name = Path.GetFileName(file.FileName);
                model.File_Size = file.ContentLength;
                model.Content_Type = file.ContentType;
                model.File_Contents = new byte[file.ContentLength];
                 
                file.InputStream.Read(model.File_Contents, 0, file.ContentLength);
     
                context.Proposal_Attachments.Add(model);
                context.SaveChanges();
            }
     
            //var message = new SystemMessage(Models.eMessageType.SUCCESS);
            //message.Message = "Your data has been saved!";
            //return PartialView("_SystemMessage", message);
            return Content("");
        }
        catch
        {
            //var message = new SystemMessage(Models.eMessageType.ERROR);
            //message.Message = "Save Failed!";
            //return PartialView("_SystemMessage", message);
            return Content("");
        }
     
    }

    Any help on how t get this to work in the way I described above would be much appreciated.

    Thanks,

    Steve









  5. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 19 Mar 2014 Link to this post

    Hello Stephen,

    Basically the only option is to send whatever you need back as JSON, any result different from json or empty string is considered as an unsuccessfull response.

    Information how to send JSON from the server and how to get it back on the client is covered in the documentation here:

    http://docs.telerik.com/kendo-ui/getting-started/using-kendo-with/aspnet-mvc/helpers/upload/metadata#receiving-metadata-from-the-save-handler

    You can send the HTML inside the JSON if you want and display it on the client with a window widget when the success event of the upload is triggered. To open the window and to set its content you should use the corresponding methods.

    http://docs.telerik.com/kendo-ui/api/web/window#methods

    Kind Regards,
    Petur Subev
    Telerik
     

    DevCraft Q1'14 is here! Watch the online conference to see how this release solves your top-5 .NET challenges. Watch on demand now.

     
  6. Stephen
    Stephen avatar
    158 posts
    Member since:
    Jan 2009

    Posted 19 Mar 2014 in reply to Petur Subev Link to this post

    Ok you sort of lost me there a bit.  Let me start more basic...

    I know I can't have the upload widget in an ajax form so it has to be an html form correct?  Can it be in a partial view that also has a grid on it and return to that same partial view and have it display as it did intially?
  7. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 21 Mar 2014 Link to this post

    Hello again Stephen,

    I am sorry for the confusion created. Basically you can use the upload widget within a regular form and you should not have problems to post it.

    However for your case you mentioned that you want to send the parameters to the server via Ajax. Because of this I mentioned that instead of posting a form with Ajax, you can use Async upload feature of the Upload and send those extra parameters on the page with along with the async request of the upload (how to send extra parameters with the ajax upload is covered here). 

    What I explained in my previous request is that you can return information for that async upload only as JSON. So if you want to update a window or show some page to the client when the upload completes you should send it as json and on the client side with the help of the API methods and the event that is triggered you should display that info to the client.

    I hope this clarifies the situation.

    Let me know if I misunderstood something.

    Kind Regards,
    Petur Subev
    Telerik
     

    Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

     
  8. Stephen
    Stephen avatar
    158 posts
    Member since:
    Jan 2009

    Posted 21 Mar 2014 in reply to Petur Subev Link to this post

    Hi Petur,

    That does clarify it a bit but I guess maybe my original question wasn't exactly clear in expressing what I want to do.  I have attached a screenshot to show you what I'm looking at.

    In the screenshot I am on a Attachments tab.  That tab displays a list of the files uploaded and also has the control to upload files.  My main concern is being able to upload a file from this screen and then return back to this screen and have the list of files update with the one(s) just uploaded.  Is there a way that I can make this happen?  Would that be using the async method you mentioned and returning JSON?  If so, how do I send back that entire partial view with the upload control and the file list via JSON?

    Thanks!
  9. Answer
    Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 25 Mar 2014 Link to this post

    Hello Stephen,

    Thank you for clarifying the situation. How is that Grid bound to these files, is it through Ajax? If it is through Ajax you can easily do like so:
    1. Use Ajax to upload your files
    2. From the server you can return empty result (check the link above point 3) to signify success.
    3. On the client side the success event will be triggered when the upload finishes
    4. Use the read method of the Grid dataSource to refresh the Grid with the latest records

    e.g.

    $(function(){
         $("#uploadName").data("kendoUpload").bind("success", function () {
                $("#gridname").data("kendoGrid").dataSource.read();
         })
    })

    I hope this helps. Let me know if some of the points is not clear.

    Kind Regards,
    Petur Subev
    Telerik
     

    Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

     
  10. Stephen
    Stephen avatar
    158 posts
    Member since:
    Jan 2009

    Posted 25 Mar 2014 in reply to Petur Subev Link to this post

    Ok I was able to make this work thanks!

    My only other question is, what should my form declaration look like for this view?

    Currently I have:
    @using (Html.BeginForm("_Attachments", "Proposals", FormMethod.Post, new { enctype = "multipart/form-data" }))


    But do I still need the FormMethod.Post and the enctype?  Since it is an async upload is it actually doing a Post?

    I took those two items out and it still works but I guess for my own knowledge I am wondering how that all works?

    Thanks!
  11. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 27 Mar 2014 Link to this post

    Hello Stephen,

    Ajax uploading does not need a form to make it work. It uses FormData. Feel free to remove that form that you used before start using  the Ajax uploading feature of the Upload widget.

    Kind Regards,
    Petur Subev
    Telerik
     

    Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

     
  12. Stephen
    Stephen avatar
    158 posts
    Member since:
    Jan 2009

    Posted 01 Apr 2014 in reply to Petur Subev Link to this post

    Thanks!
Back to Top
UI for ASP.NET MVC is VS 2017 Ready