0

I'm currently learning about mvc with asp.net. But I got problem when trying to post data from controller.

Here's my code:

   [HttpPost]
    [ValidateInput(false)]
    public ActionResult Create(FormCollection collection)
    {

        PostCareersViewModel career = new PostCareersViewModel
        {
            Title = collection["Title"],
            Description = collection["Description"],
            Photo = collection["Photo"],
            CareerStatus = int.Parse(collection["CareerStatus"]),
            JobDescription = collection["JobDescription"],
            Contact = collection["Contact"],
            MainImage = Encoding.ASCII.GetBytes(collection.Get("Photo"))
        };
        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("Title", career.Title.ToString()),
            new KeyValuePair<string, string>("Description", career.Description.ToString()),
            new KeyValuePair<string, string>("Photo", career.Photo.ToString()),
            new KeyValuePair<string, string>("CareerStatus", career.CareerStatus.ToString()),
            new KeyValuePair<string, string>("JobDescription", career.JobDescription.ToString()),
            new KeyValuePair<string, string>("Contact",career.Contact.ToString()),
            new KeyValuePair<string, string>("MainImage",career.MainImage.ToString())
        });

        try
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(UrlAddressHelper.Base_Url);

                //var responseTask = client.PostAsync(PostCareerString, new FormUrlEncodedContent(
                //                                  collection.
                //                                      AllKeys.ToDictionary(
                //                                          k => k, v => collection[v])));
                var responseTask = client.PostAsync(PostCareerString, content);
                responseTask.Wait();

                var result = responseTask.Result;
                if (result.IsSuccessStatusCode)
                {
                    return RedirectToAction("Index");
                }
            }

            ModelState.AddModelError(string.Empty, "Server Error. Please contact administrator.");
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

for the view, I'm using this code:

<section class="ftco-section">
    <div class="container">
        @using (Html.BeginForm("Create", "PostCareers", FormMethod.Post, new { @class = "bg-light p-5 contact-form" }))
        {
            @Html.AntiForgeryToken()

            <h4>Post New Job Vacancy</h4>
            <hr />
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            <div class="form-group">
                @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.TextAreaFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" }, id = "edit" })
                    @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Photo, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.TextBoxFor(model => model.Photo, new { type = "file", placeholder = Html.DisplayNameFor(model => model.Photo), @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.Photo, "", new { @class = "text-danger" })
                    @*@Html.EditorFor(model => model.Photo, new { htmlAttributes = new { @class = "form-control" } })*@
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.CareerStatus, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownList("CareerStatus", new SelectList(ViewBag.CSListItem, "Value", "Name"), new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.CareerStatus, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.JobDescription, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.JobDescription, new { htmlAttributes = new { @class = "form-control" } })
                    @*@Html.ValidationMessageFor(model => model.JobDescription, "", new { @class = "text-danger" })*@
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Contact, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Contact, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Contact, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-primary py-3 px-5" />
                </div>
            </div>
        }

        <div>
            @Html.ActionLink("Back to List", "Index")
        </div>
    </div>
</section>

I got error bad request 400.

It works perfectly if I use this responseTask

var responseTask = client.PostAsync(PostCareerString, new FormUrlEncodedContent(
                                                      collection.
                                                         AllKeys.ToDictionary(
                                                            k => k, v => collection[v])));

well PostAsJson Async need FormUrlEndcodedContent as parameter and PostAsync need httpcontent as parameret. But it formurlendcoded content works perfectly with PostAsync, And why FormUrlEndcodedContent not running with PostAsJsonAsync?

but I can't convert that MainImage Encoding.ASCII.GetBytes cause I wont store it to my api as file (Actually I don't know if that method works or not to upload file).

Is there any way to deal with this? Am I doing the correct things like convert FormCollection to model to FormUrlEncodedContent (well it is still give me 400 badrequest) ?

I'm really appreciate every answer that posted. Thanks in advance:)

8
  • Please shared your view code if possible Commented Oct 13, 2019 at 3:27
  • got it sir, the cshtml right? Commented Oct 13, 2019 at 3:37
  • Yes please share Commented Oct 13, 2019 at 3:48
  • In your job create form images control required? Commented Oct 13, 2019 at 4:54
  • when you posting data view to controller data received or not? Commented Oct 13, 2019 at 4:58

