How to change URL after post request in MVC 4 - visual-studio-2010

we made an web app using vs 2010 mvc 4, that displays product catelougue to users, we have also created cart system for the same. But whenever user submits cart We are displaying view, but URL remains same,
before posting data to action CheckOut URL is :
www.domain.com/shoppingcart/checkout
after posting data to action Checkout URL is same as mentioned. What I need to accomplish is Change "www.domain.com/shoppingcart/checkout" this URL to "www.domain.com/products" so even if user refreshes the page He/she cannot place the same order Twice or more times.
my post method is form post. No ajax calls have been made to post form.
Any suggestions?
[HttpPost]
public ActionResult CheckOut(Order order)
{
try
{
//.. some code
}
catch (Exception e)
{
HandleErrorInfo err = new HandleErrorInfo(e, "ShoppingCart", "CheckOut");
return View("Error", err);
}
return View("OrderPlaced", order);
}
Can I Do something like this?
[DisplayURL(URL="www.domain.com/Products/Catelouge")]
[HttpPost]
public ActionResult CheckOut(Order order)
{
try
{
//.. some code
}
catch (Exception e)
{
HandleErrorInfo err = new HandleErrorInfo(e, "ShoppingCart", "CheckOut");
return View("Error", err);
}
return View("OrderPlaced", order);
}

Can't you just redirect to a new page:
return Redirect("Home/MyNewPage");

Solution was suggested by Stephen Muecke.
To use PRG pattern to redirect to another method or to avoid unnecessary calls to action methods. Thanks Stephen

Related

Fetching data from the internet after a page opens in Xamarin forms

