Dodi
Dodi

Reputation: 111

Currency conversion api web service

I am a new to MVC and still learning! I am trying to create a very basic App in my web which allows users to convert money value according to their preference. I made the web APi and was successful to call the service to my forms. However, in my controller I managed to get the currencies (names) to the index view, but cannot post the form back once entering a value in the text box to generate the partial view! What am I doing wrong in my codes?!

Currency Controller

namespace MVC_ATM.Controllers
{
    public class CurrencyController : Controller
    {
      [HttpGet]
        // GET: Currency
        public ActionResult Index()
        {
            CurrenciesClient Cur = new CurrenciesClient();
           var listCurrency = Cur.findAll();
           SelectList list = new SelectList(listCurrency,"Id", "CurrencyName");
           ViewBag.listCurrencies = list;
            return View();

        }

        [HttpPost]
        public ActionResult Index(Currencies cur)
        {
            if (!ModelState.IsValid)
            {
                string errors = string.Join("<br />", ModelState.Values
                                        .SelectMany(x => x.Errors)
                                        .Select(x => x.ErrorMessage));
                return new ContentResult { Content = errors };


                var rate = Convert.ToDecimal(cur.ConversionRate);

                if (cur.CurrencyName == cur.CurrencyName)
                {
                    ModelState.AddModelError("CurrencyCountry", "Can't make the conversion for the same value");
                }
                else if (cur.CurrencyName != cur.CurrencyName)
                {
                    foreach (var currency in cur.CurrencyName)
                    {
                        ViewBag.Theresult = rate * cur.Value;
                    }
                    return PartialView("_CurrencyValue");

                }
            }
            return View();
                }
    }
}

Currencies Model

namespace Project.Model
{
    public class Currencies
    {
        public int Id { get; set; }
        public string CurrencyName { get; set; }
        public string CurrencyCountry {get; set;}
        public decimal Value { get; set; }
        public string ConversionRate { get; set; }

    }
}

Index View

@model Project.Model.Currencies

    @{
        ViewBag.Title = "Index";
    }


<h2>Currency</h2>

<body>
    <div class="converter">
        Convert: @Html.TextBoxFor(m => m.ConversionRate, new { @size = "5" })
        <div class="form-group">
            @Html.Label("Convert from", new { @class = "col-md-2 control-label" })
            <div class="col-md-10">
                @Html.DropDownList("Currency List", ViewBag.listCurrencies as SelectList, "Please Select a currency")

            </div>
        </div>
        <div class="form-group">
            @Html.Label("Convert to", new { @class = "col-md-2 control-label" })
            <div class="col-md-10">
                @Html.DropDownList("Currency List", ViewBag.listCurrencies as SelectList, "Please Select a currency")
            </div>
        </div>


        <div>
            <button type="submit" class="btn btn-primary">Convert</button>
        </div>
    </div>
</body>

Upvotes: 0

Views: 1512

Answers (2)

Searching
Searching

Reputation: 2279

Couple of things to notice, is the POST action and missing form tag in the view . You created a POST action that accepts Currencies model but the form doesn't post that. Only ConversionRate will bind to the model. To get the "Currency From" and "Currency To" and the "Conversion Rate" you will require a different approach/small changes.

ConversionModel.cs a new Model for index page that will capture your required fields.

public class ConversionModel
{
    [Required]//decimal would be better but up to you requirement
    public decimal ConversionRate { get; set; }

    [Required]
    public int FromCurrencyId {get;set;}
    public SelectList FromCurrencies {get;set;}

    [Required]
    public int ToCurrencyId {get;set;}
    public SelectList ToCurrencies {get;set;}
}

Get: while there is nothing wrong with what you've done, lets use a model approach and tightly bind it.

public ActionResult Index()
{
    CurrenciesClient Cur = new CurrenciesClient();
    var listCurrency = Cur.findAll();

    ConversionModel model = new ConversionModel();
    model.FromCurrencies = new SelectList(listCurrency,"Id", "CurrencyName");
    model.ToCurrencies = new SelectList(listCurrency,"Id", "CurrencyName");

    return View(model);

}

Post: Important thing here to notice is the SelectList will not be posted back. Only the ConversionRate, FromCurrencyId and ToCurrencyId are sent back not the Lists. If error occurs you will need to rebuild the lists and send it back in the model.

[HttpPost]
public ActionResult Index(ConversionModel curModel)
{
    if(ModelState.IsValid)
    {
        if(curModel.FromCurrencyId ==curModel.ToCurrencyId)
        {
            //do something if same currecnies and return.
        }
        else
        {
            //Get the currencyList with rates  from db
            //use currency ToCurrencyId and FromCurrencyId to fetch the 2 currencies
            // perform conversion with curModel.ConversionRate with existing logic
        } 
    }
    //Don'f forget to rebuild the Select Lists... 
    return View(curModel);
}

View:

@model Project.Model.ConversionModel

@{
    ViewBag.Title = "Index";
}


@using (Html.BeginForm("Index", "Currency", FormMethod.Post)
{
    @Html.TextBoxFor(m => m.ConversionRate, new { @size = "5" })
    @* Please check the syntax *@
    @Html.DropDownListFor(m => m.FromCurrencyId , Model.FromCurrencies as SelectList)
    @Html.DropDownListFor(m => m.ToCurrencyId , Model.ToCurrencies as SelectList)
    <button type="submit" class="btn btn-primary">Convert</button>
}

Not a CUT_COPY_PASTE. please do check for errors if any. It is only an approach.

ajax POST probably the next thing to learn... Let us know.

Upvotes: 2

CodingYoshi
CodingYoshi

Reputation: 27039

You need to put your items inside a form like this:

@using (Html.BeginForm("Index", "Currency", FormMethod.Post)
{
    // Your form items
}

Upvotes: 1

Related Questions