1 Answer 1

1

Please check below images Data coming from view.

Model

Model

Also, your images file are comming which is you have select in view

File Control data

FormCollection FromCollection Data

Sample View render for checkingenter image description here

Please find out the code

Cshtml Page code

<section class="ftco-section">
    <div class="container">
        @using (Html.BeginForm("Create", "PostCareers", FormMethod.Post, new { @class = "bg-light p-5 contact-form", enctype = "multipart/form-data" }))
        {
            @Html.AntiForgeryToken()

            <h4>Post New Job Vacancy</h4>
            <hr />
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            <div class="form-group">
                @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.TextAreaFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" }, id = "edit" })
                    @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Photo, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.TextBox("myphoto",null, new { type = "file", placeholder = Html.DisplayNameFor(model => model.Photo), @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.Photo, "", new { @class = "text-danger" })
                    @*@Html.EditorFor(model => model.Photo, new { htmlAttributes = new { @class = "form-control" } })*@
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.CareerStatus, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">                   
                    @Html.DropDownList("CareerStatus", new SelectList(ViewBag.CSListItem, "Value", "Name"), new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.CareerStatus, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.JobDescription, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.JobDescription, new { htmlAttributes = new { @class = "form-control" } })
                    @*@Html.ValidationMessageFor(model => model.JobDescription, "", new { @class = "text-danger" })*@
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Contact, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Contact, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Contact, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-primary py-3 px-5" />
                </div>
            </div>
        }

        <div>
            @Html.ActionLink("Back to List", "Index")
        </div>
    </div>
</section>

Controller code for testing data is coming or not way view to

public class PostCareersController : Controller
    {
        public ActionResult Index()
        {
            return View(new PostCareersViewModel());
        }
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Create(FormCollection collection, PostCareersViewModel model, HttpPostedFileBase myphoto)
        {

            PostCareersViewModel career = new PostCareersViewModel
            {
                Title = collection["Title"],
                Description = collection["Description"],
                CareerStatus = int.Parse(collection["CareerStatus"]),
                JobDescription = collection["JobDescription"],
                Contact = collection["Contact"],
            };
            if (myphoto != null)
            {
                string Path = Server.MapPath(string.Concat("~/Upload/", myphoto.FileName));
                myphoto.SaveAs(Path);
                career.Photo = string.Concat(Request.Url.Authority, "/Upload/", myphoto.FileName);
            }
            var content = new FormUrlEncodedContent(new[]
            {
            new KeyValuePair<string, string>("Title", career.Title.ToString()),
            new KeyValuePair<string, string>("Description", career.Description.ToString()),
            new KeyValuePair<string, string>("Photo", career.Photo.ToString()),
            new KeyValuePair<string, string>("CareerStatus", career.CareerStatus.ToString()),
            new KeyValuePair<string, string>("JobDescription", career.JobDescription.ToString()),
            new KeyValuePair<string, string>("Contact",career.Contact.ToString())
        });

            return RedirectToAction("Index");
        }
    }

    public class PostCareersViewModel
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public string Photo { get; set; }
        public int CareerStatus { get; set; }
        public string JobDescription { get; set; }
        public string Contact { get; set; }
    }

Note: you need to create one folder or your working application folder name "Upload" when you select file then your file save on folder once it's done then you read and send the JSON request.

Sign up to request clarification or add additional context in comments.

10 Comments

soo, the image that stored in my model just the path? Need a moment to try this. Thanks sir, ill inform you later
Ok, please check and let me know if any action required on this :).
Can i ask something? Why in public ActionResult Create() you put postcareersviewmodel model? Is it alternative way so no need create new PostCareerViewModel?
No no, it's not like that if you pass the data view to controller not necessary to use FormCollection if you use modelclass inseted of FormCollection then you posting the data it automatic map with respective model propeties.
You have PostCareersViewModel model class with respective some properties so please pass out the Action parameter and check that it's mapped automatically.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.