I am having some performance issues with my code. I am working with basic MVVM in Xamarin forms project, and I want to fetch data from the internet when someone navigates to another page. Below is what I have done;
This is how I am navigating to another page via Command; (To be honest I don't really know if this method of navigation has some performance penalties)
if (Application.Current.MainPage.Navigation.NavigationStack.Last().GetType() != typeof(SubcategoryPage))
{
await Application.Current.MainPage.Navigation.PushAsync(new SubcategoryPage());
}
Here, I am passing Id of a particular category to get its corresponding subcategories
public SubcategoryPage(int id)
{
InitializeComponent();
this.BindingContext = new SubcategoryPageViewModel(id);
}
In the constructor of the SubcategoryPageViewModel, I used the Id to fetch the data online like so;
public SubcategoryPageViewModel(int id)
{
SubcategoryLoader(id);
}
Below is the method that is fetching the data from the internet through my DataService class. The code below work well in getting the data from the internet;
private async Task SubcategoryLoader(int id)
{
try
{
var subCategories = await SubcategoryDataService.GetSubcategories(id);
if (subCategories.code == 1) // StatusCode = Successful
{
SubCategories = subCategories.document;
}
else
{
await Application.Current.MainPage.DisplayAlert("Oops!","Something went wrong", "Ok");
}
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert("Oops!", ex.Message, "Ok");
}
}
Now my problem is that the SubcategoryPage doesn't open until the online service is over which leads to a serious lags. So what I want to have happen is to open the SubcategoryPage before the internet services happen.
Please any assistance is appreciated.
Move it to OnAppearing method .
Add a simple check .
protected override void OnAppearing()
{
base.OnAppearing();
if(BindingContext == null)
{
BindingContext = new SubcategoryPageViewModel(id);
}
}

Spring Controller does nothing

Greeting my dear fellows
I would appreciate some help since I've been 2 days googling to find out why my code is not working. My webapp is Spring running in a Weblogic Server under Eclipse. Btw, apologies for my spelling (I am not native English speaker)
Straight from my webapp, the following controller works flawless
#RequestMapping(value = "/sendFile")
public ModelAndView vistaEnvioFicheros() throws myCustomException {
ModelAndView model = null;
try {
getLog().debug("Setting model for sending a file");
model = new ModelAndView("/content/sendFileWeb");
} catch (Exception ex) {
getLog().error("Shxx happens: ", ex);
throw new myCustomException(ex.getMessage(), ex);
}
return model;
}
This controller loads a jsp file with a file browser button and a file upload button which works great too.
So when I click on the upload button the following controller triggers:
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public Object subirFichero(#RequestParam(value = "file") MultipartFile file) throws myCustomException {
ModelAndView model = null;
if (file.isEmpty()){
try {
getLog().debug("File is empty");
model = new ModelAndView("/content/errorWeb");
} catch (Exception ex) {
getLog().error("Shxx happens again ", ex);
throw new myCustomException(ex.getMessage(), ex);
}
return model;
}
...
}
Problem is: when I upload empty file, errorWeb jsp file should be shown in my web browser, however nothing happens. If I debbug the controlles I can see the code runs propperly until return model sentence nonetheless errorWeb jsp file is not loaded
Could anyone give me a hint about why first controller loads it jsp view but second controller doesn't. Also I don't get a single error message in any console or whatever
Thank you very much
Ok, I got it solved! This was just a newbie thing (I am a newbie web developper).
The problem was in the client side, where my webapp was sending the request thay triggers the second controller, not by an standard href o after a submit (or whatever), but by a custom javascript function.
This custom javascript function firstly validates the file and then uploads it to the server. After that client side code stops listening the response from the server. That's why the new ModelAndView is ignored.
Thank you for your time to all of you who read the post

calling a spring controller from xhrPost doesnot redirect

I am calling a spring controller method from dojo xhrPost and I need to redirect to a new html from the controller method. But controller returns back to the dojo in javascript instead of moving to a new page.
my javascript:
var xhrArgs={
url:"/tradeIn/submitTradeIn",
postData:dojo.toJson(tradeInDetails),
handleAs:"text",
headers:{"Content-Type":"application/json"}
/*load:function(data){
console.log(data);
label=data;
if(data =="fail"){
location.reload(true);
window.location="/Fail";
}
else{
window.location="/success";
}
}*/
}
var deferred=dojo.xhrPost(xhrArgs);
my spring controller:
#RequestMapping(value="/tradeIn/submitTradeIn", method = {RequestMethod.POST})
public String submitTradeIn(#RequestBody TradeInDetails tradeDetails) throws UnsupportedEncodingException{
List<byte[]> labelList=new ArrayList<byte[]>();
ShippingInfo shippingInfo=new ShippingInfo();
shippingInfo.setAddress1(tradeDetails.getCustomerDetails().get(0).getAddress1());
shippingInfo.setAddress2(tradeDetails.getCustomerDetails().get(0).getAddress1());
shippingInfo.setCity(tradeDetails.getCustomerDetails().get(0).getCity());
shippingInfo.setCompany(tradeDetails.getCustomerDetails().get(0).getCompany());
shippingInfo.setDayPhone(tradeDetails.getCustomerDetails().get(0).getDayPhone());
shippingInfo.setEmail(tradeDetails.getCustomerDetails().get(0).getEmail());
shippingInfo.setEvePhone(tradeDetails.getCustomerDetails().get(0).getEvePhone());
shippingInfo.setFirstName(tradeDetails.getCustomerDetails().get(0).getFirstName());
shippingInfo.setLastName(tradeDetails.getCustomerDetails().get(0).getLastName());
shippingInfo.setState(tradeDetails.getCustomerDetails().get(0).getState());
shippingInfo.setZip(tradeDetails.getCustomerDetails().get(0).getZip());
shippingInfo.setCountry(tradeDetails.getCustomerDetails().get(0).getCountry());
List<ReturnRequestLabel> label;
List<TradeInClubs> tradeInList1= new ArrayList<TradeInClubs>();
for(ClubDetails cl: tradeDetails.getClubDetails()){
TradeInClubs tradeInclubs1=new TradeInClubs();
tradeInclubs1.setClubMaterial(cl.getShaftType());
tradeInclubs1.setClubType(cl.getClubType());
tradeInclubs1.setManufacturer(cl.getClubManufacturer());
tradeInclubs1.setModel(cl.getClubModel());
tradeInclubs1.setTradeInValue(cl.getTradeInPrice());
tradeInList1.add(tradeInclubs1);
}
try{
ReturnFedexLabel returnFedexLabel = new ReturnFedexLabel();
label=returnFedexLabel.fetchFedexLabel(tradeInList1, shippingInfo);
byte[] labelImageData;
String fedexLabelNumber=null;
for(ReturnRequestLabel rl: label){
labelImageData=rl.fedexReturnLabel.imageData;
labelList.add(labelImageData);
fedexLabelNumber=rl.trackingNumber;
}
File f=new File("label.jpg");
BufferedImage img=ImageIO.read(new ByteArrayInputStream(labelList.get(0)));
ImageIO.write(img,"JPEG",f);
int id=tradeInDao.insertQuery(shippingInfo,tradeInList1,fedexLabelNumber);
byte[] pdfData=fedexLabelToPdf.printFedexLabel(labelList);
emailTradeIn.emailTradeInDetails(pdfData,tradeDetails.getCustomerDetails().get(0).getEmail(),tradeInList1,id);
System.out.println("here");
} catch (Exception e){
logger.error(e.getMessage());
return "fail";
}
return "success";//Base64.encodeBase64String(labelList.get(0));
}
it is not moving to success page. it just stays in the current page
Check and see what deferred is, it is probably "success".
From http://dojotoolkit.org/reference-guide/1.7/quickstart/ajax.html:
dojo.xhrPost xhrPost will create an Ajax request using the HTTP POST
method and is usually used to submit data to a service. It returns
data to a callback. The callback is defined as a member of the object
used to create the request (the property-bag), or by using the
dojo.Deferred.then() method.
For complete details and examples, see the dojo.xhrPost documentation.
if you need to change the page from the controller it shouldn't be an ajax request. If you can change it from the client side then you can continue with the ajax request and respond accordingly.

WebAPI CORS - why is the OPTIONS request making its way into my Controller?

I have CORS working with the following:
[System.Web.Http.HttpPut]
[System.Web.Http.AcceptVerbs("OPTIONS")]
[System.Web.Http.Route("api/exercise")]
public HttpResponseMessage UpdateExercise(Exercise exercise) {
try {
_adminService.UpdateExercise(exercise);
return Request.CreateResponse(HttpStatusCode.OK, "Success");
} catch (Exception e) {
return Request.CreateResponse(HttpStatusCode.InternalServerError, e);
}
}
In my global.asax:
protected void Application_BeginRequest() {
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS") {
Response.Flush();
}
}
But something weird is happening - if I set a breakpoint in my controller, the OPTIONS request makes its way to the innards with a null exercise. Why is this happening? I would expect the Flush() to prevent this.
As it stands, I need to add checks for null to all of my CORS-sensitive endpoints (PUTs, DELETEs). This seems inelegant... should I be able to prevent OPTIONS requests from hitting the controller logic, instead just responding with the required headers straight-away?
Adding this as an answer, based on the comments in the question.
The problem is caused by accepting the OPTIONS verb on the action method. The MVC runtime then tries to execute the action method & the null problem occurs.
Remove the verb so MVC doesn't try to execute the method & the Application_BeginRequest event will sort out the pre-flight issue for you.

Authorize attribute is letting ActionResult code execute

I have a custom attribute that I am using for Ajax requests to prevent the default FormsAuthentication workflow from happening (since it doesn't make sense for an Ajax request).
This is the custom authorize attribute:
public class AjaxAuthorize : AuthorizeAttribute {
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
UrlHelper urlHelper;
if (filterContext.HttpContext.Request.IsAjaxRequest()) {
urlHelper = new UrlHelper(filterContext.RequestContext);
filterContext.HttpContext.Response.StatusCode = 401;
//Don't let IIS7 be mean.
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
//Return JSON which tells the client where the login page exists if the user wants to authenticate.
filterContext.HttpContext.Response.Write(new JavaScriptSerializer().Serialize(
new {
LoginUrl = string.Format("{0}?ReturnURL={1}", FormsAuthentication.LoginUrl, urlHelper.Encode(filterContext.HttpContext.Request.Url.PathAndQuery))
}
));
filterContext.HttpContext.Response.End();
} else {
base.HandleUnauthorizedRequest(filterContext);
}
}
}
I have my ActionResult decorated with the custom authorize attribute like so:
[HttpPut]
[ValidateInput(false)]
[AjaxAuthorize]
public ActionResult Comment(string id, string comment) {
//stuff happens here.
}
An exception is thrown inside of my action result because I try to access information about a user that would only exist if you are logged in. But, I don't understand why this code is even being executed because I have my authorization attribute protecting the action.
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
filterContext.Result = new HttpUnauthorizedResult();
}
This is default implementation of HandleUnauthorizedRequest. Probably you need to assign your custom ActionResult that contains JSON you need and valid status code. I'm not sure direct processing request object from HTTP context would work.
I ended up returning an HTTP 418 (I have been wanting to use this for awhile) so that the Forms Authentication module didn't intercept the request. Then in my script I look for that status code and handle it as an unauthorized request and do the proper redirect.
Try calling base.HandleUnauthorizedRequest(filterContext); inside the IF block. Or just remove the ELSE block and always call base.HandleUnauthorizedRequest(filterContext);.

Resources